ffmpeg trying to hardcode subs using -c:s mov_text but fails

7,235

I believe HDMV Presentation Graphic Stream subtitles (hdmv_pgs_subtitle) are image based, not text based, so they can't be converted to text because ffmpeg does not currently support OCR conversions.

Hardsubs

You will be able to create hardsubs, but that means you would have to re-encode the video:

ffmpeg -i in.mkv -filter_complex "[0:v][0:s]overlay[v]" -map "[v]" -map 0:a \
-c:a copy out.mp4

You may have to use the scale filter to resize the subtitle stream so it will fit if it is larger than your video (otherwise they will be rendered outside the frame and not be visible):

ffmpeg -i in.mkv -filter_complex "[0:s]scale=1280:-1[sub];[0:v][sub]overlay[v]" \
-map "[v]" -map 0:a -c:a copy out.mp4

Alternatively you could just position the subtitles with overlay if you don't want to scale them.

The ffmpeg console output should display the input subtitle frame size, or use ffprobe:

$ ffprobe -v error -of flat=s=_ -select_streams s:0 -show_entries stream=height,width input.mkv 
streams_stream_0_width=1920
streams_stream_0_height=108

Also see:

Softsubs

Perhaps a better choice may be to search for a suitable existing softsub file. I've never done this, and apparently I'm too lazy to research it, so I don't know the availability.

Note that MP4 is a poor choice for softsubs, so mov_text may not even be playable by your device or player.

Share:
7,235

Related videos on Youtube

The All Powerful
Author by

The All Powerful

Updated on September 18, 2022

