Kazumi icon indicating copy to clipboard operation
Kazumi copied to clipboard

本PR的目的是为了尝试解决看番时遭遇的广告问题

Open 0Chencc opened this issue 1 month ago • 10 comments

请查看本PR,本次改动在anime7这个源上测试。

今天在这个源上看番的时候发现经常会弹一个赌博广告然后无限月读,回到0:00从头播放10s广告,同时会有偶发性的解码错误(伴随播放这个广告时产生),不过具体的问题我没有去研究,可能是因为广告是1080p,动漫源是720p导致的(所以我在处理这个问题上,做出推断当出现 co located POCs unavailable时则认定是试图播放广告),跳过10s。 我后续播放《紫罗兰永恒花园》这个片源为1080p的进行测试时,发现并没有触发这个告警但是仍然有广告,所以我引入了其余的一系列机制。

本次改动可以完美解决10s广告的问题,我不太清楚其他源的广告是否都是10s,所以我希望能通过本pr来延申一些讨论。

我认为当本方案可行的情况下,我会在设置面板中加入自定义跳过秒数来允许用户在面对未来不同长度的广告时自动跳过。因为据我的观察,单一一个流使用的广告时长是统一的。

最后我想要补充的是:即便这个方案不是治本的方案,也是当下可以使用的治本的方案,因为经常遇到广告然后跳转到开头,接着播放接着遇到广告这样的无限月读太痛苦了。

后续我会持续关注这个问题并且思考更优秀的解决方案。

0Chencc avatar Nov 24 '25 00:11 0Chencc

这不是可行的方法

  1. 特征性不强,特定的 ffmpeg 错误实际上不是必然发生的,ffmpeg 的解复用器可以完美处理这种基于 #EXT-X-DISCONTINUITY 特性的片段插入。

  2. 跳过广告直接使用 media-kit 暴露的上层封装进行跳转,这并不是无感知的,实际上我们会遇到广告加载,然后播放器自动跳转固定的10秒,在多次跳过并可能导致循环后,再加载主视频流的糟糕的观看体验。

  3. 实际上在生效的部分是在检测到跳转到视频开头的尝试之后就判定为广告播放

由于以上提到的问题,我们不能使用这种方法,这不仅不能算是解决方案,甚至不算一个好的 workaround

我们要解决这个问题还是要通过对 ffmpeg hls demux 的改造,让 hls demuxer (解复用器) 在缓存时就直接跳过时间戳异常的片段。但是 ffmepg 的 hls demux 部分是超过3000行的纯 C 代码,且涉及复杂算法,读起来非常晦涩难懂。

Predidit avatar Nov 24 '25 02:11 Predidit

ffmpeg PTS 应该也是不错的切入点,也和你检测的报错有联系,但是 ffmpeg 的代码实在是太难读了 :D

Predidit avatar Nov 24 '25 02:11 Predidit

我思考了一下,如果从ffmpeg入手,似乎得自己来维护一个ffmpeg的fork? 你希望我们最终跳过广告的方式是无感跳过而非现在这样的检测到卡顿后直接跳过10s吗

0Chencc avatar Nov 24 '25 11:11 0Chencc

从 ffmpeg 入手理论上可以无感跳过并且性能优秀

我们不需要维护 ffmpeg fork ,但是需要维护一个 ffmpeg 树外补丁,插入我们的 libmpv 构建流程中,就像我们的 mpv 原生 directX 渲染接口补丁一样

https://github.com/Predidit/libmpv-win32-video-cmake/blob/master/packages/mpv-0001-dxd11-render-api.patch

Predidit avatar Nov 24 '25 11:11 Predidit

@0Chencc

我在我的 Github 时间轴上看到了你正在制作的 ffmpeg 补丁,看上去非常不错,不过有一些需要注意的地方

  1. 正常 seek 一样会导致 PTS 不连续,需要额外检查 PTS 位置是否在视频最开头,但这又可能破坏我们直接向视频开头进行的跳转

  2. #EXT-X-DISCONTINUITY 标志对于精准移除不起作用,这个标志在我们的用例里很重要,大部分广告插入直接将其作用域拓展到整个清单文件,以表示任何片段都可能不连续,以规避相关广告片段被精准移除,我们现在的补丁会将整个清单移除

  3. 关于编译,需要现在 Github Actions 中完成 LLVM 工具链编译,才能进行 MPV 编译,不要删除 Github Actions 中和 LLVM 相关的缓存,否则需要重新编译

  4. 关于调试,Actions 编译出的不带 dev 标记的压缩包是相对完整的 MPV 播放器,打开它们,会出现一个 MPV 播放器的全黑窗体,因为UI都被裁剪掉了,直接在这个窗体里用 Ctrl+V 剪贴视频直链即可开始播放,快进和跳转使用快捷键操作

