Python3 FFMPEG精确剪切测试笔记——使用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
重编码十倍速起步,复制编码最差百倍速起步,没有视频画面处理的需要,建议采用复制编码方式剪切,速度是一方面,关键品质不会再次损耗,保持与原片一致。
本文详细记录了使用Python3的ffmpeg-python库进行视频剪切的测试过程,包括有损剪切(重新编码)和无损剪切(复制编码)的情况,涉及多个测试案例,探讨了不同参数设置对剪切效果的影响,并给出了速度对比。

1197

被折叠的 条评论
为什么被折叠?



