In ffmpeg, how do I scale dvdsub subtitles to match video size, using scale2ref filter?

旧城冷巷雨未停 提交于 2021-02-10 04:17:26

问题


I have an mpeg file, recorded from live TV, containing video and multiple audio and subtitles streams. My eventual goal is to be able to create a smaller video file as the mpeg file is multi-gigabytes in size. My first step on that path is just to be able to select one each of the video, audio and subtitle streams and copy them to an mkv file, discarding the streams I'm not interested in. (I chose mkv as it will allow storing a dvdsub subtitle stream where other container formats wont.)

The problem I'm having is that the dvdsub subtitles appear very small when I play the output video, when I researched this I found that ffmpeg doesn't automatically scale the subtitles to match the source video: https://trac.ffmpeg.org/ticket/4744

I have tried using the scale2ref filter, but I don't understand the documentation, and the example they give makes no sense to me (see examples below).

I have a command that selects the three streams and copies 1 minute to the output, as follows:

ffmpeg -ss 00:28:00.200 -i Hillary-2016-08-21.mpg -t 00:01:00.000 -map 0:0 -c:v copy -map 0:3 -c:a copy -map 0:6 -c:s dvdsub cut.mkv

Here's the output:

Input #0, mpegts, from 'Hillary-2016-08-21.mpg':
  Duration: 01:30:00.06, start: 20852.199389, bitrate: 6813 kb/s
  Program 1 
    Stream #0:0[0xfa]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x12c](eng): Audio: aac_latm (HE-AAC) ([17][0][0][0] / 0x0011), 48000 Hz, stereo, fltp
    Stream #0:2[0x131](ita): Audio: aac_latm (HE-AAC) ([17][0][0][0] / 0x0011), 48000 Hz, stereo, fltp (visual impaired)
    Stream #0:3[0x191](eng): Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), fltp, 384 kb/s
    Stream #0:4[0x3ea]: Unknown: none ([11][0][0][0] / 0x000B)
    Stream #0:5[0x3ec]: Unknown: none ([11][0][0][0] / 0x000B)
    Stream #0:6[0x3fc](eng): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
    Stream #0:7[0x1f40]: Unknown: none ([5][0][0][0] / 0x0005)
File 'cut.mkv' already exists. Overwrite ? [y/N] y
Output #0, matroska, to 'cut.mkv':
  Metadata:
    encoder         : Lavf57.56.100
    Stream #0:0: Video: h264 (Main) (H264 / 0x34363248), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 25 fps, 50 tbr, 1k tbn, 90k tbc
    Stream #0:1(eng): Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, 5.1(side), 384 kb/s
    Stream #0:2(eng): Subtitle: dvd_subtitle (dvdsub) (hearing impaired)
    Metadata:
      encoder         : Lavc57.64.101 dvdsub
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:3 -> #0:1 (copy)
  Stream #0:6 -> #0:2 (dvb_subtitle (dvbsub) -> dvd_subtitle (dvdsub))
Press [q] to stop, [?] for help
frame= 2956 fps=0.0 q=-1.0 Lsize=   39612kB time=00:00:59.99 bitrate=5408.7kbits/s speed= 216x    
video:36702kB audio:2896kB subtitle:23kB other streams:0kB global headers:0kB muxing overhead: unknown

The documentation for scale2ref gives an example with an overlay, and I don't want to overlay anything, I just want to resize the subtitles stream. Here's their example:

'scale2ref[b][a];[a][b]overlay'

The closest I've got is something like this:

ffmpeg -ss 00:28:00.200 -i Hillary-2016-08-21.mpg -t 00:01:00.000 -map 0:0 -c:v copy -map 0:3 -c:a copy -filter_complex "[0:6]scale2ref[b]" -map "[b]"   cut.mkv

And the output is:

Input #0, mpegts, from 'Hillary-2016-08-21.mpg':
  Duration: 01:30:00.06, start: 20852.199389, bitrate: 6813 kb/s
  Program 1 
    Stream #0:0[0xfa]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x12c](eng): Audio: aac_latm (HE-AAC) ([17][0][0][0] / 0x0011), 48000 Hz, stereo, fltp
    Stream #0:2[0x131](ita): Audio: aac_latm (HE-AAC) ([17][0][0][0] / 0x0011), 48000 Hz, stereo, fltp (visual impaired)
    Stream #0:3[0x191](eng): Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), fltp, 384 kb/s
    Stream #0:4[0x3ea]: Unknown: none ([11][0][0][0] / 0x000B)
    Stream #0:5[0x3ec]: Unknown: none ([11][0][0][0] / 0x000B)
    Stream #0:6[0x3fc](eng): Subtitle: dvb_subtitle ([6][0][0][0] / 0x0006) (hearing impaired)
    Stream #0:7[0x1f40]: Unknown: none ([5][0][0][0] / 0x0005)
Streamcopy requested for output stream 0:0, which is fed from a complex filtergraph. Filtering and streamcopy cannot be used together.

And I don't really understand how I can use a filter and direct my resized subtitle stream into the output file.

Any help appreciated! Thanks!


回答1:


scale2ref tags both its output as video streams, which is what they almost always are. So ffmpeg is applying the value of c:v to the scaled subs.

Instead, you should try

ffmpeg -ss 28:00.2 -canvas_size 1920x1080 -i Hillary-2016-08-21.mpg -t 1:00 -map 0:0 -c:v copy -map 0:3 -c:a copy -map 0:6 -c:s dvdsub cut.mkv

Use

ffmpeg -ss 28:00.2 -i Hillary-2016-08-21.mpg -t 1:00 -filter_complex "[0:6][0:0]scale2ref[b][a]" -map 0:0 -c:v copy -map 0:3 -c:a copy -map "[b]" cut.mkv -map "[a]" -f null -

scale2ref takes two inputs and spits two outputs. The 2nd element at both ends is the reference video. So ffmpeg has to be told what to do with the passthrough copy of that reference. In the command above, the null muxer is assigned, which sends it to oblivion.



来源:https://stackoverflow.com/questions/41818276/in-ffmpeg-how-do-i-scale-dvdsub-subtitles-to-match-video-size-using-scale2ref

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!