[ FFmpeg ] 精确时间截取视频文件
最近收到一个项目需求,是我工作以来,见过客户提出的最明确的需求:
将视频讲解切割,每张幻灯的片断一个文件,按幻灯页码命名文件01.mp4,02.mp4,03.mp4……,以此类推;分辨率不超过320*180像素,单声道96kbps音质,控制每个文件尺寸不超过10M,另请发来对应的ppt文档,用来制作成视频与ppt同步翻页的课程。
于是,承接前面一篇,三分屏课件制作教程,我考虑也能自动按照时间轴拆分所有视频文件。于是得到了下面这段分割代码。
ffmpeg -ss [start] -t [duration] -accurate_seek -i [in].mp4 -codec copy [out].mp4
[duration] : 为需要截取的时长
[in] : 为输入视频文件名
[out] : 为输出视频文件名
[start] : 为需要截取内容的开始时间
这种截取的好处是特别快,因为它不会对视频重新编码,直接截取相关时间,导出视频,但是这种方式会导致:如果视频结尾不是关键帧,那么视频最后就会出现一段空白。
这个时候,你可以加入[-avoid_negative_ts 1]变成这样:
ffmpeg -ss [start] -t [duration] -accurate_seek -i [in].mp4 -codec copy -avoid_negative_ts 1 [out].mp4
这样截取视频之后,空白视频是没有了,但是时间不会精确截取,它会找到下一个关键帧,补全这个视频,所以,导致连续分割的视频之间存在细微的交集。
最后详细看了下FFmpeg的文档,如果你需要精确截取视频,避免关键帧的丢失并精确截取时间,这个时候最好是重新编码视频。就变成这样了:
ffmpeg -ss [start] -t [duration] -i [in].mp4 -c:v libx264 -c:a aac -strict experimental -b:a 98k [out].mp4
最后,你可以写一段脚本,把整个视频拆分:
import os
import json
with open("timeline.json") as f:
times = json.loads(f.read())
times = times["timeline"]
for i in range(len(times)):
start = times[i]["time"]
try:
length = times[i+1]["time"] - times[i]["time"]
except:
length = 1000
os.system('ffmpeg -ss %s -i small.mp4 -t %s -c:v libx264 -c:a aac -strict experimental -b:a 96k %s.mp4' % (start,length,str(i+1)))
编辑于 2017-06-12 23:58
成功案例:
ffmpeg -ss 00:02:30 -to 00:19:17 -i dpcq.mp4 -c:v copy out3.mp4
查看时长:
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i out3.mp4
标题:[ FFmpeg ] 精确时间截取视频文件
作者:llilei
地址:http://solo.llilei.work/articles/2023/11/08/1699426138021.html