我有一堆通过编程生成的webm
数据块。每个数据块的长度应该正好是 10 秒,目标是将N
它们连接起来以获得连续的webm
秒数N * 10
。问题是它们总是比这个时间长一点,并且错误会在播放过程中累积,从而导致与依赖于精确时间戳的其他数据出现差异。
每个块都是通过 获得的ffmpeg -i audio.wav -i video.webm -map 0 -map 1 -c:a:0 vorbis -c:v:0 copy chunk.webm
,最初audio.wav
和video.webm
都是在考虑 10 秒约束的情况下构建的:对于audio.wav
样本数的计算为sample_rate * TEN_SECONDS
,对于video.webm
帧数的计算为fps * TEN_SECONDS
。然后两者都写入磁盘并通过上述命令合并到 中chunk.webm
。不幸的是,ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 chunk.webm
显示每个块都是只是比预期稍长:10.003 秒。我天真地试图将它们缩短到所需长度ffmpeg -i chunk.webm -t 10 output.webm
,但令人惊讶的是,它让事情变得更糟:10.008 秒。
最后我想做ffmpeg concat -i list.txt -map 0 -codec copy all.webm
,其中的每一行都list.txt
包含file chunk_i.webm
,但我不确定处理累积错误的最佳方法是什么。有没有一种被广泛接受的方法?像“逐个连接,在添加每个块后修剪到正确的持续时间”这样的技巧是否可以正常工作而不会出现明显的问题?
谢谢!
答案1
您没有提到帧速率。如果您使用的是分数帧速率,例如 ntsc 24000/1001 或 30000/1001,则精确编码到 10.000 秒可能会更加困难。音频也是如此。默认的 48khz 采样率并不准确。
如果你以恒定的帧速率(如 30fps)进行编码,那么你可以对 10 秒的块尝试以下操作:
ffmpeg -i vid.webm -i aud.wav -c:v copy -c:a libvorbis -frames:v 300 -t:a 10.0 output.webm
在我的测试中,这个值很接近,但也不准确。对于累积误差,可以尝试类似的方法
假设列表中有 10 个文件,并且您想要 100 秒的输出。
ffmpeg -f concat -i 输入.txt -c 复制 -t 100 out100.webm
奇怪的是,如果我将时间调整为 99.98,效果会更好一些。
ffmpeg 可能无法达到这样的精度。