使用 ffmpeg 动态更改视频裁剪宽度、高度、x 和 y

Dynamically change video crop width, height, x and y using ffmpeg

我正在对视频进行对象检测,到目前为止我已经获得了视频中对象的坐标。

现在我想根据对象的location/coordinates逐帧裁剪视频

到目前为止我的代码:

def crop_video(input_video_path, output_video_path, coordinate_list):
    
    crop_ratio = 'crop=%s:%s:%s:%s' % (coordinate_list[0][0], coordinate_list[0][1], coordinate_list[0][2],coordinate_list[0][3])
    subprocess.run(['ffmpeg', '-i', input_video_path, '-filter:v', crop_ratio, output_video_path])

crop_video 函数仅使用 coordinate_list 列表中的第一个索引裁剪整个视频。如何改进代码以动态更改。 坐标列表类似于此:

 coordinate_list = [[147.5, 253.5, 927, 107],
     [147.5, 253.5, 927, 107],
     [147.0, 257.5, 928, 102],
     [148.5, 258.5, 925, 104],
     [148.5, 258.5, 925, 104],
     [155.0, 258.5, 918, 103],
     [155.0, 258.5, 918, 103],]

如何使用 coordinate_list 动态更改裁剪宽度、高度、x 和 y。我刚开始使用 ffmpeg

使用 sendcmd 过滤器。

  1. 使commands.txt:

    0    crop w 148,
         crop h 254,
         crop x 925,
         crop y 108;
    
    0.04 crop w 142,
         crop h 252,
         crop x 927,
         crop y 107;
    
    0.08 crop w 147,
         crop h 258,
         crop x 928,
         crop y 102;
    
    • 文本的格式不必与上面完全相同。为了便于阅读,我添加了换行符。如果愿意,您可以将每个时间戳放在自己的行上。
    • sendcmd 使用时间戳,而不是帧号。此示例显示帧 1-3 并假定帧速率为 25 (1/25 = 0.04)。
    • 并非所有过滤器都可以使用 sendcmd(或音频版本 asendcmd)。请参阅 ffmpeg -filters 的输出。如果过滤器支持 (a)sendcmd,它将在列表中的过滤器名称前面有一个 T
    • 并非所有过滤器选项都可以与 sendcmd 一起使用。请参阅 FFmpeg Filters Documentation 并查找“命令”。
  2. 运行 ffmpeg:

    ffmpeg -i input.mp4 -filter_complex "[0:v]sendcmd=f=commands.txt,crop" output_%03d.png