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

0

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

Posted 2014-12-03T19:22:21.110

Reputation: 33

Answers

4

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.

llogan

Posted 2014-12-03T19:22:21.110

Reputation: 31 929

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! :) – The All Powerful – 2014-12-04T08:10:58.193

@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.

– llogan – 2014-12-05T01:34:33.960

what is -c:s mov_text AND -c:s copy ?! – Dr.jacky – 2015-08-20T10:10:04.643

1

@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.

– llogan – 2015-08-20T17:58:43.237