Good day,

I try to encrypt and decrypt a segment file (MP4 fragment) which has been generated by FFmpeg. Bento4 seems to provide multiple ways to do this, but all of them either fail with relatively unspecific error messages or end up just copying the file.

Input file(s)
===

I use a 25-fps file with one audio track and one video track (I tried multiple different ones). I encode the file using FFmpeg like this:

    ffmpeg -i input.mp4 -acodec aac -vcodec h264_nvenc -b:v 2500k -g 5 -rc cbr_ld_hq -hls_segment_type fmp4 -hls_time 2 -hls_segment_filename stream-%%18d.m4s -hls_fmp4_init_filename init.mp4 -hls_playlist_type vod -t 10 index.m3u8

This generates a playlist (index.m3u8), an initialization segment (init.mp4) and five segments (stream-000000000000000000.m4s to stream-000000000000000004.m4s). For testing, I only use the initialization segment (init.mp4) and the first segment (stream-000000000000000000.m4s). They are placed in a folder called orig. I uploaded them as [segment.zip](https://github.com/axiomatic-systems/Bento4/files/5943732/segment.zip) here for reproducibility.

Encryption attempts
===

I tried to encrypt the first segment using the three different ways offered by Bento4 - mp4-hls, mp4-dash as well as mp4encrypt directly.

mp4-hls
---

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\utils\mp4-hls.py --exec-dir=.\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin --encryption-key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -o enc\ orig\stream-000000000000000000.m4s

This call fails with the following output:
```
Parsing media file orig\stream-000000000000000000.m4s
ERROR: 'tracks'
```
It seems that mp4-hls does not support fragmented MP4 files (that's reasonable since there is no parameter to pass the initialization segment). A more specific error message would, however, be nice.

mp4-dash
---

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\utils\mp4-dash.py --exec-dir=.\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin --encryption-key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb --encryption-cenc-scheme=cbcs --init-segment=orig\init.mp4 --hls -o enc\ orig\stream-000000000000000000.m4s

This call fails and prints "ERROR: 'tracks'". As this was not very descriptive, I investigated it in a debugger and found that mp4info seems to be unable to find any tracks. I do not understand why. However, a more detailed error message would, again, be nice.

mp4encrypt
---

I tried encryption with two different methods:

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin\mp4encrypt.exe --method MPEG-CENC --key 1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbb --key 2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbb --fragments-info orig\init.mp4 orig\stream-000000000000000000.m4s enc\stream-000000000000000000.m4s

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin\mp4encrypt.exe --method MPEG-CBCS --key 1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb --key 2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb --fragments-info orig\init.mp4 orig\stream-000000000000000000.m4s enc\stream-000000000000000000.m4s

Both calls seem to generate an encrypted fragment named stream-000000000000000000.m4s in the folder enc, but I cannot get them decrypted (see below).

Decryption attempts
===

I tried to decrypt the encrypted segment (that I generated with mp4encrypt) in two different ways - with mp4decrypt and with a specifically designed playlist to be used with FFplay.

mp4decrypt
---

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin\mp4decrypt.exe --key 1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --key 2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --fragments-info orig\init.mp4 enc\stream-000000000000000000.m4s dec\stream-000000000000000000.m4s

This call seems to succeed, but the output segment is bit-identical to the input file. mp4decrypt seems to just copy the file and there is no error message.

FFplay
---

To play back the encrypted segment (forcing decryption in the process), I copy the initialization segment (init.mp4) and the encrypted segment into a new folder, add a key.bin file with 16 bytes of "aa" (hex) and design a playlist (index.m3u8) file like the following:

```
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="init.mp4"
#EXT-X-KEY:METHOD=AES-128,URI="key.bin",IV=0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
#EXTINF:2.000000,
stream-000000000000000000.m4s
#EXT-X-ENDLIST
```

*Note: I adjust the IV depending on the method, see above*.

Attempting to play back the playlist with

    ffplay -allowed_extensions ALL .\index.m3u8

results in FFplay not recognizing the file properly:

    Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none, 1920x1080): unspecified pixel format

Question
===

How can I use Bento4 to encrypt and decrypt an FFmpeg-generated fMP4 segment? Decryption can be done by either Bento4 or FFplay. I explained my attempts above - if I have made a mistake somewhere, please let me know and maybe use it as input for some more detailed error messages, where applicable. Thank you.
Encryption and decryption failure on FFmpeg-generated fMP4 segments
This is a GitHub Issue
repo:Bento4
owner:axiomatic-systems
Title : Encryption and decryption failure on FFmpeg-generated fMP4 segments
Issue date:

--- start body ---
Good day,

I try to encrypt and decrypt a segment file (MP4 fragment) which has been generated by FFmpeg. Bento4 seems to provide multiple ways to do this, but all of them either fail with relatively unspecific error messages or end up just copying the file.

Input file(s)
===

I use a 25-fps file with one audio track and one video track (I tried multiple different ones). I encode the file using FFmpeg like this:

    ffmpeg -i input.mp4 -acodec aac -vcodec h264_nvenc -b:v 2500k -g 5 -rc cbr_ld_hq -hls_segment_type fmp4 -hls_time 2 -hls_segment_filename stream-%%18d.m4s -hls_fmp4_init_filename init.mp4 -hls_playlist_type vod -t 10 index.m3u8

This generates a playlist (index.m3u8), an initialization segment (init.mp4) and five segments (stream-000000000000000000.m4s to stream-000000000000000004.m4s). For testing, I only use the initialization segment (init.mp4) and the first segment (stream-000000000000000000.m4s). They are placed in a folder called orig. I uploaded them as [segment.zip](https://github.com/axiomatic-systems/Bento4/files/5943732/segment.zip) here for reproducibility.

Encryption attempts
===

I tried to encrypt the first segment using the three different ways offered by Bento4 - mp4-hls, mp4-dash as well as mp4encrypt directly.

mp4-hls
---

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\utils\mp4-hls.py --exec-dir=.\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin --encryption-key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -o enc\ orig\stream-000000000000000000.m4s

This call fails with the following output:
```
Parsing media file orig\stream-000000000000000000.m4s
ERROR: 'tracks'
```
It seems that mp4-hls does not support fragmented MP4 files (that's reasonable since there is no parameter to pass the initialization segment). A more specific error message would, however, be nice.

mp4-dash
---

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\utils\mp4-dash.py --exec-dir=.\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin --encryption-key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb --encryption-cenc-scheme=cbcs --init-segment=orig\init.mp4 --hls -o enc\ orig\stream-000000000000000000.m4s

This call fails and prints "ERROR: 'tracks'". As this was not very descriptive, I investigated it in a debugger and found that mp4info seems to be unable to find any tracks. I do not understand why. However, a more detailed error message would, again, be nice.

mp4encrypt
---

I tried encryption with two different methods:

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin\mp4encrypt.exe --method MPEG-CENC --key 1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbb --key 2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbb --fragments-info orig\init.mp4 orig\stream-000000000000000000.m4s enc\stream-000000000000000000.m4s

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin\mp4encrypt.exe --method MPEG-CBCS --key 1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb --key 2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb --fragments-info orig\init.mp4 orig\stream-000000000000000000.m4s enc\stream-000000000000000000.m4s

Both calls seem to generate an encrypted fragment named stream-000000000000000000.m4s in the folder enc, but I cannot get them decrypted (see below).

Decryption attempts
===

I tried to decrypt the encrypted segment (that I generated with mp4encrypt) in two different ways - with mp4decrypt and with a specifically designed playlist to be used with FFplay.

mp4decrypt
---

    .\Bento4-SDK-1-6-0-637.x86_64-microsoft-win32\bin\mp4decrypt.exe --key 1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --key 2:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --fragments-info orig\init.mp4 enc\stream-000000000000000000.m4s dec\stream-000000000000000000.m4s

This call seems to succeed, but the output segment is bit-identical to the input file. mp4decrypt seems to just copy the file and there is no error message.

FFplay
---

To play back the encrypted segment (forcing decryption in the process), I copy the initialization segment (init.mp4) and the encrypted segment into a new folder, add a key.bin file with 16 bytes of "aa" (hex) and design a playlist (index.m3u8) file like the following:

```
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="init.mp4"
#EXT-X-KEY:METHOD=AES-128,URI="key.bin",IV=0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
#EXTINF:2.000000,
stream-000000000000000000.m4s
#EXT-X-ENDLIST
```

*Note: I adjust the IV depending on the method, see above*.

Attempting to play back the playlist with

    ffplay -allowed_extensions ALL .\index.m3u8

results in FFplay not recognizing the file properly:

    Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none, 1920x1080): unspecified pixel format

Question
===

How can I use Bento4 to encrypt and decrypt an FFmpeg-generated fMP4 segment? Decryption can be done by either Bento4 or FFplay. I explained my attempts above - if I have made a mistake somewhere, please let me know and maybe use it as input for some more detailed error messages, where applicable. Thank you.
--- end body ---
