关于 FFmpeg 合并 HLS/m3u8 流 TS 切片时出现 Non-monotonous DTS in output stream 的问题

作者:一年又一年 分类: 技术 发布于:2019-6-7 12:27 ė62次浏览 60条评论

这个问题是由 FFmepg 的缺陷导致的,至今(2019年)仍未解决。

引发问题的根源在于 HLS/m3u8 流文件列表中,存在两个相邻切片之间的 TS 包计数不连续。(TS 包计数不连续的情况,可在 直播过程中存在推流中断后重推 的 直播流/回放流列表 中出现)

对于这种情况,HLS/m3u8 流文件列表会在与前者计数不连续的文件前加上 EXT-X-DISCONTINUITY 标签来显式地告诉播放器留意。

但遗憾的是,FFmpeg 的 HLS 处理模块不支持该标签,进而导致遇到计数不连续的 TS 时,无意识地强制合并两个计数不连续的 TS,导致 Non-monotonous DTS in output stream 警告,再加上其他一些缺陷,最终导致合并后时间码不正确。


说明

本文结论由我本人在参阅了大量相关问题汇报、社区提问后得出;部分参阅的文章链接见文末。

其中,最有价值的是


ticket #5419 有不少技术细节和相关讨论;user2286522 给出了他对这个问题的直白描述,本人在参阅了大量资料后,支持他的表述,给出了前文的结论。

此外,user2286522 还提出了这个问题的一种可能可行的解决方法,见本文后部分的解决方案章节。


关于这个缺陷的历史讨论与修复进展

FFmpeg 的 bugtrack 中,与 EXT-X-DISCONTINUITY 标签支持相关的缺陷反馈,已经累计不少了。

参阅:https://trac.ffmpeg.org/search?q=EXT-X-DISCONTINUITY


这个问题存在的时间已经不短了(至少从 2016 年开始),也曾有不止一人提供过修复此问题的 patch,但由于开源界种种喜闻乐见的原因没有合并,至今也仍未修复。

参阅 #5419 这个 ticket:https://trac.ffmpeg.org/ticket/5419

最近一次提供 patch 的开发者(Joe Koberg)于 2018 年 5 月 在  ffmpeg-devel 邮件列表询问了能否合并其代码:

参阅:http://ffmpeg.org/pipermail/ffmpeg-devel/2018-March/226706.html (可读性更高的版本:https://ffmpeg-devel.ffmpeg.narkive.com/tNjaNRWP/fix-hls-discontinuity-non-monotonous-dts


时至今日, #5419 这个 ticket 下面还是不是有人催问这个 bug 目前进展如何,到底还修不修复。

哎,庭有枇杷树,如今已亭亭如盖矣。


解决方案

如前文所说,这个问题(https://stackoverflow.com/questions/49289394/downloading-ts-stream-with-ext-x-discontinuity-sequence-ffmpeg)中名为 user2286522 的用户给出了一个可能可行的解决方法:

  • 手动将 m3u8 依 #EXT-X-DISCONTINUITY 标签切分,构造成多个独立的 m3u8 列表,然后丢给 FFmpeg。
    manually split the m3u8 in several pieces. where you see the #EXT-X-DISCONTINUITY tags. then (after making these pieces valid m3u8 singleton) feed them all to ffmpeg.
  • 这样每段各自合并成一个视频,之后再用 FFmpeg 的 concat 命令(https://trac.ffmpeg.org/wiki/Concatenate)把多个段的视频合并到一起,这样做就不会有问题(就是这么神奇)。
    that will give you several video pieces, but you can (as strangely as it may sound) merge them all together using ffmpeg without problem using the concat command (https://trac.ffmpeg.org/wiki/Concatenate).


另一位名为 user9546659 的用户在另一个问题(https://stackoverflow.com/questions/38241521/converting-hls-with-discontinuity-tag-into-mp4-using-ffmpeg)下提供了另外一种可能可行的解决方法,大致的思路是:

  • 弃用 HLS,换用 concat(m3u8 -> ffconcat),把多个分段 ts 合并成一个整体 ts。(实测 concat 过程中会有警告和错误,但不会像 HLS 一样导致最终视频总时长异常)
  • 之后再转成其他格式(如 mp4)。


本文参阅的文章链接(部分)

本文中所有出现的外链

https://github.com/ytdl-org/youtube-dl/issues/10719

https://www.jianshu.com/p/e9b2331b6163

---

https://stackoverflow.com/questions/55914754/how-to-fix-non-monotonous-dts-in-output-stream-01-when-using-ffmpeg

https://superuser.com/questions/1150276/trim-video-and-concatenate-using-ffmpeg-getting-non-monotonous-dts-in-output

0 FFmpeg 解决方案 HLS m3u8 合并 ts

♥ 若您欲转载敝站的原创内容,还请您附注出处及相应链接

发表评论

电子邮件地址不会被公开。必填项已用*标注

Ɣ回顶部