6

I have a video in MP4 format that is predominantly English language, but has a scene in which a character speaks another language. I have an English subtitle track in SRT format for this character's dialogue. Is it possible to embed the subtitle track in the MP4 itself and have it be on by default without having to manually turn it on. With the command I'm currently using (below), the subtitle track is added to the file, but I have to manually select it when playing the video.

ffmpeg -i movie.mp4 -i movie.srt -c:v copy -c:a copy -c:s mov_text \
  -metadata:s:s:0 language=eng movie-sub.mp4

Is there some other bit of metadata I need to add in order for the subs to show up by default? I'd like to avoid hard subs if possible. If this is a limitation of the MP4 container, I'd be fine with switching to another format like MKV.

Output from ffmpeg:

ffmpeg version 2.1.1 Copyright (c) 2000-2013 the FFmpeg developers
  built on Dec 31 2013 15:44:02 with Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
  configuration: --prefix=/opt/local --enable-swscale --enable-avfilter --enable-avresample --enable-libmp3lame --enable-libvorbis --enable-libopus --enable-libtheora --enable-libschroedinger --enable-libopenjpeg --enable-libmodplug --enable-libvpx --enable-libspeex --enable-libass --enable-libbluray --enable-gnutls --enable-libfreetype --disable-indev=jack --disable-outdev=xv --mandir=/opt/local/share/man --enable-shared --enable-pthreads --cc=/usr/bin/clang --arch=x86_64 --enable-yasm --enable-gpl --enable-postproc --enable-libx264 --enable-libxvid --enable-version3 --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-nonfree --enable-libfaac
  libavutil      52. 48.101 / 52. 48.101
  libavcodec     55. 39.101 / 55. 39.101
  libavformat    55. 19.104 / 55. 19.104
  libavdevice    55.  5.100 / 55.  5.100
  libavfilter     3. 90.100 /  3. 90.100
  libavresample   1.  1.  0 /  1.  1.  0
  libswscale      2.  5.101 /  2.  5.101
  libswresample   0. 17.104 /  0. 17.104
  libpostproc    52.  3.100 / 52.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'movie.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2013-03-18 08:10:43
  Duration: 01:37:23.05, start: 0.000000, bitrate: 1877 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720, 1683 kb/s, 23.98 fps, 23.98 tbr, 48k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
Input #1, srt, from 'movie.srt':
  Duration: N/A, bitrate: N/A
    Stream #1:0: Subtitle: subrip
Output #0, mp4, to 'movie-sub.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Lavf55.19.104
    Stream #0:0(und): Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1280x720, q=2-31, 1683 kb/s, 23.98 fps, 48k tbn, 48k tbc (default)
    Stream #0:1(und): Audio: aac ([64][0][0][0] / 0x0040), 44100 Hz, stereo, 191 kb/s (default)
    Stream #0:2(eng): Subtitle: mov_text ([8][0][0][0] / 0x0008)
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
  Stream #1:0 -> #0:2 (subrip -> mov_text)
Press [q] to stop, [?] for help
frame=140093 fps=9457 q=-1.0 Lsize= 1340911kB time=01:37:23.04 bitrate=1880.0kbits/s    
video:1200658kB audio:136946kB subtitle:0 global headers:0kB muxing overhead 0.247196%
3
  • What player(s) did you test?
    – llogan
    Jan 11 '14 at 3:51
  • I have tried QuickTime and VLC. Both required me to manually select the subtitle track.
    – Sean
    Jan 11 '14 at 7:19
  • I think this depends on the player. My VLC will actually show all subtitles by default. I remember I always had to turn them off. Can you make a short copy of the file with ffmpeg -i movie-sub.mp4 -c copy -map 0 -t 1 out.mp4 and upload it somewhere?
    – slhck
    Jan 11 '14 at 9:16
6

The previously accepted answer is no longer correct, since the disposition flag has been added to ffmpeg. Using the example you provided, you could set the subtitle track to display by default as follows:

ffmpeg -i movie.mp4 -i movie.srt -c:v copy -c:a copy -c:s mov_text \
    -metadata:s:s:0 language=eng -disposition:s:0 default movie-sub.mp4

The format is -disposition[:stream_specifier] value.

If you need to remove a previously set disposition from a stream (for example, a stream is set to default, but you want to disable this), use the value 0.

You can see the list of available disposition options and additional examples in the ffmpeg documentation by searching for "disposition".

1
  • I tried this on an mkv file and an mp4 file (both very similar in nature). the command "runs" in both cases, but VLC will auto play the subtitle on the MKV, but not the mp4. Am I missing something on the mp4 file?
    – Andy
    Jan 4 at 0:39
