【问题标题】:FFMpeg video stopmotionFFMpeg 视频定格动画
【发布时间】:2018-12-13 13:58:24
【问题描述】:

我想从原始视频制作定格视频。 逻辑是以指定的间隔取帧。 并以指定的播放速率播放视频。

例如,
原始视频时长为 114.048 秒。
输出视频播放速度比源视频快5倍。
以 1 秒的间隔拍摄每一帧。所以最终的视频时长应该是 (22.81 = 114.048/1*0.2) 秒

下面是demo的截图

为此我需要 ffmpeg 代码

ffmpeg -r 1 -i D:\21-03-2018\15305154945b39d026a18da.mp4 D:\21-03-2018\output.mp4

【问题讨论】:

    标签: video ffmpeg


    【解决方案1】:

    我想详细说明Gyan 已经给出的the answer 的代码以及我对文档的解释和我所做的试验。

    ffmpeg -i in.mp4 -vf "select='trunc(t)-trunc(prev_selected_t)',setpts=0.2*PTS" -an out.mp4

    从后到前分析

    • 流选择/音频选项

      • -an 选项detailed here 跳过将音频流包含到输出中

        • 由于如果 ffmpeg 尝试混合长度较长的未处理音频,则视频是唯一已处理并缩短长度的部分,因此生成的视频将是两者中较长者的长度。
    • 视频过滤器-vf "...."

      • setpts 过滤器、documentation herea brief explanation by Gyan aswell, here。只改变输出视频的速度

        • 您可以将乘数查看为setpts=(<input_speed>/<output_speed>)*PTS

          • 大于 1 的数字意味着输出比输入慢,反之亦然。

            • 0.2 是 1/5,因此输出视频比输入快 5 倍。
      • select 过滤器 documented here 逐帧处理并定义丢弃帧或将其作为计算表达式的结果发送到输出。

        • 代码'trunc(t)-trunc(prev_selected_t)'中定义的表达式采用:
          • t :过滤后视频帧的PTS,以秒为单位。
          • prev_selected_t :上次选择的视频帧的 PTS,以秒为单位。
          • 将它们截断,删除小数部分,然后减去它,如果处理的帧来自视频中的不同秒,则结果会与零不同。
            • 按照这个等式,它将每秒选择第一帧并丢弃其余帧。
              • 这相当于“每秒从原始视频中获取一帧”

    不同的剪辑率

    trunc(x) - trunc(x_{-1}) 在每个整数的交叉点上的计算结果都不是零。如果您增加或减少样本空间中的整数数量,您将获得更多或更少的结果帧。由于tprev_selected_t 代表每一帧的秒数,您可以乘以这种表示法以将这些秒数映射为或多或少的整数,从而获得不同的采样/剪辑率。

    • 0.2s : 'trunc(5*t)-trunc(5*prev_selected_t)'
    • 0.4s : 'trunc(2.5*t)-trunc(2.5*prev_selected_t)'
    • 0.6s : 'trunc((5/3)*t)-trunc((5/3)*prev_selected_t)'
    • 0.8s : 'trunc(1.25*t)-trunc(1.25*prev_selected_t)'
    • 1.5s : 'trunc(0.667*t)-trunc(0.667*prev_selected_t)'
    • 5.0s : 'trunc(0.2*t)-trunc(0.2*prev_selected_t)'
    • ...

    您不仅限于 trunc() here you can find other examples using other functions 函数,正如 Praveen Tamil 在他的回答中提出的那样

    list and brief explanations of the functions evaluated in the expression definition can be found here

    感谢 Gyan 提供这个过滤器,帮助我发现了更好的 ffmpeg。

    希望我的简短解释有助于理解可能进一步调整代码;)

    【讨论】:

      【解决方案2】:

      使用

      ffmpeg -i in.mp4 -vf "select='trunc(t)-trunc(prev_selected_t)',setpts=0.2*PTS" -an out.mp4
      

      【讨论】:

      • 嗨 Gyan,输出视频的时长仍然与原始视频的时长相同
      • 看起来你有音频。添加-an
      • -an 生成的输出视频持续时间为 37 秒。但根据我的逻辑,输出视频应长 22.81 秒
      • 在答案中尝试新的 expr
      • 输出视频的时长仍然是 37 秒
      【解决方案3】:

      我通过以下代码做到了这一点

      ffmpeg -i D:\21-03-2018\15305154945b39d026a18da.mp4 -an -vf "select='isnan(prev_selected_t)+gte(t-prev_selected_t,1)',setpts=0.20*PTS" D:\21-03-2018\output.mp4

      【讨论】:

        猜你喜欢
        • 2014-07-29
        • 1970-01-01
        • 2017-02-14
        • 2023-03-05
        • 2021-03-29
        • 2016-09-07
        • 1970-01-01
        • 2014-03-15
        • 2018-09-18
        相关资源
        最近更新 更多