ffmpeg: drop 丢弃帧问题,与-c copy 下载问题

2020-03-04 20:55:31 +08:00
 lxk11153
3728 次点击
所在节点    FFmpeg
9 条回复
Satelli
2020-03-04 21:09:37 +08:00
接在 -i 后面的是针对输出的参数。
-c:v 是制定视频流的编码器,没有 h264 这个编码器,软件编码是默认 libx264。
-b 是制定流码率。-b:v 是指定视频码率,不能和 -c copy 混用。如果你需要重推流,-re 后接 -c copy 且不要指定码率。

ffmpeg -c copy 是与原件有区别,你只是单独拿出来里面的一条视频轨道和一条音频轨道再重新 mux 到你指定的容器格式里。原本容器的元数据、格式已经丢弃。

.m3u8 是播放列表,aria2 当然不能直接 -i 进来后只能看到文件名,没有原始路径。而且最后下载下来的也只是该资源在 HLS 分发下的片段。

ffmpeg 本质不是下载,只是把每一个片段按照 .m3u8 播放列表拼接在一起,最后再根据你指定的容器格式封装。

在这个情况下,原件就是这些片段。
Satelli
2020-03-04 21:19:09 +08:00
另,尝试了手动指定 -c:v h264 -b:v 900k,会 fallback 到 libx264。默认 -preset 是 medium。

在 Intel 45W 6 核心 6 线程的 CPU 能力下,该视频能有 5x 的编码速度。
lxk11153
2020-03-04 23:09:57 +08:00
@Satelli #1
- 其实我不太懂 h264 在具体上下文指什么,比如
-- 1. ffmpeg(/ffprobe): Stream #0:0: Video: h264 (High)
-- 2. Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
-- 3. ffmpeg -codecs
---- DEV.LS h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (encoders: libx264 libx264rgb h264_amf h264_videotoolbox )
- 1. 不能混用我知道 2. 重推流,如果想原画推就-c copy,如果想调码率可以加呀 3. 我说到"-c:v h264"和"-b:v 900k"只是想表达你可以使用"ffmpeg -i index.m3u8 -c copy -c:v h264 out.ts"/"ffmpeg -i index.m3u8 -c copy -b:v 900k out.ts"来测试我说的"大概在 160.ts 左右出现 drop",然后在 drop 情况下-re 推流,别人在看流的话就会出现信号中断(/黑画面 maybe),So 如何解决?★
- 拿 aria2 来说,把片段都下载下来然后 cat 合成一个 out.ts 文件,我其实已经不知道这个 out.ts 文件还存不存在"元数据"还是.ts 这种格式有无"元数据"?★
- 因为 m3u8 里是相对路径,所以补全成绝对路径就可以 aria2c -i 使用了,对应我说的"需补全 index.m3u8 内文件的地址"
lxk11153
2020-03-04 23:40:09 +08:00
fix #3 "1. 不能混用我知道 ……"
1. 混用问题不好意思,思考短路导致文案出错了 2. 重推流,如果想原画推就-c copy,如果想调码率可以加呀 3. see 第 2 条附言
mxalbert1996
2020-03-04 23:49:03 +08:00
这是原视频的问题,你可以试一下播放原视频的 11 分 3 秒左右。
另外 H264 是编码格式,libx264 ( x264 )是编码器,一个编码格式可能有很多种编码器,x264 是 H264 的编码器之一,ffmpeg 的 -c:v 和 -c:a 后面接的是编码器,比如同为 H264 的编码器你还可以选择 OpenH264。
lxk11153
2020-03-04 23:55:12 +08:00
new #4 "1. 不能混用我知道 ……"
1. 混用问题不好意思,思考短路导致文案出错了 2. (可能是前面混用引起的连锁,不纠结这里) 重推流,如果想原画推就 ffmpeg -re -i in -c copy out,如果想调码率可以指定码率呀 ffmpeg -re -i in -c copy -c:v h264 -b:v 900k out (后面的-c 会覆盖前面的,这里意思就是-c:v h264 其它 copy ) 3. see 第 2 条附言

ps: ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers
built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
fgodt
2020-03-04 23:58:10 +08:00
我看了下-c copy 存下来的视频没有问题啊,也没出现过 drop 现象 ffmpeg 是 4.2.2
lxk11153
2020-03-05 00:59:21 +08:00
@Satelli #2 因为我看官方文档上也有-c:v h264 的写法,感觉是自适应编码器(比如只有 OpenH264 的 ffmpeg 和只有 libx264 的编码器,两者的通用写法,我猜的);是只有个别的才有这种写法还是其它的也可以,比如 av1 对应 libaom-av1,vp9 对应 libvpx-vp9 ?
@mxalbert1996 #5 "播放原视频的 11 分 3 秒" 感谢,第一次接触 drop(都没想到原来是视频本身有问题),本地播放器看的话我这看到画面湖了几秒然后正常续播;但拿去推流,然后看流,会显示信号中断 /之后画面定格声音续播等状况然后可能会正常续播(可以手动刷新正常续播,不同浏览器看和手机 app 看可能出错表现不一样)。。。可能没啥好的解决方案吧,就这样吧。👆

@fgodt #7 不能都 copy 加个-c:v h264 就有 drop 了
Satelli
2020-03-05 12:28:15 +08:00
@lxk11153
.ts 也是一种容器格式。在你这个 case 下,原文件只是已经通过 HLS 分发出来的 .ts 片段。视频流总是指容器里的 H.264 数据。逻辑上你通过 cat 或 ffmpeg -f concat -c copy 拼接出来的整个文件不是原本的文件,但是视频流是没有变化的。音频同理。

h264 指 H.264 编码。H.264 有很多编码器,你可以通过 ffmpeg -encoders | grep h264 列出 ffmpeg 可用的编码器选项及注释。ffmpeg -codecs 列出的是编码,括号内接的就是该编码可用的编码器。

你的 log 里有一行 Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
这行是指原容器的该条视频流将会用原生 H.264 解码器解码,通过 libx264 软件编码,放入新的容器中。

官方就 H.264 的编码向导 https://trac.ffmpeg.org/wiki/Encode/H.264 ,里面用的 libx264 做例子。使用 h264、vp9、av1 应该只会匹配到首个可用编码器。如果是自适应,macOS 平台用 h264 应该会使用更节能、快速的 VideoToolbox,而不是软件实现的 libx264,虽然质量无法与后者相比。这里为猜测。

手动指定编码器会 drop 原因应该和楼上指出 11 分 3 秒的视频数据损坏有关。-c copy 不会涉及解码,ffmpeg 会原封不动把原视频流拿过来,放入新的容器中。手动指定之后 ffmpeg 会使用默认的(或你指定的)解码器解码每一帧,再通过默认的(或你指定的)编码器进行编码后,再放入新的容器中。原视频视频流有错误,ffmpeg 解码就会出错。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/649899

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX