gpt4 book ai didi

audio - 为什么我不能用 ffmpeg 重新排序我的 mpg 容器中的流?

转载 作者:行者123 更新时间:2023-12-04 07:49:29 26 4
gpt4 key购买 nike

背景:Could having audio as stream 0 and video as stream 1 explain why my MPG will play on OSX QuickTime Player, but not Win10 Movies & TV?
我有一个 mpg 文件,其中音频作为流 0,视频作为流 1。
它在 OSX QT Player 下可以正常播放,但在 Win10 的默认应用程序下无法正常播放。
由于缺乏更好的主意,我假设异常的流排序是我的问题,我正在尝试用 ffmpeg 修复它。
多么幸运! https://trac.ffmpeg.org/wiki/Map准确地描述了我的情况!

Re-order streams

The order of your -map options determines the order of the streams in the output. In this example the input file has audio as stream #0 and video as stream #1 (which is possible but unusual). Example to re-position video so it is listed first, followed by the audio:

ffmpeg -i input.mp4 -map 0:v -map 0:a -c copy output.mp4

This example stream copies (re-mux) with -c copy to avoid re-encoding.


我完全使用该命令,但翻转似乎不起作用,如下所示:
ffprobe -hide_banner myfile.trimmed.mpg
[h264 @ 000001b965b569c0] Increasing reorder buffer to 2
Input #0, mpeg, from 'myfile.trimmed.mpg':
Duration: 00:02:41.09, start: 0.500000, bitrate: 6255 kb/s
Stream #0:0[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream #0:1[0x1e2]: Video: h264 (High), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc
ffmpeg -hide_banner -i myfile.trimmed.mpg -map 0:v -map 0:a -c copy myfile.trimmed.flipped.mpg
[h264 @ 000001fa0ee94680] Increasing reorder buffer to 2
Input #0, mpeg, from 'myfile.trimmed.mpg':
Duration: 00:02:41.09, start: 0.500000, bitrate: 6255 kb/s
Stream #0:0[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream #0:1[0x1e2]: Video: h264 (High), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc
[mpeg @ 000001fa0ee88dc0] VBV buffer size not set, using default size of 230KB
If you want the mpeg file to be compliant to some specification
Like DVD, VCD or others, make sure you set the correct buffer size
[mpeg @ 000001fa0ee88dc0] ac3 in MPEG-1 system streams is not widely supported, consider using the vob or the dvd muxer to force a MPEG-2 program stream.
Output #0, mpeg, to 'myfile.trimmed.flipped.mpg':
Metadata:
encoder : Lavf58.45.100
Stream #0:0: Video: h264 (High), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 59.94 fps, 59.94 tbr, 90k tbn, 59.94 tbc
Stream #0:1: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Stream #0:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 9570 fps=0.0 q=-1.0 Lsize= 123008kB time=00:02:40.95 bitrate=6260.6kbits/s speed= 518x
video:114772kB audio:7545kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.565047%
ffprobe -hide_banner myfile.trimmed.flipped.mpg
[h264 @ 0000021edcf36ac0] Increasing reorder buffer to 2
Input #0, mpeg, from 'myfile.trimmed.flipped.mpg':
Duration: 00:02:41.09, start: 0.500000, bitrate: 6255 kb/s
Stream #0:0[0x80]: Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream #0:1[0x1e2]: Video: h264 (High), yuv420p(tv, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc
什么什么?!
命令输出看起来完全符合我的要求,但生成的文件具有与原始文件相同的流顺序。 我错过了什么?
一个可能的线索:看起来音频流在视频流之前开始。我在音频流中看到的最小 pkt_pts_time 是 00:00:00.500000,而我在视频流中看到的最小是 0:00:01.912967。 那有关系吗?

最佳答案

起初看起来很棘手。我想知道 this old FFmpeg trac ticket 是否可能掌握关键:

There is no stream order in mpeg-ps.what you see from ffmpeg output order is likely just if a audio or video packet comes first


但这实际上不是问题。但是值得注意的是,当您应该尝试输出 MP4 或 MKV 时,您的文件具有 .mpg 扩展名。 ".mpg" is only valid if it contains legacy MPEG-1 and MPEG-2 formats 。 H.264 或 AAC 基本流无效。
如果您没有自己创建此文件,则它可能是一个错误标记的容器(例如 MKV 或 MP4),或者有人奇怪地将流混合到 .mpg。请注意 FFmpeg 在您的流重新排序尝试期间如何警告您不兼容的编解码器。
MPEG-PS 是一种分组格式,因此不存在这样的基本流。如果它是真正的 MPEG-PS 文件,则可能首先出现一个音频样本。无论哪种方式,您都应该放弃使用 .mpg 作为您的格式。
请参阅此答案的结尾,了解如何使用 FFprobe 相当准确地识别实际容器格式。
我又想了想,最后一个神经元提醒了我 -map 输出是如何遵循赋值顺序的。
需要注意的重要一点是, -map 0:v -map 0:a 对于包含多个流类型的文件并不完全符合您的预期,因为该语法匹配该类型的所有适用流。

Gyan 澄清说,如果您的文件只有一个视频和一个音频流,则 -map 0:v -map 0:a 将等效于 -map 0:1 -map 0:0
如果您想使用 0:a 语法,例如,如果您有多个音频,则必须单独处理它们,否则 FFmpeg 将在重新排序时将它们分组。 -map 0:a 将移动两个音频; -map 0:a:0 只会移动第一个音频。
另一种方法,记住始终检查您操作的每个文件中的流顺序,是按照您希望它们在输出中的顺序指定绝对流编号。因此,如果您的视频是源文件中两个流中的第二个,则为 -map 0:1 -map 0:0
对于具有一个视频和一个音频流的文件,您可以使用任一方法。

