Python3 FFMPEG精确剪切测试笔记——使用ffmpeg-python库

本文详细记录了使用Python3的ffmpeg-python库进行视频剪切的测试过程,包括有损剪切(重新编码)和无损剪切(复制编码)的情况,涉及多个测试案例,探讨了不同参数设置对剪切效果的影响,并给出了速度对比。

1. 测试环境

1.1 ffmpeg-python

ffmpeg-python库文档:
https://github.com/kkroening/ffmpeg-python

命令安装:

pip install ffmpeg-python

1.2 ffmpeg

FFmpeg下载页面:
https://ffmpeg.org/download.html

D:\test_video>ffmpeg -version
ffmpeg version N-101404-g17127f81c5 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 9.3-win32 (GCC) 20200320
configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --disable-w32threads --enable-pthreads --enable-iconv --enable-zlib --enable-libxml2 --enable-libfreetype --enable-libfribidi --enable-gmp --enable-lzma --enable-fontconfig --enable-opencl --enable-libvmaf --disable-vulkan --enable-libvorbis --enable-amf --enable-libaom --enable-avisynth --enable-libdav1d --enable-libdavs2 --enable-ffnvcodec --enable-cuda-llvm --disable-libglslang --enable-libass --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvpx --enable-libwebp --disable-lv2 --enable-libmfx --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-ldflags=-pthread --extra-libs=-lgomp
libavutil      56. 67.100 / 56. 67.100
libavcodec     58.129.100 / 58.129.100
libavformat    58. 71.100 / 58. 71.100
libavdevice    58. 12.100 / 58. 12.100
libavfilter     7.109.100 /  7.109.100
libswscale      5.  8.100 /  5.  8.100
libswresample   3.  8.100 /  3.  8.100
libpostproc    55.  8.100 / 55.  8.100

1.3 测试视频

测试视频下载点这里

2. 重新编码情况(有损剪切)

2.1 编码参数

ffmpeg.output( vcodec=‘h264’)

2.2 正确参数用法总结

input(ss=HH:MM:SS.xxx),output(t=HH:MM:SS.xxx),output(vframes=n)
ss = 入点时码前一帧
t = 目标时长帧数加一帧
vframes = 目标时长帧数加一帧
ms = frame / fps

2.3 测试过程

为了测试精准剪切,用了三个镜头,第一个镜头保留两帧,第三个镜头保留两帧

2.31 测试一

剪切打点出入点时码 timecode.frame

  • 8.10f (138f) - 20.13f (333f) = 12.1875 (195f)

转码命令出入点时码 timecode.ms

  • 8.625ms (138f) - 20.8125ms (333f) = 12.1875 (195f)
import ffmpeg
(
	ffmpeg
	.input('test.mp4',ss="00:00:08.625")
	.output('output_cut.mp4',vcodec='h264',acodec='aac',t="00:00:12.1875")
	.overwrite_output()
	.run()
)
frame=  195 fps=0.0 q=-1.0 Lsize=    1403kB time=00:00:12.16 bitrate= 944.5kbits/s speed=13.2x

结束剪切时长 00:00:12.16ms 开始画面少了一帧

2.32 测试二

解决测试一问题 : 开始画面少了一帧

  • 入点提前一帧
  • 转码总帧数=新的出点-新的入点=目标帧数+1

剪切打点出入点时码 timecode.frame

  • 8.10f (138f) - 20.13f (333f) = 12.1875 (195f)

转码命令出入点时码 timecode.ms

  • 8.5625ms (137f) - 20.8125ms (333f) = 12.25 (196f)
import ffmpeg
(
	ffmpeg
	.input('test.mp4',ss="00:00:08.5625")
	.output('output_cut.mp4',vcodec='h264',acodec='aac',t="00:00:12.25")
	.overwrite_output()
	.run()
)
frame=  196 fps=0.0 q=-1.0 Lsize=    1419kB time=00:00:12.23 bitrate= 950.2kbits/s speed=13.4x

结束剪切时长 00:00:12.23ms 画面前后都达标

2.33 测试三

剪切时长改为帧vframes

timecode.frame

  • frames = hh*3600*fps + mm*60*fps + ss*fps + frame

timecode.ms

  • frames = hh*3600*fps + mm*60*fps + ss*fps + ms*fps

剪切打点出入点时码 timecode.frame

  • 8.10f (138f) - 20.13f (333f) = 12.1875 (195f)

转码命令出入点时码 timecode.ms

  • 8.5625ms (137f) - 20.8125ms (333f) = 12.25 (196f)
import ffmpeg
(
	ffmpeg
	.input('test.mp4',ss="00:00:08.5625")
	.output('output_cut.mp4',vcodec='h264',acodec='aac',vframes=196)
	.overwrite_output()
	.run()
)
frame=  196 fps=0.0 q=-1.0 Lsize=    1423kB time=00:00:12.67 bitrate= 919.6kbits/s speed=14.1x

结束剪切时长 00:00:12.67ms 画面前后都达标

3. 复制编码情况(无损剪切)

3.1 编码参数

ffmpeg.output( codec=‘copy’)

3.2 正确参数用法总结

input(ss=HH:MM:SS.xxx),output(t=HH:MM:SS.xxx),output(vframes=n)
ss = 入点时码前一帧
t = 目标时长帧数减一帧
vframes = 结束帧号
ms = frame / fps

3.3 测试过程

