如何为 mp4 容器的视频流指定偏移量和查找位置?

How to specify an offset and a seek position for a video stream of a mp4 container?

似乎我可以拥有其中之一(-ss-itsoffset),但不能同时拥有两者,否则它们会相互抵消。

我使用以下命令创建 output.mp4:

ffmpeg -i input.mp3 -itsoffset 4 -t 4 -ss 3 -i input.mp4 -c:v copy output.mp4

使用此命令,我希望音频立即开始播放,视频在 4 秒后开始播放,在视频的 3 秒处搜索。

但是,当我播放 input.mp4 时,视频只比音频晚一秒开始播放(而不是 4 秒)。我想它做了 "offset - seek = 1" 类型的事情。

如何防止寻道影响偏移量?

干杯!

正如 Gyan 所建议的,我通过将视频流与搜索位置和持续时间分开编码来实现它:

ffmpeg -t 4 -ss 3 -i input.mp4 -c:v libx264 output.mp4

然后在最终的 .mp4 中将其与偏移量混合:

ffmpeg -i input.mp3 -itsoffset 4 -i input.mp4 -c:v copy output.mp4

"I expect the audio to start playing right away, and the video to start playing 4 seconds later,
(seeked at 3 seconds into the video).

How can it be done without re-encoding?"

尝试使用 as:

ffmpeg -ss 00:00:03 -itsoffset 4 -i video.mp4 -ss 00:00:00 -i audio.mp3 -c:v copy output.mp4

命令的含义(它们的 entry/order 也很重要)...

-ss 00:00:03 = 寻找 3 秒的输入 video.mp4 设置为输出的起点 video track.

-itsoffset 4 = 在输入作为输出播放之前设置延迟。提供静止帧 4 秒。

-i video.mp4 = 设置 video 输入。

-ss 00:00:00 = 寻找 0 秒的输入 audio.mp4 作为输出的起点 audio track.

-i audio.mp3 = 在此时设置 音频 输入...(请参阅下面的音频 side-note) .

-c:v copy =(避免视频轨道的re-encode。

output.mp4 = 设置输出 a/v 容器.

旁注:

关于视频: MPEG 视频只能寻找关键帧(也称为i-frames)。如果您在设置 -ss 3 的同时还使用 -c:v copy,并且在 -ss.

时没有找到关键帧,事情可能不会按预期工作

可能缺少 3 秒的关键帧可能解释了您的:

"When I play input.mp4, the video starts only one second later than the audio
(as opposed to 4 seconds)"

这甚至在文档中警告(参见:FFmpeg wiki page - Seeking)。

Seeking while doing a codec copy

Using -ss as input option together with -c:v copy might not be accurate since ffmpeg is forced to only use/split on i-frames. Though it will —if possible adjust the start time of the stream to a negative value to compensate for that.

Basically, if you specify "second 157" and there is no key frame until second 159, it will include two seconds of audio (with no video) at the start, then will start from the first key frame.

So be careful when splitting and doing codec copy
.

唯一的解决方案是保留 test/adjusting 视频 -ss 值以找到 next-best 折衷方案。

  • 考虑使用 HOURS:MM:SS.MILLISECONDS 时间格式以获得最接近预期的 3 秒。 示例: -ss 00:00:02.895

关于音频: MP4 通常有一个 AAC 音轨。请注意,由于您的输入音频是 MP3 格式,因此 FFmpeg 会自动将其 re-encoded 转换为 AAC 格式。

  • 要避免音频格式re-encode:强制MP3用-c:a copy
    (可以在上面的-c:v copy之后添加)。