问题
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 ref
erence 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