利用FFMPEG命令进行文件分割
ffmpeg -ss 00:00:00 -i input.mp4 -c copy -t 60 output.mp4
-ss 表示视频分割的起始时间,-t 表示分割时长,同时也可以用 00:01:00表示
注意 :-ss 要放在 -i 之前
对于普通的视频分割这个命令可能够用了
但是
如果你想要连续风格一段视频,简单的使用此命令就会发现一个问题:连续分割的视频之间存在细微的交集
原因:
视频的开始都是一个关键帧,如果视频的第一帧不是关键帧就会导致视频播放的前面简短画面模糊不清,所以为了让视频不会出现开始画面模糊的情况,就会从所开始时间定位到其对应帧,如果该帧不是关键帧,则在其位置附近找关键帧的位置,然后从该关键帧处开始复制视频帧。
根据起始时间定位到的帧不是关键帧,而是位于两个关键帧中间的B帧或P帧上,那么是从前一个关键帧开始还是后一个关键帧开始呢?
截至时间定位的帧同样可能处于非关键帧处,这时候不一定要向两边找关键帧?
这时候起始帧如果找前面的关键帧作为起始帧开始复制,就会导致本段视频的和前面视频有重复帧:重复帧数为起始关键帧和上一段截至帧之间的帧数。
如果起始帧找后面的关键帧开始复制,就会导致两段连续分割的视频可能出现跳帧现象
利用ffmpeg提供的库自己实现不重复不跳帧分割
利用上述分析,我们在分割的时候自己统一设置分割视频的截止帧为截止时间对应帧(假设此帧为非关键帧,否则为此帧的前一帧)附近前面关键帧的前一帧,而下一段分割视频就从该关键帧开始。
关键代码
视频头信息设置
AVOutputFormat *ofmt = NULL;
int ret;
ofmt = ofmtCtx->oformat;
for (int i = 0; i < ifmtCtx->nb_streams; i++) {
//根据输入流创建输出流
AVStream *in_stream = ifmtCtx->streams[i];
AVStream *out_stream = avformat_new_stream(ofmtCtx, in_stream->codec->codec);
if (!out_stream) {
return false;
}
//复制AVCodecContext的设置
ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
if (ret < 0) {
return false;