目录

工欲善其事

实践出真知

活跃标签: linux java mysql 待分类 js springboot win10 电路 vue macOS nginx windows esp32 git docker idea maven esp8266 python Arduino

存档:

X

[ FFmpeg ] 精确时间截取视频文件

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