我们可以考虑只在 M3U8 文件内包含 #EXT-X-DISCONTINUITY 时启用基于PTS的过滤,这样应该效果不错并且可以减少误伤

Predidit avatar Nov 26 '25 07:11 Predidit

@0Chencc

我在我的 Github 时间轴上看到了你正在制作的 ffmpeg 补丁,看上去非常不错,不过有一些需要注意的地方

  1. 正常 seek 一样会导致 PTS 不连续,需要额外检查 PTS 位置是否在视频最开头,但这又可能破坏我们直接向视频开头进行的跳转
  2. #EXT-X-DISCONTINUITY 标志对于精准移除不起作用,这个标志在我们的用例里很重要,大部分广告插入直接将其作用域拓展到整个清单文件,以表示任何片段都可能不连续,以规避相关广告片段被精准移除,我们现在的补丁会将整个清单移除
  3. 关于编译,需要现在 Github Actions 中完成 LLVM 工具链编译,才能进行 MPV 编译,不要删除 Github Actions 中和 LLVM 相关的缓存,否则需要重新编译
  4. 关于调试,Actions 编译出的不带 dev 标记的压缩包是相对完整的 MPV 播放器,打开它们,会出现一个 MPV 播放器的全黑窗体,因为UI都被裁剪掉了,直接在这个窗体里用 Ctrl+V 剪贴视频直链即可开始播放,快进和跳转使用快捷键操作

我们可以考虑只在 M3U8 文件内包含 #EXT-X-DISCONTINUITY 时启用基于PTS的过滤,这样应该效果不错并且可以减少误伤

好的,我确实在尝试编写一个patch来解决问题,感谢你的提醒,我会尽快尝试这个方案的可行性

0Chencc avatar Nov 26 '25 10:11 0Chencc

@0Chencc

我查看了一下你的分支上现在的改动

  1. 每次编译之后在 cache 清除掉 mpv 缓存,但不要清除 llvm 缓存,你可以从这些缓存建立的时间来粗略判断哪些来自工具链编译,不然之前编译失败的部分产物可能留在编译环境中,例如已经应用的补丁,导致补丁和当前目录冲突,出现编译失败。

  2. 使用AI辅助尽量先在完整的 ffmpeg 代码库中操作,然后手动 git diff 出来,现在的 AI 还没进化到能直接修 patch 的地步。

我仓库的工具链也在编译,明天我也会做一些尝试,有些规则的广告太多了

Predidit avatar Nov 26 '25 13:11 Predidit

@0Chencc

我查看了一下你的分支上现在的改动

  1. 每次编译之后在 cache 清除掉 mpv 缓存,但不要清除 llvm 缓存,你可以从这些缓存建立的时间来粗略判断哪些来自工具链编译,不然之前编译失败的部分产物可能留在编译环境中,例如已经应用的补丁,导致补丁和当前目录冲突,出现编译失败。
  2. 使用AI辅助尽量先在完整的 ffmpeg 代码库中操作,然后手动 git diff 出来,现在的 AI 还没进化到能直接修 patch 的地步。

我仓库的工具链也在编译,明天我也会做一些尝试,有些规则的广告太多了

我明白,实际上我昨晚就是本地在完整的ffmpeg进行了测试,接着git diff得到了这份,本来打算在本地编译来测试patch的可行性的。

0Chencc avatar Nov 26 '25 15:11 0Chencc

@0Chencc

我在我的 Github 时间轴上看到了你正在制作的 ffmpeg 补丁,看上去非常不错,不过有一些需要注意的地方

  1. 正常 seek 一样会导致 PTS 不连续,需要额外检查 PTS 位置是否在视频最开头,但这又可能破坏我们直接向视频开头进行的跳转
  2. #EXT-X-DISCONTINUITY 标志对于精准移除不起作用,这个标志在我们的用例里很重要,大部分广告插入直接将其作用域拓展到整个清单文件,以表示任何片段都可能不连续,以规避相关广告片段被精准移除,我们现在的补丁会将整个清单移除
  3. 关于编译,需要现在 Github Actions 中完成 LLVM 工具链编译,才能进行 MPV 编译,不要删除 Github Actions 中和 LLVM 相关的缓存,否则需要重新编译
  4. 关于调试,Actions 编译出的不带 dev 标记的压缩包是相对完整的 MPV 播放器,打开它们,会出现一个 MPV 播放器的全黑窗体,因为UI都被裁剪掉了,直接在这个窗体里用 Ctrl+V 剪贴视频直链即可开始播放,快进和跳转使用快捷键操作

