FFmpeg——视频拼接总结

最近需要做一个关于视频拼接的内容,需要将两个视频合成一个视频,使用opencv的话需要将视频读上来然后再写到文件了,这个会很消耗时间也没有必要。两个视频的编码格式是一样的,并不需要转码操作所以想法是直接将视频流补到后面,这样可以直接省去加解码操作。在查找了ffmpeg资料后发现是支持这么做的,但是必须要将文件一一打开然后复制到另一个文件中,资料中有很多中说法concat demuxer(解复用,这个其实不太理解什么意思,但是看说明就是利用一个txt文件将需要进行拼接的文件列在这个txt中,然后一一去处理,做一个流的拷贝)。FFmpeg功能强大唯一不好的一点是大部分都是使用命令行的操作,编程相关的内容少的可怜,而且很不全面,后面找了好久都没找到很完整的内容,需要自己一点一点去找和试,其中有几个不错的参考。一个是一本新上来的书,他有随书代码可以参考“ffmpeg从零基础到短视频上线”,这个里面的示例还是挺多的,感觉也挺实用的。还有就是官方的github代码以及“https://github.com/0voice/ffmpeg_develop_doc”这个网址下有很多的参考资料。这几个是我能找到相对较全并且内容也比较实用的资料了,剩下的基本上都是命令行之类的我用不到就先忽略。

这里主要记录一下完整的视频流拷贝代码,网上想找一个比较完整的代码好难,这个代码用于提供参考以及后面自己回顾。

这里就以两个文件为例进行合并,并且只转换其中的视频流。

vector<string> fileList = {
   
    url_origin,url_add };//这是两个文件
//获得原始输入视频文件编码等信息
const AVOutputFormat* ofmt = NULL;//输出格式
AVFormatContext* ifmt_ctx = NULL, * ofmt_ctx = NULL;//视频数据维护对象
AVPacket* pkt = NULL;//数据包

int ret;//函数执行返回码
int stream_index;//数据流索引

pkt = av_packet_alloc();//初始化数据包结构
if (!pkt)
{
   
   
	return;
}

if ((ret = avformat_open_input(&ifmt_ctx, url_origin, 0, 0) < 0))
{
   
   
	goto end;//打开文件失败
}

//获得输出文件名
string out_file;
auto name = ifmt_ctx->iformat->name;//自动识别文件的封装类型
//hevc只能使用MP4或者hevc封装才能完成转换,其余封装报错,因为这里进行了自动识别可以不用管具体格式
out_file.replace(out_file.find('.')+1, 3

你可能感兴趣的:(FFmpeg,ffmpeg,音视频,c++)