Use Case
When a user records an audio file and uploads to firebase storage, run a trigger that crops a clip of that file and saves it to a "preview" directory.
Problem
When the file arrives on the server, it is just dead air before the start time (10 seconds) and then doesn't stop after the duration of 10 seconds is exceeded. Whatever I put in the "-t" and "-ss" arguments seems to have no impact on the output file - not cropping correctly.
Environment
mac client / firebase storage
node v8.1.0
ffmpeg v3.2.2
fluent-ffmpeg v2.1.2
Node Code
var command = new ffmpeg({ source: tempFilePath, timeout: 0 })
.setFfmpegPath(ffmpegPath)
.setFfprobePath(ffprobePath)
.inputOption('-t', '10')
.inputOption('-ss', '10')
.outputOption('-acodec', 'copy')
.on('start', function(commandLine) {
console.log('Spawned Ffmpeg with command: ', commandLine);
})
.on('end', function() {
console.log('Preview file cropping done successfully');
})
.on('error', function(err, stdout, stderr) {
var build = err;
if (!stdout === '') { build = build + '\n' + stdout; }
build = build + '\n' + stderr;
console.log(build);
}).save(tempFilePath);
Ffmpeg Command
Spawned Ffmpeg with command: ffmpeg -t 10 -i
/tmp/2EB100B0-6C1E-4D51-9087-764CA653AFC720170711232034.aac -y -acodec
aac /tmp/2EB100B0-6C1E-4D51-9087-764CA653AFC720170711232034.aac
Console Output
$ ffmpeg -t 10 -i E506FE2E-DC81-4DD8-B751-211F7FD9A25820170816160502.aac -y -acodec aac output.aac -loglevel debug
ffmpeg version 3.2.2 Copyright (c) 2000-2016 the FFmpeg developers
built with llvm-gcc 4.2.1 (LLVM build 2336.11.00)
configuration: --prefix=/Volumes/Ramdisk/sw --enable-gpl --enable-pthreads --enable-version3 --enable-libspeex --enable-libvpx --disable-decoder=libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-avfilter --enable-libopencore_amrwb --enable-libopencore_amrnb --enable-filters --enable-libgsm --enable-libvidstab --enable-libx265 --disable-doc --arch=x86_64 --enable-runtime-cpudetect
libavutil 55. 34.100 / 55. 34.100
libavcodec 57. 64.101 / 57. 64.101
libavformat 57. 56.100 / 57. 56.100
libavdevice 57. 1.100 / 57. 1.100
libavfilter 6. 65.100 / 6. 65.100
libswscale 4. 2.100 / 4. 2.100
libswresample 2. 3.100 / 2. 3.100
libpostproc 54. 1.100 / 54. 1.100
Splitting the commandline.
Reading option '-t' ... matched as option 't' (record or transcode "duration" seconds of audio/video) with argument '10'.
Reading option '-i' ... matched as input url with argument 'E506FE2E-DC81-4DD8-B751-211F7FD9A25820170816160502.aac'.
Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'.
Reading option '-acodec' ... matched as option 'acodec' (force audio codec ('copy' to copy stream)) with argument 'aac'.
Reading option 'output.aac' ... matched as output url.
Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option y (overwrite output files) with argument 1.
Applying option loglevel (set logging level) with argument debug.
Successfully parsed a group of options.
Parsing a group of options: input url E506FE2E-DC81-4DD8-B751-211F7FD9A25820170816160502.aac.
Applying option t (record or transcode "duration" seconds of audio/video) with argument 10.
Successfully parsed a group of options.
Opening an input file: E506FE2E-DC81-4DD8-B751-211F7FD9A25820170816160502.aac.
[file # 0x7fe42f700420] Setting default whitelist 'file,crypto'
[aac # 0x7fe431000000] Format aac probed with size=2048 and score=51
[aac # 0x7fe431000000] Before avformat_find_stream_info() pos: 0 bytes read:32928 seeks:4 nb_streams:1
[aac # 0x7fe431000000] All info found
[aac # 0x7fe431000000] Estimating duration from bitrate, this may be inaccurate
[aac # 0x7fe431000000] After avformat_find_stream_info() pos: 37888 bytes read:98464 seeks:4 frames:50
Input #0, aac, from 'E506FE2E-DC81-4DD8-B751-211F7FD9A25820170816160502.aac':
Duration: 00:01:24.28, bitrate: 335 kb/s
Stream #0:0, 50, 1/28224000: Audio: aac (LC), 44100 Hz, stereo, fltp, 335 kb/s
Successfully opened the file.
Parsing a group of options: output url output.aac.
Applying option acodec (force audio codec ('copy' to copy stream)) with argument aac.
Successfully parsed a group of options.
Opening an output file: output.aac.
[file # 0x7fe42f7016e0] Setting default whitelist 'file,crypto'
Successfully opened the file.
detected 4 logical cores
[graph 0 input from stream 0:0 # 0x7fe42f701880] Setting 'time_base' to value '1/44100'
[graph 0 input from stream 0:0 # 0x7fe42f701880] Setting 'sample_rate' to value '44100'
[graph 0 input from stream 0:0 # 0x7fe42f701880] Setting 'sample_fmt' to value 'fltp'
[graph 0 input from stream 0:0 # 0x7fe42f701880] Setting 'channel_layout' to value '0x3'
[graph 0 input from stream 0:0 # 0x7fe42f701880] tb:1/44100 samplefmt:fltp samplerate:44100 chlayout:0x3
[audio format for output stream 0:0 # 0x7fe42f702060] Setting 'sample_fmts' to value 'fltp'
[audio format for output stream 0:0 # 0x7fe42f702060] Setting 'sample_rates' to value '96000|88200|64000|48000|44100|32000|24000|22050|16000|12000|11025|8000|7350'
[AVFilterGraph # 0x7fe42f6101a0] query_formats: 5 queried, 12 merged, 0 already done, 0 delayed
Output #0, adts, to 'output.aac':
Metadata:
encoder : Lavf57.56.100
Stream #0:0, 0, 1/44100: Audio: aac (LC), 44100 Hz, stereo, fltp, delay 1024, 128 kb/s
Metadata:
encoder : Lavc57.64.101 aac
Stream mapping:
Stream #0:0 -> #0:0 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
cur_dts is invalid (this is harmless if it occurs once at the start per stream)
Last message repeated 1 times
[output stream 0:0 # 0x7fe42f701ee0] EOF on sink link output stream 0:0:default.
No more output streams to write to, finishing.
[aac # 0x7fe431001200] Trying to remove 344 more samples than there are in the queue
size= 160kB time=00:00:10.00 bitrate= 130.9kbits/s speed=20.2x
video:0kB audio:157kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.881580%
Input file #0 (E506FE2E-DC81-4DD8-B751-211F7FD9A25820170816160502.aac):
Input stream #0:0 (audio): 432 packets read (398208 bytes); 432 frames decoded (442368 samples);
Total: 432 packets (398208 bytes) demuxed
Output file #0 (output.aac):
Output stream #0:0 (audio): 431 frames encoded (441000 samples); 432 packets muxed (160716 bytes);
Total: 432 packets (160716 bytes) muxed
432 frames successfully decoded, 0 decoding errors
[AVIOContext # 0x7fe42f611040] Statistics: 0 seeks, 432 writeouts
[aac # 0x7fe431001200] Qavg: 4508.253
[AVIOContext # 0x7fe42f7004c0] Statistics: 458912 bytes read, 4 seeks
Related
I am working on a simple R package to submit hashes for trusted timestamping and to get timestamp info back through Origin Timestamps. I manage to get the information, but I do not manage to POST it OpenTimestamp post hash.
I am using the http package in R. My package ROriginStamp is on github, and the function which I do not get to work is store_hash_info().
Whenever I execute it, I get:
> store_hash(hash = "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e")
Error in store_hash(hash = "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e") :
Bad Request (HTTP 400).
3.
stop(http_condition(x, "error", task = task, call = call))
2.
httr::stop_for_status(result$response) at store_hash.R#29
1.
store_hash(hash = "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e")
>
The function is defined as follow:
store_hash <- function(
hash,
error_on_fail = TRUE,
information = NULL
) {
result <- new_OriginStampResponse()
##
url <- paste0("https://api.originstamp.org/api/", hash)
request_body_json <- jsonlite::toJSON( information, auto_unbox = TRUE )
result$response <- httr::POST(
url,
httr::add_headers(
Authorization = get_option("api_key"),
body = request_body_json
),
httr::content_type_json()
)
if (error_on_fail) {
httr::stop_for_status(result$response)
}
##
try(
{
result$content <- httr::content(
x = result$response,
as = "text"
)
result$content <- jsonlite::fromJSON( result$content )
},
silent = TRUE
)
##
return(result)
}
The function get_option("api_key") just returns my api key.
Any suggestions what I am doing wrong?
Edits
Thanks to Thomas Hepp, Here is a curl command which does work:
curl 'https://api.originstamp.org/api/ff55d7bc3fe6cb2958e4bdda3d4a4a8e528fb67d9194991e9539d97a55cda2a3' \
-H 'authorization: YOUR API KEY' \
-H 'content-type: application/json' \
-H 'accept: application/json' \
-H 'user-agent: OriginStamp cURL Test' \
--data-binary '{"url":null,"email":null,"comment":"this is a test","submit_ops":["multi_seed"]}'
I’m not familiar with R. But, it’s possible to timestamp a file using opentimestamps.org, by posting a hash of the file to one of their calendar servers, using the following methodology. There is no need for an API key, and this procedure can be used to prove the existence of the file at a point in time, via a reference to a value stored in the OP_RETURN field of a bitcoin transaction, in a block in the bitcoin blockchain.
As an example, first, create a test file:
$ echo -n 'this is a test... this is only a test...' > file.txt
Now, take a sha256 hash of the file:
$ sha256sum file.txt
This produces:
c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca
Now, to create a timestamp of the file, post the raw bytes of the hash to one of the calendar servers (e.g. https://a.pool.opentimestamps.org/). This can be done using curl, like so:
$ echo -n 'c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca' | xxd -r -p | curl -X POST --data-binary - https://a.pool.opentimestamps.org/digest > out.ots
[Optional: If you don’t want to disclose the hash of the file that you are timestamping to Opentimestamps, you can add a random salt to the file hash, then do sha256(original file hash + salt) and post the result of this.]
The response from the above request is redirected to a file out.ots. To get the status of the timestamp, we need to parse the raw bytes of out.ots.
First, view the raw bytes of the file using a hex editor, or xxd:
$ xxd out.ots
00000000: f010 95ee b35a b002 5b8b 5e76 3522 6970 .....Z..[.^v5"ip
00000010: 886c 08f1 0462 be3e 32f0 081a ff1c ae94 .l...b.>2.......
00000020: 4f00 4600 83df e30d 2ef9 0c8e 2e2d 6874 O.F..........-ht
00000030: 7470 733a 2f2f 616c 6963 652e 6274 632e tps://alice.btc.
00000040: 6361 6c65 6e64 6172 2e6f 7065 6e74 696d calendar.opentim
00000050: 6573 7461 6d70 732e 6f72 67 estamps.org
Some of the bytes represent instructions, as follows:
f0 xx: append xx bytes
f1 xx: prepend xx bytes
80: sha256 hash
00: stop
Start with the hash that we timestamped:
c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca
then, proceed by parsing the response of the POST request. The first two bytes are f0 10. This means append the next 16 bytes (10 in hex is 16 in decimal). This produces:
c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca95eeb35ab0025b8b5e7635226970886c
Continuing parsing the POST response, the next byte is 80. This means take the sha256 hash of the above.
echo -n ‘c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca95eeb35ab0025b8b5e7635226970886c’ | xxd -p -r | sha256sum
produces:
f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef35090
Continuing, we have f1 04. This means prepend the next 4 bytes to the above. This produces:
62be3e32f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef35090
Next, we have f0 08. Append the next 8 bytes. This produces:
62be3e32f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef350901aff1cae944f0046
Finally, we have 00. This means stop. At this point, skip the next 10 bytes, then extract starting from this point to get the URL that we’ll need to get the status of the timestamp:
https://alice.btc.calendar.opentimestamps.org
then, concatenate ‘/timestamp/’ followed by the result above:
https://alice.btc.calendar.opentimestamps.org/timestamp/62be3e32f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef350901aff1cae944f0046
The status of the timestamp can be accessed by making a GET request to the above URL:
curl https://alice.btc.calendar.opentimestamps.org/timestamp/62be3e32f7d0917a163a8df26066cd669eb12e2d0d59bb5f454aaee338dcc0694ef350901aff1cae944f0046
returns:
Pending confirmation in Bitcoin blockchain
If you wait a few hours, the confirmation will be written to the bitcoin blockchain, and the above GET request will return a much longer proof like the one above, eventually chaining-up to a value that is written to the OP_RETURN field of a bitcoin transaction, in a block in the bitcoin blockchain. By saving this proof, you can verify the existence of the file at the point in time that the block was written to the blockchain, without the need to query the Opentimestamps servers.
The following python script automates the above procedure:
import hashlib
import requests
filehash=bytes.fromhex('c16d7c8e23baf68525cf0a42fff6b394fdba1791db9817fd601b3f73e2f5fbca')
server='https://a.pool.opentimestamps.org/digest'
print('posting ' + filehash.hex() + ' to ' + server)
response=requests.post(url=server, data=filehash)
bytearray=response.content
print('saving response to ./out.ots')
f=open('./out.ots', 'wb')
f.write(bytearray)
f.close()
print('analysing response')
i=0
ptr=0x00
result=filehash
while(True):
print(i)
print('ptr:', hex(ptr))
nextinstruction=bytearray[ptr]
if(nextinstruction==0xf0):
#append
ptr+=1
numberofbytes=bytearray[ptr]
ptr+=1
bytesegment=bytearray[ptr:ptr+numberofbytes]
print('append ', bytesegment.hex())
result=result+bytesegment
ptr+=numberofbytes
elif(nextinstruction==0xf1):
#prepend
ptr+=1
numberofbytes=bytearray[ptr]
ptr+=1
bytesegment=bytearray[ptr:ptr+numberofbytes]
print('prepend ', bytesegment.hex())
result=bytesegment+result
ptr+=numberofbytes
elif(nextinstruction==0x08):
#sha256
print('sha256')
result=hashlib.sha256(result).digest()
ptr+=1
elif(nextinstruction==0xff):
#fork
print('fork')
ptr+=1
elif(nextinstruction==0x00):
#stop
print('stop')
ptr+=11
url=bytearray[ptr:].decode()
url=url + '/timestamp/' + result.hex()
print('url: ', url)
else:
print('invalid ots file format')
quit()
print('result:', result.hex())
print('-----')
i+=1
if(nextinstruction==0x00): break
print('to get status of timestamp, make a GET request to ' + url)
print('GET ' + url)
response=requests.get(url)
print(response.text)
I have a file which i've encrypted in CENC, and i'm trying to now decrypt it using mp4decrypt from the bento4 mp4decrypt tools. The file consists of a single h264 track in an mp4 file. This is the output of mp4info --verbose
File:
major brand: dash
minor version: 0
compatible brand: iso6
compatible brand: dash
Movie:
duration: 0 ms
time scale: 120000
fragments: yes
Found 1 Tracks
Track 1:
flags: 7 ENABLED IN-MOVIE IN-PREVIEW
id: 1
type: Video
duration: 0 ms
language: und
media:
sample count: 0
timescale: 120000
duration: 0 (media timescale units)
duration: 0 (ms)
bitrate (computed): 6386.097 Kbps
display width: 1920.000000
display height: 817.021271
Sample Description 0
[ENCRYPTED]
Coding: encv
Scheme Type: cenc
Scheme Version: 65536
Scheme URI:
Protection System Details:
[schi] size=8+32
[tenc] size=12+20
default_AlgorithmID = 1
default_IV_size = 8
default_KID = [23 b6 70 1b e9 8b 4e ea 80 4e 9b 59 6c 59 37 a5]
Bytes: 0000000000000001000000000000000000000000000000000780033000480000004800000000000000010a41564320436f64696e670000000000000000000000000000000000000000000018ffff000000476176634301640028ffe1002e67640028acc8501e019effc0c7c0c81a808080a000007d200017701c00000301c9c380000773595359803c60c65801000668e938233c8f
Coding: avc1 (H.264)
Width: 1920
Height: 816
Depth: 24
AVC Profile: 100 (High)
AVC Profile Compat: 0
AVC Level: 40
AVC NALU Length Size: 4
AVC SPS: [67640028acc8501e019effc0c7c0c81a808080a000007d200017701c00000301c9c380000773595359803c60c658]
AVC PPS: [68e938233c8f]
Codecs String: avc1.640028
So to decrypt it using the above key, surely I would do:
mp4decrypt --key 1:23b6701be98b4eea804e9b596c5937a5 --show-progress input.mp4 output.mp4
MP4 Decrypter - Version 1.4
(Bento4 Version 1.5.0.0)
(c) 2002-2015 Axiomatic Systems, LLC
usage: mp4decrypt [options] <input> <output>
Options are:
--show-progress : show progress details
--key <id>:<k>
<id> is either a track ID in decimal or a 128-bit KID in hex,
<k> is a 128-bit key in hex
(several --key options can be used, one for each track or KID)
note: for dcf files, use 1 as the track index
note: for Marlin IPMP/ACGK, use 0 as the track ID
note: KIDs are only applicable to some encryption methods like MPEG-CENC
--fragments-info <filename>
Decrypt the fragments read from <input>, with track info read
from <filename>.
All I get is zero output on the command-line, and the output file is still unplayable.
Any ideas? the video track is for the whole file, it's not split into segments itself.
You are trying to decipher the file with the Key ID instead of the Key itself. "23 b6 70 1b e9 8b 4e ea 80 4e 9b 59 6c 59 37 a5" is the identifier of the key, not the key itself. Sure you will not decipher. It is in the file in order for the DRM system to retrieve the key (sending or searching the keyID for getting the Key itself in return).
Try to use the key value to decipher.
Your mp4encrypt command should have been used with an option like:
--key 1::0000000000000000
as your IV size is 8
I have a few thousand .ts AES-128 encrypted audio files with a .key and .m3u8 file.
The key file just contains a key comprised of 44 characters. The .m3ud files appears to be some type of playlist.
#EXTM3U
#EXT-X-ALLOW-CACHE:NO
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="http://localhost:[port]/hls/keys/nax_9781843794066.key"
#EXTINF:10,
http://localhost:[port]/filesequence0000000.ts
#EXTINF:10,
etc...
Note that both the key URI and path to the .ts files is now wrong.
Looking around, it appears ffmpeg might work with this format. But I am unsure of the syntax.
How can I decrypt and combine these files?
I have been playing around with fixing the playlist syntax and figuring out how to use ffmpeg and got to.
ffmpeg -i nax_9781843794066.m3u8 -c copy output.ts
ffmpeg version N-77197-gdf2ce13 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 5.2.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib
libavutil 55. 10.100 / 55. 10.100
libavcodec 57. 17.100 / 57. 17.100
libavformat 57. 19.100 / 57. 19.100
libavdevice 57. 0.100 / 57. 0.100
libavfilter 6. 20.100 / 6. 20.100
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
[hls,applehttp # 0000003e6348a660] Error when loading first segment 'filesequence0000000.ts'
nax_9781843794066.m3u8: Invalid data found when processing input
filesequence0000000.ts is the first file, in the same folder. I cannot tell if this is some problem with the encryption or something else.
This is the key file, if it matters: MoOoNvcKlThWBm2T+VzYq9QKZLw7MFUqSyLYjiwquTQ=
Recent versions of ffmpeg should be able to decrypt the AES-128 HLS streams. You don't need a webserver. If the m3u8 URIs/paths are wrong you can:
create a directory
copy the key to a key file, ie my.key, and place it in the dir. Note that keys can be rotated, if the playlist has multiple keys copy all of them to different files.
copy all .ts segments to the same dir
copy and edit the playlist.m3u8 and use just the filename(s) for the key(s) URI(s) and segments.
to obtain a single .ts file do:
ffmpeg -i playlist.m3u8 -c copy output.ts
if you want just the audio stream without the .ts container you can extract it. Eg: assuming you have a single audio stream using the AAC codec run:
ffmpeg -i playlist.m3u8 -map 0:a -c copy output.aac
This will extract the AAC stream to a file without re-encoding. If you want a codec different than your source you will have to re-encode.
If for some reason you have to use openssl to decrypt the segments keep in mind that if no IV is specified then the IV is equal to the segment's media sequence, ie. the first segment has IV=0, the second has IV=1 and so on. After decryption update the playlist to point the decrypted segments and remove the EXT-X-KEY line. If you go this route you don't even need ffmpeg to obtain a single .ts file as MPEG-TS is directly concatenable, ie. you can just use cat on the decrypted segments.
I've had few free hours today and toyed with this. Long story short - that base64 key is AES encrypted. This additional encryption is done with key which is dynamically generated from device data... meaning that even if I have whole data folder from your device I wouldn't be able to decrypt it.
Now, when you posses rooted device with offline data that's another matter - you can obviously inject your code to intercept key when it's decrypted so content can start playing... which is how I got it.
When you have proper key, decryption and joining of *.ts files is trivial. I recommend that you use FFMPEG for this task, my C# code that I'm leaving for illustration works well works only in some cases (depending on how files are encoded):
var folder = "path_to_folder";
byte[] encryptionKey = File.ReadAllBytes(folder + "path_to_key.key");
var outputFile = "c:\\i_love_you_guys.ts";
using (FileStream outputFileStream = new FileStream(outputFile, FileMode.Create))
{
var files = Directory.GetFiles(folder, "*.ts");
for (int i = 0; i < files.Length; i++)
{
byte[] encryptionIV = new byte[16];
using (FileStream inputFileStream = new FileStream(files[i], FileMode.Open))
{
using (var aes = new AesManaged { Key = encryptionKey, IV = encryptionIV, Mode = CipherMode.CBC })
using (var encryptor = aes.CreateDecryptor())
using (var cryptoStream = new CryptoStream(inputFileStream, encryptor, CryptoStreamMode.Read))
{
cryptoStream.CopyTo(outputFileStream);
}
}
}
}
So, this turned out to be wild goose chase. What #aergistal says in his answer is completely valid as long as you have proper my.key. Thus focus on obtaining key in plain format and decryption will then be super easy.
I have a little question about this codes:
var folder = "path_to_folder";
byte[] encryptionKey = File.ReadAllBytes(folder + "path_to_key.key");
var outputFile = "c:\\i_love_you_guys.ts";
using (FileStream outputFileStream = new FileStream(outputFile, FileMode.Create))
{
var files = Directory.GetFiles(folder, "*.ts");
for (int i = 0; i < files.Length; i++)
{
byte[] encryptionIV = new byte[16];
using (FileStream inputFileStream = new FileStream(files[i], FileMode.Open))
{
using (var aes = new AesManaged { Key = encryptionKey, IV = encryptionIV, Mode = CipherMode.CBC })
using (var encryptor = aes.CreateDecryptor())
using (var cryptoStream = new CryptoStream(inputFileStream, encryptor, CryptoStreamMode.Read))
{
cryptoStream.CopyTo(outputFileStream);
}
}
}
}
How to decrypt individually not a single file output?
I want to write a .wav file to audio device. I used alsa for that purpose. I took a sample file.Here I am copying the file sample data to buffer.
file.read(reinterpret_cast<char*>(&buff),wave.dataHeader.chunkSize);
int nframes = wave.dataHeader.chunkSize/2;
while( nframes > 0 ){
int r = snd_pcm_writei (playback_handle,
reinterpret_cast<const char*>(buff), nframes);
nframes = nframes - r;
if(r < 0){
fprintf (stderr, "write to audio interface failed (%s)\n",
snd_strerror (err));
exit (1);
}
buff += r * 2;
}
My files data is
File Size: 2084
FmtChunk Size: 16
Format Type: 1
Channels: 2
Sample Rate: 48000
Bytes Per Sec: 192000
Bits per sample: 16
here it is giving error
a.out: pcm.c:1250: snd_pcm_writei: Assertion `pcm' failed.
Aborted.
Here what should be the nframes value and how should i write to audio device any help thanks in advance.
Following is my bat file:
#echo off
mediainfo --Inform=file://template.txt "in.mp4" >info.txt
Following is my template.txt
General;File is: %FileName%\r\n
Video;\r\nFormat: %Format%\r\nCodecID: %CodecID%\r\nResolution: %Width%x%Height%\r\nDAR: %DisplayAspectRatio/String% or %DisplayAspectRatio%\r\nPAR: %PixelAspectRatio%\r\nFrameMode: %FrameRate_Mode%\r\nVideoBitrateMode: %BitRate_Mode%\r\nScanType: %ScanType%
Audio;\r\nAudioCodec: %Format%\r\nAudioBitrateMode: %BitRate_Mode%
Following is the output (in info.txt)
File is: in
Format: AVC
CodecID: avc1
Resolution: 1280x720
DAR: 16:9 or 1.778
PAR: 1.000
FrameMode: VFR
VideoBitrateMode:
ScanType: Progressive
AudioCodec: AAC
AudioBitrateMode: VBR
No matter what I do I can't get MediaInfo to give BitRate_Mode for any given file?
Following is the CLI help document for mediainfo:
Help doc
I did exhaustive tests and I have found that most of the time mediainfo doesn't return the %BitRate_Mode% on video tracks, but it does return the %BitRate_Maximum% and if you compare it to the %BitRate% and it is different, it is a VBR video, here is my template:
General;Name.........: %FileName%.%FileExtension%\r\nSize.........: %FileSize/String%\r\nDuration.....: %Duration/String3%\r\n
Video;Resolution...: %Width%x%Height%\r\nCodec........: %Codec/String% %Format_Profile%\r\nBitrate......: %BitRate/String%\r\nMax Bitrate..: %BitRate_Maximum/String%\r\nFramerate....: %FrameRate% fps\r\nAspect Ratio.: %DisplayAspectRatio/String%\r\n
Audio;Audio........: %Language/String% %BitRate/String% %BitRate_Mode% %Channel(s)% chnls %Codec/String%\r\n
Text;%Language/String%
Text_Begin;Subs.........:
Text_Middle;,
Text_End;.\r\n
It will retirn something like this:
Name.........: My Video.m4v
Size.........: 8.23 GiB
Duration.....: 02:20:02.880
Resolution...: 1920x800
Codec........: AVC High#L3.0
Bitrate......: 7 504 Kbps
Max Bitrate..: 27.1 Mbps
Framerate....: 23.976 fps
Aspect Ratio.: 2.40:1
Audio........: English 448 Kbps CBR 6 chnls AC3
Audio........: Spanish 448 Kbps CBR 6 chnls AC3
Subs.........: English, Spanish.