我尝试使用以下命令使用视频的开始和结束时间来剪切视频

ffmpeg -ss 00:00:03 -t 00:00:08 -i movie.mp4 -acodec copy -vcodec copy -async 1 cut.mp4

通过使用上面的命令,我想把视频从00:00:03剪辑到00:00:08。但它并没有在这两个时间之间剪切视频,而是剪切了前11秒的视频。有人能帮我解决这个问题吗?

编辑1:

我尝试使用mark4o建议的以下命令进行切割

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

但是显示了以下错误。

编码器“aac”是实验性的,但实验性编解码器未启用

因此,我在命令中添加了-strict -2,即,

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 -strict -2 cut.mp4

现在它工作得很好。


当前回答

我的设置:

$ ffmpeg
ffmpeg version 4.4 Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 12.0.5 (clang-1205.0.22.9)

我发现开关的顺序很重要。 如果-i不在-ss和-t之间,那么结果中有大约3秒的空白。

所以无论你使用什么额外的开关,确保这三个开关的顺序是正确的,就像这样

ffmpeg -ss 00:00:03 -i movie.mp4 -t 00:00:08 cut.mp4

其他回答

    ffmpeg -i movie.mp4 -vf trim=3:8 cut.mp4

除了第3秒到第8秒,放下所有东西。

使用-to代替-t: -to指定结束时间,-t指定持续时间

下面是我使用的,只需要几秒钟就可以运行:

ffmpeg -i input.mp4 -ss 01:19:27 -to 02:18:51 -c:v copy -c:a copy output.mp4

参考:使用FFmpeg由Alexander Refsum Jensenius修剪视频文件。


生成的mp4文件也可以在iMovie中使用。有关使用get_duration(input_video)模型获取完整持续时间的更多信息。

如果你想连接多个过场动画,你可以使用以下Python脚本:

#!/usr/bin/env python3

import subprocess

def get_duration(input_video):
    cmd = ["ffprobe", "-i", input_video, "-show_entries", "format=duration",
           "-v", "quiet", "-sexagesimal", "-of", "csv=p=0"]
    return subprocess.check_output(cmd).decode("utf-8").strip()


def main():
    name = "input.mkv"
    times = []
    times.append(["00:00:00", "00:00:10"])
    times.append(["00:06:00", "00:07:00"])
    # times = [["00:00:00", get_duration(name)]]
    if len(times) == 1:
        time = times[0]
        cmd = ["ffmpeg", "-i", name, "-ss", time[0], "-to", time[1], "-c:v", "copy", "-c:a", "copy", "output.mp4"]
        subprocess.check_output(cmd)
    else:
        open('concatenate.txt', 'w').close()
        for idx, time in enumerate(times):
            output_filename = f"output{idx}.mp4"
            cmd = ["ffmpeg", "-i", name, "-ss", time[0], "-to", time[1], "-c:v", "copy", "-c:a", "copy", output_filename]
            subprocess.check_output(cmd)

            with open("concatenate.txt", "a") as myfile:
                myfile.write(f"file {output_filename}\n")

        cmd = ["ffmpeg", "-f", "concat", "-i", "concatenate.txt", "-c", "copy", "output.mp4"]
        output = subprocess.check_output(cmd).decode("utf-8").strip()
        print(output)


if __name__ == "__main__":
    main()

示例脚本将在00:00:00 - 00:00:10和00:06:00 - 00:07:00之间剪切和合并场景。


如果你想剪切完整的视频(如果你想将mkv格式转换为mp4格式),只需取消下面这一行的注释:

# times = [["00:00:00", get_duration(name)]]

我创建了一对shell脚本来处理我的代码转换需求,包括剪切广告。我想做毫秒级的精确剪辑,不介意付出重新编码的代价。

sh处理代码转换,包括提取片段。 一个可以指定广告(或片段)开始和停止的前端。

把两个脚本都放在你的路径上……和…

# Cut out everything from (3min 12.345s to 4min 1s) and (1hour 48min 0.2s to 1hour 52min 43.0s)
ff-segmenter.sh -i "input.mp4" -o "output.mp4" -x -s 3:12.345-4:01 -s 1:48:00.2-1:52:43

如果没有-x开关,选择是反向的。因此删除列表之外的所有内容。-h开关解释了这一点。

首先,视频应该使用ffvhuff编码器进行编码,以便视频可以精确地切割到开始和结束时间。通常,使用上面给出的其他命令,视频可能不会被切割到特定的持续时间,因为不是每一帧都是内部编码帧。

ffmpeg -ss 00:03:00 -i input_file.mkv -t 00:01:19 -c:v ffvhuff -pix_fmt yuv420p -y output_file.mkv