V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
xiaopenyou
V2EX  ›  问与答

怎样“无缝”拼接多个“帧率不同”的 mp4 文件?

  •  
  •   xiaopenyou · Jan 16, 2019 · 5807 views
    This topic created in 2659 days ago, the information mentioned may be changed or developed.

    一句话说

    多个帧率(fps)不同的 mp4 片段,怎样无缝、不重编码(without re-encode)地拼接(concat)回一个文件,且不改变时间长度?

    关键词:帧率不同、无缝拼接、不重编码、不改变时间长度

    如果 4 个定语无法同时满足,无缝拼接可以去掉


    详细说

    定期收到的视频,每个视频总被剪成 N 段片段,现想合并回 1 个文件。试了下面的方案,都不满意:

    1. fps 不同的文件,直接 ffmpeg concat demuxer 会各种问题,大佬肯定知道,不细说了

    2. 即使 fps 相同,用如下命令直接 concat demuxer,在合并的分界处,也会有卡屏停顿。相反用 Boilsoft Video Joiner 合并,就没有卡屏、真正无缝。所以不知道 ffmpeg 想无缝拼接,应该怎么写命令?
      (echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
      ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

    3. 试了如下命令,虽然不重编码,但会改变时间长度:
      ffmpeg -y -i seeing_noaudio.mp4 -c copy -f h264 seeing_noaudio.h264
      ffmpeg -y -r 29.97 -i seeing_noaudio.h264 -c copy seeing.mp4

    4. 试了如下命令,会重编码(有损转换,丢视频质量): ffmpeg -i input.mp4 -r 29.97 -y output.mp4

    所以这种需求,有办法实现么?

    1. 求助前提:只有剪辑后的片段。不聊能拿到未剪辑视频源的情况

    2. 大佬可能说,不改变时间长度就必须丢弃帧,那怎么可能不重编码?是这样吗?菜鸟不懂,说错求科普,谢谢😛

    20 replies    2019-01-17 08:34:03 +08:00
    d3vil
        1
    d3vil  
       Jan 16, 2019
    此帖仅限大佬盖楼,请楼下慎重。
    xiaopenyou
        2
    xiaopenyou  
    OP
       Jan 16, 2019
    @d3vil #1 热切期盼回帖呀,虚心求教,求大家帮帮忙😂😘
    xiaopenyou
        3
    xiaopenyou  
    OP
       Jan 16, 2019
    目前采用的,是先重编码把所有片段转成帧率一致,然后再调用 Boilsoft Video Joiner 合并,但唯一缺点就是会重编码、丢视频质量,所以发帖,请教下见多识广的 v 友们,有没更优良的方案……
    kokutou
        4
    kokutou  
       Jan 16, 2019 via Android
    搞个 m3u8 播放列表?
    xiaopenyou
        5
    xiaopenyou  
    OP
       Jan 16, 2019
    @kokutou #4 “合并”主要是为了二次分发,以及导入到专业工具中管理
    实在无奈没辙的话,这也是个方法啦,谢谢😘
    cest
        6
    cest  
       Jan 16, 2019
    你要的 vfr 只在规格上存在,还没看过那个工具真的做出来
    Elethom
        7
    Elethom  
       Jan 16, 2019 via iPhone   ❤️ 1
    不可能完全不重编码,能想到的成本最低的方式就是无脑型插帧或丢帧,比如说 24 转 30 就每隔 4 帧插一个不变的 P 帧进去,30 转 24 就每 5 帧丢掉一帧(遇到 I 帧 B 帧还是要涉及一点点编码)不过效果会比较奇怪就是了。
    xiaopenyou
        8
    xiaopenyou  
    OP
       Jan 16, 2019
    @cest #6 那作为“ vfr 当前实践尚做不到”的推论,是不是要拼接就必须先“帧率一致化”?
    那问题就转换成“能否不重编码地转换帧率”,请教大神这一点目前可以做到吗?
    俺对视频编码这块一窍不通,问的蠢的话见谅
    Elethom
        9
    Elethom  
       Jan 16, 2019 via iPhone
    @Elethom
    @Livid,移动端折行样式有点奇怪。
    xiaopenyou
        10
    xiaopenyou  
    OP
       Jan 16, 2019
    @Elethom #7 是的,上面第 4 条用的 ffmpeg -i input.mp4 -r 29.97 -y output.mp4 命令,就是无脑丢帧的方法
    咨询个蠢问题:是不是理论上,“无脑丢帧”就必然等于要“重编码”啊?如果是这样,就不折腾了……
    Elethom
        11
    Elethom  
       Jan 16, 2019 via iPhone
    @Elethom
    纠正 #7,P 帧也需要编码。
    Elethom
        12
    Elethom  
       Jan 16, 2019 via iPhone   ❤️ 1
    @xiaopenyou
    无脑丢帧的话,重编码也不是整个重编码,只是被操作的帧会重编码(比如说 I、P、P 三帧丢掉了中间的 P 帧会把两个 P 帧的变化量合并到一个 P 帧里),理论上不会影响视频的清晰度,只是会在时间上有一点时快时慢的感觉。我没看过 ffmpeg 的源码所以不能回答你它的 behaviour 具体是什么样的。
    zhs227
        13
    zhs227  
       Jan 16, 2019
    需要重新做转码成一致的帧率,要不然你放到各种软件中能正常处理的占少数
    xiaopenyou
        14
    xiaopenyou  
    OP
       Jan 16, 2019
    @Elethom #12 原来这样啊,看来目前最极限的方案,也只能要么 m3u8,要么重编码了
    知道不会丢太多清晰度,吃了颗定心丸,谢谢非常感激科普
    fgodt
        15
    fgodt  
       Jan 16, 2019 via Android
    你这种就只能动态插入 sps pps ,现在默认的 mp4 格式又是全局 sps pps 很多解码器都不支持所以无解,但理论上是可以支持的
    EridanusSora
        16
    EridanusSora  
       Jan 16, 2019 via Android
    理论上可以,实际上研究过找不到工具能做……感觉做出来能不能播也是问题
    annoy1309
        17
    annoy1309  
       Jan 16, 2019 via Android
    @Elethom p 不一定需要编码,有“可能”不需要编码
    worldGM
        18
    worldGM  
       Jan 17, 2019 via iPhone
    播放,录屏....这个思路不知道行不行 QAQ
    msg7086
        19
    msg7086  
       Jan 17, 2019   ❤️ 1
    首先第一个问题是就不应该考虑 ffmpeg 的 concat。ffmpeg 的 concat 是非常原始的连接,对于容器格式不是很适用。
    然后要合并文件,要考虑的是目标文件格式支持哪些特性。
    比如说你要合并成 mp4,那么流的格式就有限定(比如 ass 字幕就不可能合并),流本身也有限定,比如把一个 avc 的视频和一个 hevc 的视频接在一起大概率是要崩的。不同参数编码出来的视频放在一起也有很大概率会崩。

    最有希望合并的情况是,这些片段原本就是从一个源上切下来的,或者是从多个相同参数编码的片段上切下来的。
    这种情况直接用 mp4box 合并大概就行了。

    mp4box -cat part1.mp4 -cat part2.mp4 output.mp4

    就是要注意一下这样合并出来的视频,中间可能会有多余的 VPS SPS SEI 帧,如果你介意的话还得手动编辑流去去掉。

    另外帧率不同其实只需要合并一下 timecode 就行了。
    35korea
        20
    35korea  
       Jan 17, 2019 via Android
    final cut 不是可以改参数统一 fps 吗
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4858 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 09:57 · PVG 17:57 · LAX 02:57 · JFK 05:57
    ♥ Do have faith in what you're doing.