先来看个示例:
ffmpeg -s 0 -i input.mp4 -t 10 output.mp4
这段命令将截取输入视频 input.mp4 从0秒开始到第10秒之间的片段,并保存的 output.mp4 文件。命令可以分为三个部分:
ffmpeg 接受三种类型的输出:
C++音视频开发学习资料:点击领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
借助 - 特性,我们可以以管道风格调用ffmpeg命令,例如:
ffmpeg -s 0 -i input.mp4 -t 10 -f mpegts - | tee output.ts
提示:使用 - 时,ffmpeg 会尽量遵循管道通讯约束,将命令处理后的视频流输出到标准输出流;将命令运行的过程信息输出到标准错误流。
流式处理最大的好处是不用等整个视频命令处理完就可以先拿到一部分数据,这在一些性能敏感场景,比如web视频服务、直播流等能够提高响应速度。在node实现中,本质上是使用 spawn 接口调用 ffmpeg 命令,借助父子进程间的管道通讯机制,将 ffmpeg 命令的标准输出流输出到目标视频文件中,实现保存效果,完整示例:
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
function transform(sourceFile, outputStream, start, duration) {
const params = [`-ss`, start, `-i`, sourceFile, `-t`, duration, '-f', 'mpegts', '-'];
return new Promise((r, j) => {
const cp = spawn('ffmpeg', params);
// ffmpeg 标准输出流
cp.stdout.pipe(outputStream);
// 将 ffmpeg 执行的过程日志输出到程序的标准输出流,通常为console
cp.stderr.pipe(process.stdout);
cp.on('error', (err) => {
j(err);
});
cp.on('close', (code) => {
console.log(`ffmpeg process close all stdio with code ${code}`);
r(code);
});
cp.on('exit', (code) => {
console.log(`ffmpeg process exited with code ${code}`);
});
});
}
async function run() {
const inputFile = path.join(__dirname, 'test.mp4');
const output = fs.createWriteStream(path.join(__dirname, 'output.mp4'));
await transform(inputFile, output, 0, 100);
}
run();
运行效果:
C++音视频开发学习资料:点击领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
ffmpeg 虽然提供了流式输出功能,但并不适用于所有场景,我简单测试了一下发现:
留言与评论(共有 0 条评论) “” |