我们可以考虑只在 M3U8 文件内包含 #EXT-X-DISCONTINUITY 时启用基于PTS的过滤,这样应该效果不错并且可以减少误伤

目前我已经识别出了画面并且跳过,但是这时候存在着一个问题是音频的跳过问题,我在思考应该怎么解决..

0Chencc avatar Nov 26 '25 23:11 0Chencc

@0Chencc

我对 ffmpeg 的内部细节不熟悉,你可以考虑问问AI,但我觉得可能是 PTS 需要更精细的校准,每个流(无论是视频还是音频)有自己的PTS。

mpv 上层虽然有一个可以调整脱同步时播放器行为的属性 video-sync ,但是在我们的用例下应该不会正确生效。我们还是要在这个补丁的范围内修复错误。

此外即使编译成功了,也需要移除 LLVM 之外的缓存,否则CI执行过程中 ffmpeg 不会重新编译。

Predidit avatar Nov 27 '25 02:11 Predidit

https://github.com/Predidit/libmpv-win32-video-cmake/pull/4

hi,我已经修复了广告问题,现在的实现算是比较流畅,我建议你可以尝试使用我的方案在本地进行测试,我在本地编译了mpv之后测试没有任何问题。

0Chencc avatar Dec 02 '25 16:12 0Chencc

抱歉,由于 libmpv-win32 那个仓库是一个 fork 仓库,我并没有收到 PR 的邮件提醒,我会在明天尽快尝试你的实现。

Predidit avatar Dec 02 '25 17:12 Predidit

我之前做过m3u8解析 广告插入的m3u8文件里的ts片段样式和普通视频ts不一样 所以我当时是用这个方法去广告的。

keyboard2005 avatar Dec 03 '25 16:12 keyboard2005

我之前做过m3u8解析 广告插入的m3u8文件里的ts片段样式和普通视频ts不一样 所以我当时是用这个方法去广告的。

它这个样式上有一点不一样的,我自己解析过几个,最明显的是1080p跟720p,但是在京阿尼的动画里这个特征就无法识别了,因为《永恒紫罗兰花园》也是1080p。

不过您有相关的实现吗?我可以阅读一下看看怎么做的特征识别。

0Chencc avatar Dec 03 '25 17:12 0Chencc

我之前做过m3u8解析 广告插入的m3u8文件里的ts片段样式和普通视频ts不一样 所以我当时是用这个方法去广告的。

它这个样式上有一点不一样的,我自己解析过几个,最明显的是1080p跟720p,但是在京阿尼的动画里这个特征就无法识别了,因为《永恒紫罗兰花园》也是1080p。

不过您有相关的实现吗?我可以阅读一下看看怎么做的特征识别。

很久以前了 代码没了,然后我把有广告的源删了,所以能不能给我一个测试用的数据 就是告诉我 哪个源(以及它对应的网站) 的哪个番第几集里的多少秒出现广告? 我想去看看能不能找到解决方法,