测试
我创建了一个 .MP4 文件,其中包含一个作为流 0:0 的 H.264 视频和一个作为流 0:1 的 MP3 音频。
原始文件:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\temp\video-audio.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.78.100
Duration: 00:05:00.30, start: 0.000000, bitrate: 422 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 421 kb/s, 23.98 fps, 23.98 tbr, 11988 tbn, 47.95 tbc (default)
Metadata:
handler_name : GPAC ISO Video Handler
vendor_id : [0][0][0][0]
Stream #0:1(und): Audio: mp3 (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 180 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
然后我把它反馈给 FFmpeg:

ffmpeg -i C:\temp\video-audio.mp4 -map 0:1 -map 0:0 -c copy C:\temp\swapped.mp4
(equivalent to -map 0:a -map 0:v in this case)


结果:交换流; MP3 音频流为 0:0,H.264 视频流为 0:1
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\temp\swapped.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.78.100
Duration: 00:05:00.30, start: 0.000000, bitrate: 422 kb/s
Stream #0:0(und): Audio: mp3 (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 180 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 421 kb/s, 23.98 fps, 23.98 tbr, 11988 tbn, 47.95 tbc (default)
Metadata:
handler_name : GPAC ISO Video Handler
vendor_id : [0][0][0][0]
这似乎可以完成您想要的:-)

ffmpeg -i INPUTFILE -map 0:1 -map 0:0 -c copy OUTPUTFILE.mp4 or
ffmpeg -i INPUTFILE -map 0:v -map 0:a -c copy OUTPUTFILE.mp4


提醒:
  • 对于一个视频和一个音频流的文件,您可以使用上述任一方法。
  • 对于具有多个音频或视频的文件,确定流索引并使用更细化的 0:v:00:a:0 语法进行指定。
  • ffmpeg -i INPUTFILE 显示文件的数字流 ID,这对于奇数文件可能更快。但是,数字引用在重新排序时会跳过仅指定音频、视频、字幕等的完整性检查。
    FFmpeg's Stream SpecifiersAdvanced Options 文档值得收藏。
    进一步阅读:
  • FFmpeg Trac documentation for -maptheir main documentation for -map
  • This previous Q&A on Video.SE ,它又引用了 this answer ,它谈到了 -disposition 开关。注意 -disposition 用于指示播放器“应该”将哪些流视为默认流( Section 5.4, "Main Options" in the FFmpeg docs ),而不是进行任何物理流重新排序。

  • (非常感谢 Gyan 如此细心!)

    使用FFprobe识别容器
    FFprobe 可以尽最大努力检测真正的容器格式,忽略扩展名。这是我的演示“swapped.mp4”的示例,重命名为 .mpg:
    ffprobe -hide_banner -show_error -show_format -i "C:\temp\swapped.mpg"
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\temp\swapped.mpg':
    Metadata:
    major_brand : isom
    minor_version : 512
    compatible_brands: isomiso2avc1mp41
    encoder : Lavf58.78.100
    Duration: 00:05:00.30, start: 0.000000, bitrate: 422 kb/s
    Stream #0:0(und): Audio: mp3 (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 180 kb/s (default)
    Metadata:
    handler_name : SoundHandler
    vendor_id : [0][0][0][0]
    Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 421 kb/s, 23.98 fps, 23.98 tbr, 11988 tbn, 47.95 tbc (default)
    Metadata:
    handler_name : GPAC ISO Video Handler
    vendor_id : [0][0][0][0]
    [FORMAT]
    filename=C:\temp\swapped.mpg
    nb_streams=2
    nb_programs=0
    format_name=mov,mp4,m4a,3gp,3g2,mj2
    format_long_name=QuickTime / MOV
    start_time=0.000000
    duration=300.301000
    size=15847817
    bit_rate=422184
    probe_score=100
    TAG:major_brand=isom
    TAG:minor_version=512
    TAG:compatible_brands=isomiso2avc1mp41
    TAG:encoder=Lavf58.78.100
    [/FORMAT]
    注意 major_brand=isom ( ISO Base Media file format)、 format_nameformat_long_name 等。
    我上个月制作的一个真正的 MPEG-2 视频(DVD 翻录)输出如下:
    ffprobe -hide_banner -show_error -show_format -i "C:\temp\opera.mpg"
    Input #0, mpeg, from 'C:\temp\opera.mpg':
    Duration: 02:15:23.71, start: 66240.530111, bitrate: 4194 kb/s
    Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv, smpte170m, top first), 720x576 [SAR 64:45 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
    Side data:
    cpb: bitrate max/min/avg: 7000000/0/0 buffer size: 1835008 vbv_delay: N/A
    Stream #0:1[0x80]: Audio: ac3, 48000 Hz, stereo, fltp, 192 kb/s
    [FORMAT]
    filename=C:\temp\opera.mpg
    nb_streams=2
    nb_programs=0
    format_name=mpeg
    format_long_name=MPEG-PS (MPEG-2 Program Stream)
    start_time=66240.530111
    duration=8123.712000
    size=4259503237
    bit_rate=4194637
    probe_score=26
    [/FORMAT]
    FFprobe 正确地将 format_name 报告为 mpegformat_long_name 作为 MPEG-PS

    关于audio - 为什么我不能用 ffmpeg 重新排序我的 mpg 容器中的流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67051170/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com