2

You can use MP4Box 0.6.2-DEV-rev453 (May 2016) or higher to do this:

mp4box -add alfa.mp4 -add bravo.srt:txtflags=0xC0000000 -new charlie.mp4

Example

This will mark the subtitle stream in the output file as forced.

However, this mark will only be recognized starting with these versions of programs:


I have seen mentions to this post on the FFmpeg mailing list about a patch that implements disposition for FFmpeg:

ffmpeg -i alfa.mp4 -i bravo.srt -c copy -c:s mov_text -disposition:s forced charlie.mp4

However after having tried it with both "forced" and "default", the subtitles marked by FFmpeg are not recognized as forced by either MPC-HC or VLC.

0
1

No, there isn't an option in ffmpeg to specify a subtitle track that should be shown by default.

(ffmpeg version 2.6.1 built with gcc 4.9.2 (GCC) 20150304 (prerelease) as default on Arch, see end of answer for compile flags)

Resources highlighting the lack of command line options for setting default/forced subtitles stream in ffmpeg include the following:

Finally, this question on StackOverflow asks the same as you but for mkv, and highlights the fact that ffmpeg is the culprit since mkvpropedit (part of mkvtoolnix) can do it.

However, there is a potential workaround

This March 2013 ffmpeg bug report (still open) deals with mkv and default flag for subtitles and explains something that we can use to circumvent this limitation in some scenarios:

The Matroska specification - ​http://matroska.org/technical/specs/index.html (search for FlagDefault) - specifies that the value for the default flag is "default" if nothing is specified, the demuxer therefore marks all subtitle tracks as "default".

So ffmpeg may write the default flag on our subtitles stream in some cases; I tried it with different input video files and got mixed results:

  • with the Big Buck Bunny AVI Mpeg4 and a random .srt file, the remuxed mkv subtitles stream did have the default flag:

    $ ffmpeg -i big_buck_bunny_480p_surround-fix.avi -i subtitle.srt -c copy test.mkv
    $ ffmpeg -i test.mkv
    Input #0, matroska,webm, from 'test.mkv':
      Metadata:
        ENCODER         : Lavf56.25.101
      Duration: 00:28:31.40, start: 0.000000, bitrate: 1028 kb/s
        Stream #0:0: Video: mpeg4 (Simple Profile), yuv420p, 854x480 [SAR 1:1 DAR 427:240], 24 fps, 24 tbr, 1k tbn, 24 tbc (default)
        Stream #0:1: Audio: ac3, 48000 Hz, 5.1(side), fltp, 448 kb/s (default)
        Stream #0:2: Subtitle: subrip (default)
    
  • however I couldn't reproduce this with a sample mp4-contained H264 sample neither with a personal mp4, so I guess mp4 --> mkv doesn't work. But what if...?

    $ ffmpeg -i sample.mp4 -c copy sample.avi
    $ ffmpeg -i sample.avi -i subtitle.srt -c copy sample.mkv
    $ ffmpeg -i sample.mkv
    ...
    Input #0, matroska,webm, from 'sample.mkv':
      Metadata:
        ENCODER         : Lavf56.25.101
      Duration: 00:28:31.40, start: 0.000000, bitrate: 2 kb/s
        Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(tv, bt709), 560x320, SAR 1:1 DAR 7:4, 60 fps, 60 tbr, 1k tbn, 60 tbc (default)
        Stream #0:1: Audio: aac (LC), 48000 Hz, mono, fltp (default)
        Stream #0:2: Subtitle: subrip (default)
    

VICTORY! Doing mp4 --> avi and then avi + srt --> mkv gets the subtitles stream on by default and VLC displays them correctly.

Sure that's very roundabout and I'd rather not think of the information loss in the process, but at least it works.

Summary

  • ffmpeg is definitely not adapted right now for setting streams as default or forced,
  • mkv is probably better than mp4 as an origin container, since it has a known tool doing the job fine (mkvpropedit from mkvtoolnix).
ffmpeg version details:

ffmpeg version 2.6.1 built with gcc 4.9.2 (GCC) 20150304 (prerelease) configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-runtime-cpudetect --enable-shared --enable-swresample --enable-vdpau --enable-version3 --enable-x11grab`

2
  • 5
    I think as per this patch this is now possible. At least for me it works with ffmpeg -i in.mp4 -i in.srt -c copy -disposition:s:0 default out.mkv
    – user223771
    Feb 5 '16 at 23:22
  • As mentioned in the previous comment, this answer is no longer correct. It is now possible to set a default subtitle track with ffmpeg.
    – blendenzo
    Dec 27 '19 at 16:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.