还是说问题已经解决了?, (我当时的情况是广告片段的ts文件路径和普通视频的完全不一样, 我直接做了行操作删除处理, 可能我遇到的广告插入比较简单所以才能这样处理?

keyboard2005 avatar Dec 04 '25 07:12 keyboard2005

https://www.dm569.com/这个网站,后面的东西是我改过,不一定能用,你可试试以下 kazumi://eyJhcGkiOiIxIiwidHlwZSI6IjEiLCJuYW1lIjoic2F1a3VyYSIsImdyb3VwIjoiIiwidmVyc2lvbiI6IjEuMC4wIiwibXVsaVNvdXJjZXMiOnRydWUsInVzZVdlYnZpZXciOnRydWUsInVzZU5hdGl2ZVBsYXllciI6dHJ1ZSwidXNlUG9zdCI6ZmFsc2UsInVzZUxlZ2FjeVBhcnNlciI6ZmFsc2UsInVzZXJBZ2VudCI6IiIsImJhc2VVUkwiOiJodHRwczovL3d3dy5kbTU2OS5jb20vIiwic2VhcmNoVVJMIjoiaHR0cHM6Ly93d3cuZG01NjkuY29tL3NlYXJjaC9Aa2V5d29yZC0tLS0tLS0tLS1AcGFnZW51bS0tLS5odG1sIiwic2VhcmNoTGlzdCI6Ii8vKltAaWQ9XCJzZWFyY2hMaXN0XCJdL2xpIiwic2VhcmNoTmFtZSI6Ii8vZGl2WzJdL2g0L2EiLCJzZWFyY2hJbWciOiIvL2RpdlsxXS9hL0BkYXRhLW9yaWdpbmFsIiwic2VhcmNoUmVzdWx0IjoiLy9kaXZbMl0vaDQvYSIsImNoYXB0ZXJSb2FkcyI6Ii8vZGl2WzJdL2RpdlszXS9kaXZbMV0vZGl2WzFdL2Rpdi9kaXZbMl0vZGl2IiwiY2hhcHRlckl0ZW1zIjoiLy91bC9saSIsImNoYXB0ZXJSZXN1bHQiOiIvL2EiLCJjaGFwdGVyUmVzdWx0TmFtZSI6Ii8vYSIsImNoYXB0ZXJSZXZlcnNlIjpmYWxzZSwicmVmZXJlciI6IiIsInRhZ3MiOnsi55uu5YmNIjp7InVybCI6ImVsZW1lbnQiLCJ4cGF0aCI6Ii8vZGl2WzFdL2Evc3BhblsyXS90ZXh0KCkiLCJ2YWx1ZSI6IuabtOaWsOiHszI16ZuGIiwic2hvdyI6dHJ1ZX0sIuagh+etviI6eyJ1cmwiOiJlbGVtZW50IiwieHBhdGgiOiIvL2RpdlsyXS9wWzNdIiwidmFsdWUiOiLliIbnsbvvvJrlm73kuqfliqjmvKvlnLDljLrvvJrlpKfpmYblubTku73vvJoyMDI1Iiwic2hvdyI6dHJ1ZX19fQ==

1312853182 avatar Dec 04 '25 09:12 1312853182

我之前做过m3u8解析 广告插入的m3u8文件里的ts片段样式和普通视频ts不一样 所以我当时是用这个方法去广告的。

它这个样式上有一点不一样的,我自己解析过几个,最明显的是1080p跟720p,但是在京阿尼的动画里这个特征就无法识别了,因为《永恒紫罗兰花园》也是1080p。 不过您有相关的实现吗?我可以阅读一下看看怎么做的特征识别。

很久以前了 代码没了,然后我把有广告的源删了,所以能不能给我一个测试用的数据 就是告诉我 哪个源(以及它对应的网站) 的哪个番第几集里的多少秒出现广告? 我想去看看能不能找到解决方法,

还是说问题已经解决了?, (我当时的情况是广告片段的ts文件路径和普通视频的完全不一样, 我直接做了行操作删除处理, 可能我遇到的广告插入比较简单所以才能这样处理?

https://vip.dytt-hot.com/20250119/9462_9cafd121/index.m3u8

可以尝试这个流,这个流会在4分56秒(左右)准时插入一段18s的广告,我现在测试的基础都是在这个流,目前我已经完善了一切,但是似乎由于我们的libmpv-win32-video-cmake一些配置问题导致我无法正常编译,我目前正在调试看看如何才能正常在workflow编译出mpv。

我自己通过拉取mpv编译是可以正常工作的,在我的仓库下https://github.com/0Chencc/libmpv-win32-video-cmake/tree/skip-ad的052897e0c735f53c96cb1e259317a69e40309355提交是可以正常在mpv编译应用的,如果你需要的话,可以尝试直接使用我的patch来进一步调试。

0Chencc avatar Dec 04 '25 09:12 0Chencc

@Predidit hi,最近忙完了,总算有时间来继续我们的实现,目前我已经成功在我的项目下编译了带着跳过广告的patch的mpv。 https://github.com/0Chencc/libmpv-win32-video-cmake/actions/runs/20023983232

你有兴趣来测试一下吗?

.\mpv.com --start=4:53 --demuxer-lavf-o=hls_ad_filter=1 "https://vip.dytt-hot.com/20250119/9462_9cafd121/index.m3u8"

使用本命令在4:53开始播放,4:56是原本的广告,现在可以跳过,不过在中间由于丢包会有一个卡顿,卡顿过后我使用了一次seek做了同步校准,目前已经不会再有音画不同步的问题。

0Chencc avatar Dec 08 '25 10:12 0Chencc

@0Chencc

很高兴看到我们终于编译出了可用的 mpv 二进制文件,我将立即着手开始测试

我注意到你只编译了完整的 mpv 可执行程序,而没有编译 .dll ,我像知道这是有意为之,方便测试,还是错误运行了 actions

如果要编译 .dll ,在运行 actions 时不要勾选 Build latest mpv tarball 复选项

此外我注意到补丁中已经有简单的重同步逻辑,你提到的 卡顿过后我使用了一次seek做了同步校准 指的是这里的同步,还是我们需要在 dart 侧手动同步

Predidit avatar Dec 08 '25 11:12 Predidit

@0Chencc

很高兴看到我们终于编译出了可用的 mpv 二进制文件,我将立即着手开始测试

我注意到你只编译了完整的 mpv 可执行程序,而没有编译 .dll ,我像知道这是有意为之,方便测试,还是错误运行了 actions

如果要编译 .dll ,在运行 actions 时不要勾选 Build latest mpv tarball 复选项

此外我注意到补丁中已经有简单的重同步逻辑,你提到的 卡顿过后我使用了一次seek做了同步校准 指的是这里的同步,还是我们需要在 dart 侧手动同步

@Predidit 不需要在dart侧做同步了,我的patch已经完成了一切,编译dll似乎是因为我的workflow没有正确上传dev文件,我补充了并且重新优化了patch,我目前在本机测试已经可以无感跳过广告了。可以稍微等待30分钟应用最新的patch来测试。

0Chencc avatar Dec 08 '25 11:12 0Chencc

@0Chencc

我注意到你在试图利用简单的方式上传包含 .dll 的名称中带有 dev 字样的打包

这样是不能成功的,因为相关文件并不存在, Build latest mpv tarball 复选项控制了 CI 运行 mpv.cmake 还是 mpv-release.cmake

而 .dll 的打包逻辑只存在于 mpv.cmake 中

Predidit avatar Dec 08 '25 11:12 Predidit

我建议你勾选和不勾选 Build latest mpv tarball 各运行一次 CI

这样我们可以得到一份完整版本和一份能立即在 kazumi 中测试的 dll

Predidit avatar Dec 08 '25 11:12 Predidit

@Predidit https://github.com/0Chencc/libmpv-win32-video-cmake/actions/runs/20028935001 我编译出了dll与mpv,并且调优了代码,目前的问题是会遇到广告时稍微卡顿2-3s,因为会下载广告的包再丢弃,至于提前检测后丢弃的办法我尝试了会导致后续的片段产生一些花屏问题,仔细思考了一下这样的实现可能更现实一些。

当前的实现下,在2-3s卡顿之后,会无比畅通,没有任何问题。

0Chencc avatar Dec 08 '25 13:12 0Chencc

看上去相当不错,我会在明天给出反馈

Predidit avatar Dec 08 '25 14:12 Predidit

@0Chencc

这个复杂的实现完美的让我惊讶,令人头痛的误判问题也用 ffmepg 的内部方法成功解决了。

实际使用效果也非常好,虽然只测试了 vip.dytt-hot.com 域名下的资源,但是泛用性应该相当不错,我在找一些其他的流进行测试

在此期间,你可以准备一下全平台其他编译仓库的PR吗,如果有补丁兼容问题,可以直接将 ffmpeg 定位到我们现在的版本。

Predidit avatar Dec 09 '25 13:12 Predidit

我会先在各个仓库处理阻碍当前编译的问题,以避免你提交PR时遇到麻烦

Predidit avatar Dec 09 '25 13:12 Predidit

@Predidit 没有问题,这段时间我会着手准备。

0Chencc avatar Dec 09 '25 15:12 0Chencc

@0Chencc

hi ,目前四个 libmpv 构建仓库的主分支均可正确构建,可以提交 PR ,我会一并合并所有的 PR 以进行发布

https://github.com/Predidit/libmpv-darwin-build https://github.com/Predidit/libmpv-linux-build https://github.com/Predidit/libmpv-win32-video-cmake https://github.com/Predidit/libmpv-android-video-build

可能需要检查一下应用补丁的步骤,有些仓库明确指定了应用补丁的文件名,而有些使用通配符

Predidit avatar Dec 10 '25 05:12 Predidit

我找到了另一个测试流,广告插入方式略有不同,但一样完美跳过

https://v.cdnlz22.com/20251109/25595_593f7b09/index.m3u8

广告位于约 4:58 处

Predidit avatar Dec 10 '25 06:12 Predidit

能验证我的实现就很好,我现在正在着手推送另外三个仓库的pr

0Chencc avatar Dec 10 '25 06:12 0Chencc