1

我有一个 mkv 视频,它混合了多种分辨率的记录,例如,我有前几秒的宽屏 16:9 (1024x576) 分辨率,其余的视频则为 4:3 (768x576) 分辨率。我想将此视频缩小 3 倍,同时复制所有其他属性(音频编解码器、字幕等)。我用ffmpeg -i <input_mkv> -vf scale=iw/2:-1 -acodec copy <output_mp4>. 此外,VLC 检测到它的分辨率为 720x576。

问题是缩放后,分辨率不断变为 4:3 (360x288)。如何保持输入视频文件的动态纵横比,即 16:9 部分缩放为 16:9,而 4:3 部分缩放为 4:3?

更新

当分辨率切换时,播放器大小实际上会发生变化,至少在 mplayer 中是这样。我发现了主要问题。似乎每一帧都标有一个样本纵横比(SAR),所以当玩家播放它时,它可以找到显示纵横比。编码为 MKV 时,不会复制此 SAR 值。当编码为 MPG 时,它确实被复制了,我得到了一个精确的副本,播放器切换大小,但不是 MKV。

输出ffprobe -show_streams filename

ffprobe version 0.10.3 Copyright (c) 2007-2012 the FFmpeg developers
  built on May  9 2012 17:51:07 with gcc 4.7.0 20120505 (prerelease)
  configuration: --prefix=/usr --enable-libmp3lame --enable-libvorbis --enable-libxvid --enable-libx264 --enable-libvpx --enable-libtheora --enable-libgsm --enable-libspeex --enable-postproc --enable-shared --enable-x11grab --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libschroedinger --enable-libopenjpeg --enable-librtmp --enable-libpulse --enable-gpl --enable-version3 --enable-runtime-cpudetect --disable-debug --disable-static
  libavutil      51. 35.100 / 51. 35.100
  libavcodec     53. 61.100 / 53. 61.100
  libavformat    53. 32.100 / 53. 32.100
  libavdevice    53.  4.100 / 53.  4.100
  libavfilter     2. 61.100 /  2. 61.100
  libswscale      2.  1.100 /  2.  1.100
  libswresample   0.  6.100 /  0.  6.100
  libpostproc    52.  0.100 / 52.  0.100
Input #0, matroska,webm, from 'sample.mkv':
  Metadata:
    title           : Pan prstenu. Dve veze
  Duration: 00:00:29.80, start: 0.000000, bitrate: 3124 kb/s
    Stream #0:0(eng): Video: mpeg2video (Main), yuv420p, 720x576 [SAR 64:45 DAR 16:9], 15000 kb/s, 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
    Stream #0:1(cze): Audio: mp2, 48000 Hz, stereo, s16, 128 kb/s (default)
[STREAM]
index=0
codec_name=mpeg2video
codec_long_name=MPEG-2 video
codec_type=video
codec_time_base=1/50
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
width=720
height=576
has_b_frames=1
sample_aspect_ratio=64:45
display_aspect_ratio=16:9
pix_fmt=yuv420p
level=8
timecode=16:35:19:10
id=N/A
r_frame_rate=25/1
avg_frame_rate=25/1
time_base=1/1000
start_time=0.000000
duration=N/A
nb_frames=N/A
TAG:language=eng
[/STREAM]
[STREAM]
index=1
codec_name=mp2
codec_long_name=MP2 (MPEG audio layer 2)
codec_type=audio
codec_time_base=1/48000
codec_tag_string=[0][0][0][0]
codec_tag=0x0000
sample_fmt=s16
sample_rate=48000
channels=2
bits_per_sample=0
id=N/A
r_frame_rate=0/0
avg_frame_rate=125/3
time_base=1/1000
start_time=0.000000
duration=N/A
nb_frames=N/A
TAG:language=cze
[/STREAM]
4

1 回答 1

3

FFmpeg video filters have a surprisingly rich set of logical functions for building complex filters and you should be able to use those to preserve the changing SAR in your file. Try something like this:

ffmpeg ... -vf scale='if(gt(dar\, 4/3)\, 512) + ifnot(gt(dar\, 4/3)\, 384):-1' ...

Replacing 512 and 384 with appropriate values as necessary. That said, I don't have a multi-SAR video to test with, so YMMV.

You might also look into the showinfo filter to get excruciatingly detailed information about each frame, and potentially the setsar filter, though the lack of frame-specific variables would suggest difficulty in changing it midstream.

于 2012-05-31T21:29:42.590 回答