Reputation: 868
I'm currently using FFMPEG to embed subtitles into my MP4 files and I am stumped trying to figure out how to custom set the "handler_name" metadata tag on my subtitle stream so I can control the name that is displayed when selecting the subtitle within a player like MPC-HC (Media Player Classic)?
My current command to embed the subtitle is:
ffmpeg -i "video.mp4" -sub_charenc UTF-8 -i "video.srt" -c:v copy -c:a copy -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:0 handler_name="English" -id3v2_version 3 -write_id3v1 1 "subbed_video.mp4"
Output:
C:\path\to>ffmpeg -y -i "video.mp4" -sub_charenc UTF-8 -i "video.srt" -c:v copy -c:a copy -c:s mov_text -metadata:s:s:0 language="eng" -metadata:s:s:0 handler_name="English" -id3v2_version 3 -write_id3v1 1 "subbed_video.mp4"
ffmpeg version N-68482-g92a596f Copyright (c) 2000-2014 the FFmpeg developers
built on Dec 16 2014 02:53:08 with gcc 4.9.2 (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-libfreetype --enable-libgme --enable-libgsm --enable
libavutil 54. 15.100 / 54. 15.100
libavcodec 56. 15.100 / 56. 15.100
libavformat 56. 15.105 / 56. 15.105
libavdevice 56. 3.100 / 56. 3.100
libavfilter 5. 3.101 / 5. 3.101
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf55.34.101
Duration: 01:27:44.17, start: 0.000000, bitrate: 878 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x536 [SAR 1:1 DAR 160:67], 842 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (HE-AAC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 32 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream #0:2(eng): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s (default)
Metadata:
handler_name : SubtitleHandler
Input #1, srt, from 'video.srt':
Duration: N/A, bitrate: N/A
Stream #1:0: Subtitle: subrip
Output #0, mp4, to 'subbed_video.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.15.105
Stream #0:0(und): Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1280x536 [SAR 1:1 DAR 160:67], q=2-31, 842 kb/s, 24 fps, 24 tbr, 12288 tbn, 12288 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac ([64][0][0][0] / 0x0040), 48000 Hz, stereo, 32 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream #0:2(eng): Subtitle: mov_text ([8][0][0][0] / 0x0008) (default)
Metadata:
handler_name : English
encoder : Lavc56.15.100 mov_text
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Stream #0:2 -> #0:2 (mov_text (native) -> mov_text (native))
Press [q] to stop, [?] for help
frame=126337 fps=13751 q=-1.0 Lsize= 564499kB time=01:27:44.17 bitrate= 878.5kbits/s
video:541239kB audio:20564kB subtitle:39kB other streams:0kB global headers:0kB muxing overhead: 0.472881%
The command completes sucessfully, but when I run:
ffmpeg -i "C:\path\to\subbed_video.mp4"
it shows:
Stream #0:2(eng): Subtitle: mov_text (tx3g / 0x67337874), 0 kb/s (default)
Metadata:
handler_name : SubtitleHandler
Even though the output from the command shows:
Stream #0:2(eng): Subtitle: mov_text ([8][0][0][0] / 0x0008) (default)
Metadata:
handler_name : English
encoder : Lavc56.15.100 mov_text
No matter what options I have tried or what order I place the -metadata tags in, this tag simply will not set with FFMPEG? I find it really ugly to see SubtitleHandler [eng] (tx3g) (English) within my player's menu instead of simply saying English.
Now, I can work around this issue by using MP4BOX to embed the subtitles into my mp4's using:
MP4BOX -lang eng -add "video.srt:name=English" "video.mp4" -out "subbed_video.mp4"
Adding "name=English" allows me to set the subtitle stream's "handler_name" to "English"; which displays perfectly in FFMPEG and MPC-HC, but the problem is that I do not want my app to be dependent on an additional external tool like MP4BOX if it can be avoided?
I would greatly appreciate any advice regarding how to properly set the "handler_name" tag on my subtitle stream using FFMPEG, or maybe a confirmation as to whether FFMPEG can even handle this tag seeing as it is not technically listed in FFMPEG's valid metadata tag list?
P.S. As an alternative to FFMPEG, I would be willing to use AtomicParsley to set the "handler_name" as I will already be using it to set advanced metadata on the "subbed_video.mp4" after I embed the subtitles. It does seem like it would be possible to do with AtomicParsley, but I have not been able to understand half the help information with regards to setting custom ATOM's.
TIA!!
Upvotes: 9
Views: 15138
Reputation: 11
I've had no luck setting the label for subtitle (or audio) streams using ffmpeg, at least not in a way that players show. After a ton of research, it seems that what vlc and other players show for the stream labels isn't based on the handler at all, but is based on the UDTA name atom in the mp4/QuickTime metadata.
The only tool I've been able to find that will reliably set the UDTA name in a way that is shown by VLC and other players without re-encoding or adding a new stream has been GPAC/mp4box, and this is only a very recently added (in Oct 2020) feature:
MP4Box -udta TRACKID:type=name:str="Track Label" file.mp4
Upvotes: 1
Reputation: 1788
If you're using VLC and the accepted answer didn't work, you should add the title
option to your stream metadata. Using OPs example:
ffmpeg -i "video.mp4" -sub_charenc UTF-8 -i "video.srt" -c:v copy -c:a copy -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:0 title="English" -id3v2_version 3 -write_id3v1 1 "subbed_video.mp4"
Same goes for other streams. Tested on FFmpeg version N-79630-g9ac154d.
Upvotes: 1
Reputation: 868
Finally figured it out today, and I cannot believe I didn't try this before...Although the tag name is listed as handler_name= in FFMPEG's output, the active tag to use is just handler=, without adding _name.
-metadata:s:s:0 handler="English"
ffmpeg -i "video.mp4" -sub_charenc UTF-8 -i "video.srt" -c:v copy -c:a copy -c:s mov_text -metadata:s:s:0 language=eng -metadata:s:s:0 handler="English" -id3v2_version 3 -write_id3v1 1 "subbed_video.mp4"
Upvotes: 11