audio - 如何使用 mkvmerge 和外部时间码强制 A/V 同步?

标签 audio video ffmpeg video-encoding mkv

背景

我正在开发一个项目,其中视频和音频是 MKV 源文件的算法解释,我使用 ffmpeg -ss 和 -t 将音频和视频的特定区域提取到单独的文件中。我在音频过程中使用视频中的场景变化(即视频场景变化时的音频变化),因此同步至关重要。

音频为 48khz,使用 512 个样本 block 。
视频是 23.976fps(我也试过 24)。

我根据累积 block 将sceneChanges的帧开始存储在一个文件中:

blocksPerFrame = (48000 / 512) / 23.976
sceneOnsetBlock = sceneOnsetFrame*blocksPerFrame

我在我的音频代码中使用这些 block 将与每个场景关联的样本视为一个组。

当我将音频和视频重新组合在一起时(目前使用 ffmpeg 在 MKV 容器中生成 mp4(v) mp3(a)),音频和视频开始同步但越来越漂移,直到它最终关闭约 35 秒。最糟糕的是音频滞后是非线性的!非线性,我的意思是,如果我将滞后与滞后的位置绘制出来,我没有得到一条线,但是你在下图中看到的)。由于这种非线性,我不能仅仅移动或缩放音频以适应视频。我无法弄清楚这种非线性增加的音频延迟的原因;我已经两次和三次检查了我的数学。

Cumulative lag against time

由于我知道场景更改的确切时间,我应该能够为 mkvmerge 生成“外部时间码”(来自上面的 block )以完美同步输出!

子问题:
  • 这是最好的方法(除了试图找出问题所在)吗?当我使用我的视频帧作为
    引用,如果我使用场景变化作为音频的时间码,
    它会强制视频匹配音频,反之亦然?与同步相比,我不太关心持续时间。制作视频要费力得多,所以我宁愿放一些声音也不愿放一些帧。
  • 我不清楚在时间码文件中使用哪些数字。
    根据 mkvmerge documentation “对于视频来说,这正是
    一帧,对于音频,这是一个特定音频类型的数据包。”
    由于我使用的是 MP3,所以数据包大小是多少? 理想情况下,我可以指定与我的 block 大小 (512) 匹配的数据包大小(在音频编码器中?),以保持一致和简单。我可以用 ffmpeg 做到这一点吗?

  • 谢谢!

    最佳答案

    我最终在我的代码中解决了问题的原因,所以我不需要按照我上面的想法去做。在与 mkvmerge 的作者讨论时,我确实确定了以下答案:

  • 最好将视频同步到音频,因为一些播放器使用音频时间戳(时间码)作为引用,并且视频比音频更容易被播放器减速和加速。
  • 音频没有单一的数据包大小。数据包大小取决于编码器,甚至可能在流的不同部分具有不同的大小。必须从 MKV header 中提取每个数据包中的样本数,并使用它来计算每个数据包的持续时间以生成时间戳。
  • 关于audio - 如何使用 mkvmerge 和外部时间码强制 A/V 同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43359375/

    相关文章:

    java - 使用 Java ME 的诺基亚不支持 FocusControl?

    c# - ffmpeg.win10 nuget 包文档

    python - Python:将传感器数据转换为连续的调频音频

    IOS 如何异步下载和缓存图像和视频以在我的应用程序中使用

    iphone - iOS LPCM Non-interleaved Audio input with 2 channels : not possible?

    swift - 在 iOS 11 上滑动时 AVPlayerViewController 黑屏

    browser - ffmpeg 导致浏览器挂断?

    android - FFmpeg 相机编码 h264 mp4 muxing atom avcC 太小

    iphone - iPhone AVAudioPlayer循环卡死了吗?

    ios - 如何在AVPlayer或任何其他受支持的 Controller 中播放.mpeg和.x-wav格式的音频文件