Comments

  • The All Powerful
    The All Powerful over 1 year

    Please bear with me; I'm still learning the intricacies of ffmpeg and have hit a problem with subtitles.

    So, I am trying to change the container of a video from mkv to mp4, and simultaneously hardcode the subtitles onto the video so that my Playstation will accept them.

    The mkv is structured as follows:

    ffmpeg version git-2013-09-23-34b429d Copyright (c) 2000-2013 the FFmpeg developers
      built on Sep 23 2013 18:16:42 with gcc 4.7 (Ubuntu/Linaro 4.7.3-1ubuntu1)
      configuration: --prefix=/home/seb/ffmpeg_build --extra-cflags=-I/home/seb/ffmpeg_build/include --extra-ldflags=-L/home/seb/ffmpeg_build/lib --bindir=/home/seb/bin --extra-libs=-ldl --enable-gpl --enable-libass --enable-libfdk-aac --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab
      libavutil      52. 46.100 / 52. 46.100
      libavcodec     55. 33.100 / 55. 33.100
      libavformat    55. 18.102 / 55. 18.102
      libavdevice    55.  3.100 / 55.  3.100
      libavfilter     3. 87.100 /  3. 87.100
      libswscale      2.  5.100 /  2.  5.100
      libswresample   0. 17.103 /  0. 17.103
      libpostproc    52.  3.100 / 52.  3.100
    [matroska,webm @ 0xa52ce60] Could not find codec parameters for stream 2 (Subtitle: hdmv_pgs_subtitle): unspecified size
    Consider increasing the value for the 'analyzeduration' and 'probesize' options
    Input #0, matroska,webm, from 'entirely-innocent-video.mkv':
      Metadata:
        creation_time   : 2014-11-15 09:27:00
      Duration: 02:10:24.29, start: 0.000000, bitrate: 3838 kb/s
        <--BLAH BLAH BLAH CHAPTERS -->
        Stream #0:0(eng): Video: h264 (High), yuv420p(tv, bt709), 1280x690 [SAR 1:1 DAR 128:69], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
        Metadata:
          BPS             : 3196139
          BPS-eng         : 3196139
          DURATION        : 02:10:24.233000000
          DURATION-eng    : 02:10:24.233000000
          NUMBER_OF_FRAMES: 187594
          NUMBER_OF_FRAMES-eng: 187594
          NUMBER_OF_BYTES : 3125917529
          NUMBER_OF_BYTES-eng: 3125917529
          _STATISTICS_WRITING_APP: mkvmerge v7.3.0 ('Nouages') 32bit built on Oct 22 2014 18:44:01
          _STATISTICS_WRITING_APP-eng: mkvmerge v7.3.0 ('Nouages') 32bit built on Oct 22 2014 18:44:01
          _STATISTICS_WRITING_DATE_UTC: 2014-11-15 09:27:00
          _STATISTICS_WRITING_DATE_UTC-eng: 2014-11-15 09:27:00
          _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
          _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
        Stream #0:1(eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
        Metadata:
          BPS             : 640000
          BPS-eng         : 640000
          DURATION        : 02:10:24.288000000
          DURATION-eng    : 02:10:24.288000000
          NUMBER_OF_FRAMES: 244509
          NUMBER_OF_FRAMES-eng: 244509
          NUMBER_OF_BYTES : 625943040
          NUMBER_OF_BYTES-eng: 625943040
          _STATISTICS_WRITING_APP: mkvmerge v7.3.0 ('Nouages') 32bit built on Oct 22 2014 18:44:01
          _STATISTICS_WRITING_APP-eng: mkvmerge v7.3.0 ('Nouages') 32bit built on Oct 22 2014 18:44:01
          _STATISTICS_WRITING_DATE_UTC: 2014-11-15 09:27:00
          _STATISTICS_WRITING_DATE_UTC-eng: 2014-11-15 09:27:00
          _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
          _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
        Stream #0:2(eng): Subtitle: hdmv_pgs_subtitle (default) (forced)
        Metadata:
          BPS             : 840
          BPS-eng         : 840
          DURATION        : 01:40:03.622000000
          DURATION-eng    : 01:40:03.622000000
          NUMBER_OF_FRAMES: 252
          NUMBER_OF_FRAMES-eng: 252
          NUMBER_OF_BYTES : 630808
          NUMBER_OF_BYTES-eng: 630808
          _STATISTICS_WRITING_APP: mkvmerge v7.3.0 ('Nouages') 32bit built on Oct 22 2014 18:44:01
          _STATISTICS_WRITING_APP-eng: mkvmerge v7.3.0 ('Nouages') 32bit built on Oct 22 2014 18:44:01
          _STATISTICS_WRITING_DATE_UTC: 2014-11-15 09:27:00
          _STATISTICS_WRITING_DATE_UTC-eng: 2014-11-15 09:27:00
          _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
          _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
    

    I then use the following command:

    ffmpeg -i entirely-innocent-video -c:v copy -c:a copy -c:s mov_text entirely-innocent-video.mp4
    

    Which as far as I can see should re-code the video, leaving the audio and video untouched, but hardcode in the subtitles... But it doesn't... It fails with the following message:

    Error while opening encoder for output stream #0:2 - maybe incorrect parameters such as bit_rate, rate, width or height
    

    And I just can't work out why! I've tried all sorts of permutations on the -c:s mov_text command but just keep getting error messages!

    At a guess I'd say it has something to do with this message:

    [matroska,webm @ 0xa52ce60] Could not find codec parameters for stream 2 (Subtitle: hdmv_pgs_subtitle): unspecified size
        Consider increasing the value for the 'analyzeduration' and 'probesize' options
    

    But I'm just not experienced enough with ffmpeg to know where to start doing anything about it...

    Can any of you clever experienced people help me unravel what's going on? :)

    Thanks!

    Seb

  • The All Powerful
    The All Powerful over 9 years
    So, your hardcode script APPEARED to work; It ran without errors, and made all the right noises. I left it overnight to recode, and when I got up this morning I had a finished MP4, with good video and audio but still no subs... I'm beginning to wonder about whether it's a problem with the actual subtitles themselves, so I'm going to download a set of external subs later and try with those to see if I can get it working that way... Thanks for your help! :)
  • Elisa Cha Cha
    Elisa Cha Cha over 9 years
    @TheAllPowerful I now know what the issue is. The subtitles are being overlaid, but if the subtitles "frame size" is too big then it will go out of frame and be invisible. Example updated. Use the -ss and -t options if you want to test just a segment.
  • Dr.jacky
    Dr.jacky over 8 years
    what is -c:s mov_text AND -c:s copy ?!
  • Elisa Cha Cha
    Elisa Cha Cha over 8 years
    @Mr.Hyde -c:s mov_text will encode text-based subtitles as "3GPP TS 26.245 Timed Text". -c:s copy will stream copy the subtitles stream.