为了测试精准剪切,用了三个镜头,第一个镜头保留两帧,第三个镜头保留两帧

3.31 测试三

剪切打点出入点时码 timecode.frame

  • 8.10f (138f) - 20.13f (333f) = 12.1875 (195f)

转码命令出入点时码 timecode.ms

  • 8.625ms (138f) - 20.8125ms (333f) = 12.1875 (195f)
import ffmpeg
(
	ffmpeg
	.input('test.mp4',ss="00:00:08.625")
	.output('output_cut.mp4',codec='copy',t='00:00:12.1875')
	.overwrite_output()
	.run()
)
frame=  335 fps=0.0 q=-1.0 Lsize=    3537kB time=00:00:12.18 bitrate=2379.2kbits/s speed=1.58e+03x

结束剪切时长 00:00:12.18ms 开始画面少了一帧 结束画面多了两帧

3.32 测试四

解决测试三问题 : 开始画面少了一帧 结束画面多了两帧

  • 入点提前一帧
  • 转码总帧数=新的出点-新的入点-1=目标时长

剪切打点出入点时码 timecode.frame

  • 8.10f (138f) - 20.13f (333f) = 12.1875 (195f)

转码命令出入点时码 timecode.ms

  • 8.5625ms (137f) - 20.8125ms (333f) = 12.25 (196f) - 1 = 12.1875 (195f)
import ffmpeg
(
	ffmpeg
	.input('test.mp4',ss="00:00:08.5625")
	.output('output_cut.mp4',codec='copy',t='00:00:12.1875')
	.overwrite_output()
	.run()
)
frame=  334 fps=0.0 q=-1.0 Lsize=    3523kB time=00:00:12.17 bitrate=2370.7kbits/s speed=1.49e+03x

结束剪切时长 00:00:12.17ms 开始画面正常 结束画面多一帧

3.33 测试五

解决测试四问题 : 结束画面多一帧

  • 入点提前一帧
  • 转码总帧数=新的出点-新的入点-2=目标时长-1

剪切打点出入点时码 timecode.frame

  • 8.10f (138f) - 20.13f (333f) = 12.1875 (195f)

转码命令出入点时码 timecode.ms

  • 8.5625ms (137f) - 20.8125ms (333f) = 12.25 (196f) - 2 = 12.125 (194f)
import ffmpeg
(
	ffmpeg
	.input('test.mp4',ss="00:00:08.5625")
	.output('output_cut.mp4',codec='copy',t='00:00:12.125')
	.overwrite_output()
	.run()
)
frame=  333 fps=0.0 q=-1.0 Lsize=    3516kB time=00:00:12.10 bitrate=2379.7kbits/s speed=1.56e+03x

结束剪切时长 00:00:12.10ms 画面前后都达标

3.34 测试六

剪切时长改为帧vframes

转码命令出入点帧码

  • 8.5625ms (137f) - 20.8125ms (333f) = 12.25 (196f) - 2 = 12.125 (194f)
import ffmpeg
(
	ffmpeg
	.input('test.mp4',ss="00:00:08.5625")
	.output('output_cut.mp4',codec='copy',vframes=194)
	.overwrite_output()
	.run()
)
frame=  194 fps=0.0 q=-1.0 Lsize=    1865kB time=00:00:03.37 bitrate=4526.3kbits/s speed= 380x

结束剪切时长 00:00:3.37ms 开始画面达标 结束时长不正确194f-138f=56f

3.35 测试七

解决测试六问题 : 结束时长不正确194f-138f=56f

  • codec=copy情况下vframes理解为结束帧,重新编码情况下为时长帧

转码命令出入点帧码

  • 8.5625ms (137f) - 20.8125ms (333f)
import ffmpeg
(
	ffmpeg
	.input('test.mp4',ss="00:00:08.5625")
	.output('output_cut.mp4',codec='copy',vframes=333)
	.overwrite_output()
	.run()
)
frame=  333 fps=0.0 q=-1.0 Lsize=    3515kB time=00:00:12.06 bitrate=2387.4kbits/s speed=1.29e+03x

结束剪切时长 00:00:12.06ms 画面时长都达标

4. 速度对比

  • 默认参数h264重编码

ffmpeg.output( vcodec=‘h264’)

frame=  195 fps=0.0 q=-1.0 Lsize=    1403kB time=00:00:12.16 bitrate= 944.5kbits/s speed=13.2x
frame=  196 fps=0.0 q=-1.0 Lsize=    1419kB time=00:00:12.23 bitrate= 950.2kbits/s speed=13.4x
frame=  196 fps=0.0 q=-1.0 Lsize=    1423kB time=00:00:12.67 bitrate= 919.6kbits/s speed=14.1x
  • 复制编码

ffmpeg.output( codec=‘copy’)

frame=  335 fps=0.0 q=-1.0 Lsize=    3537kB time=00:00:12.18 bitrate=2379.2kbits/s speed=1.58e+03x
frame=  333 fps=0.0 q=-1.0 Lsize=    3516kB time=00:00:12.10 bitrate=2379.7kbits/s speed=1.56e+03x
frame=  194 fps=0.0 q=-1.0 Lsize=    1865kB time=00:00:03.37 bitrate=4526.3kbits/s speed= 380x

重编码十倍速起步,复制编码最差百倍速起步,没有视频画面处理的需要,建议采用复制编码方式剪切,速度是一方面,关键品质不会再次损耗,保持与原片一致。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值