V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lxk11153
V2EX  ›  FFmpeg

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

  •  
  •   lxk11153 · 2020-03-04 20:55:31 +08:00 · 3692 次点击
    这是一个创建于 1712 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 例子: http://youku.com-t-youku.com/20190209/3349_fcce50be/1000k/hls/index.m3u8

    • ffmpeg -i index.m3u8 -c copy -c:v h264 out.ts

      ①不一定要-c:v h264,也可以-b:v 900k,反正就是别-c:v copy。大概在 160.ts 左右就开始出现 dup=0 drop= 丢弃帧(这样在ffmpeg -re推流时有一段时间看起来就是没数据的),为什么会这样,如何解决?

    • FFmpeg 与下载的区别

      • ffmpeg -i index.m3u8 -c copy m3u8-ffmpeg.ts

      • aria2c -i index.m3u8 --download-result=hide 然后cat合并

        需补全 index.m3u8 内文件的地址

      • aria2c 是原样下载(因为它就是个下载工具),ffmpeg -c copy和原件还是有区别

        • ② 区别在哪,ffmpeg 调整了哪些?
        • ③ ffmpeg 可以加参数来原样下载吗?
    第 1 条附言  ·  2020-03-04 23:18:48 +08:00
    • fix: "ffmpeg -c copy和原件还是有区别"
      • 把aria2c下载然后cat成的ts文件叫m3u8-aria2c.ts好了,它和m3u8-ffmpeg.ts看起来有点小区别
        • ② 区别在哪,ffmpeg 调整了哪些?
        • ③ ffmpeg 可以加参数来避免调整吗?(就是贴近m3u8-aria2c.ts)
    第 2 条附言  ·  2020-03-04 23:35:09 +08:00

    fix: "ffmpeg -i index.m3u8 -c copy -c:v h264 out.ts"

    • ffmpeg -i index.m3u8 -c copy -c:v h264 out.ts
      • 大概在 160.ts 左右就开始出现 dup=0 drop= 丢弃帧,然后在 drop 情况下-re 推流,别人在看流的话就会出现信号中断(/黑画面 maybe),为什么会drop,如何解决信号中断问题?
    9 条回复    2020-03-05 12:28:15 +08:00
    Satelli
        1
    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
        2
    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
        3
    lxk11153  
    OP
       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
        4
    lxk11153  
    OP
       2020-03-04 23:40:09 +08:00
    fix #3 "1. 不能混用我知道 ……"
    1. 混用问题不好意思,思考短路导致文案出错了 2. 重推流,如果想原画推就-c copy,如果想调码率可以加呀 3. see 第 2 条附言
    mxalbert1996
        5
    mxalbert1996  
       2020-03-04 23:49:03 +08:00 via Android
    这是原视频的问题,你可以试一下播放原视频的 11 分 3 秒左右。
    另外 H264 是编码格式,libx264 ( x264 )是编码器,一个编码格式可能有很多种编码器,x264 是 H264 的编码器之一,ffmpeg 的 -c:v 和 -c:a 后面接的是编码器,比如同为 H264 的编码器你还可以选择 OpenH264。
    lxk11153
        6
    lxk11153  
    OP
       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
        7
    fgodt  
       2020-03-04 23:58:10 +08:00
    我看了下-c copy 存下来的视频没有问题啊,也没出现过 drop 现象 ffmpeg 是 4.2.2
    lxk11153
        8
    lxk11153  
    OP
       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
        9
    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 解码就会出错。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2927 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:11 · PVG 21:11 · LAX 05:11 · JFK 08:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.