ffmpeg视频精确截取与合成

发布于 2020-04-04  916 次阅读


1:精确截取视频(按秒)

ffmpeg  -ss 开始时间 -i mp4输入路径 -t 持续时间 -c:v libx264 -c:a aac -strict experimental  -vf scale=宽:高  -b 500k 输出路径.mp4 

以上代码就是从视频中按照时间来截取视频片段,然后做一次转码,关于网上其他的视频截取大部分都是用的copy...就是很不准确了,需要按照1s间隔截取莫名其妙就变成了3s 4s....

如果想按照时间区间来截取的话只需要稍微修改一下参数

ffmpeg -ss 开始时间 -to 结束时间-accurate_seek -i mp4输入路径 -c:v libx264 -c:a aac -strict experimental -vf scale=宽:高 -b 500k 输出路径.mp4

其中开始时间格式为00:00:00 结束时间同理

2:多视频合成一个视频

其实拼接的方法有好几种,有concat分离器,concat协议等方法,因为我需要拼接批量的视频文件,这里我选了concat分离器来做,因为如果用concat协议来拼接的话就要一直拼接字符串会比较麻烦,而用分离器来做的话直接写文件即可,读取完文件拼接成功直接丢掉文件(删除)

文件格式为:file '路径'

然后读取文件:

ffmpeg -f concat -safe 0 -i "file.txt" -c copy   "输出mp4的路径" -y

file.txt 文件的内容大致是这样的

file '/temp/0000.mp4'
file '/temp/0001.mp4'
file '/temp/0002.mp4'
file '/temp/0003.mp4'
file 'temp/0004.mp4'
file '/temp/0005.mp4'
file '/temp/0006.mp4'
file '/temp/0007.mp4'
file '/temp/0008.mp4'

示例代码:

//生成file.txt文件
let videoPath='xxx/xxx/xxx' 
let files = fs.readdirSync('videoPath');
        files = files.filter(file => file != '.DS_Store');
        let videoFile = 'xxx/xxx.txt';   
        //存在文件先删除
        if (fs.existsSync(videoFile)) fs.unlinkSync(videoFile);
        for (let file of files) {
            let filePath = path.join(videoPath, file);
            fs.appendFileSync(videoFile, `file '${filePath}' \n`);
        }

以上代码是用js写的,大致思路就是这样,生成文件执行以上的命令即可拼接视频,完成之后别忘了毁尸灭迹(指删除file.txt和多余的文件)

后续===>

这里先排几个雷,免得踩坑

1:关于Unsafe file name /xx/xxx/xx/xxx.mp4和file.txt: Operation not permitted 等错误解决

出现了 Operation not permitted 这种错误很明显是权限不够,那么加上以上的 -safe 0 即可

-safe 这个属性我去官网的文档查了一下,默认值是1,1代表拒绝所有不安全的文件路径

大致是因为文件只包含了字母、数字这些他认为不规范的命名,所以这里要么改文件名,或者把safe属性调整为0 0则代表同意任何文件

2:出现 执行ffmpeg -f concat -safe 0 -i "file.txt" -c copy "输出mp4的路径" -y 命令出现 Impossible to open '"xxx/xxx/xxx.mp4"'错误

那是因为写文件的时候把'' 写成了"",把""改成''即可


一个逐渐被时间遗忘掉的人