ffmpeg格式转换之MP4转mov

原MP4格式视频文件

格式转换后mov格式文件

转换成功

实现方式


//引入c语言头文件
extern "C"
{
	#include <libavformat\avformat.h>
}

#include <iostream>
using namespace std;
//引入链接库
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")

//将MP4格式的文件转换成mov格式
int main()
{
	char infile[] = "test.mp4";
	char outfile[] = "test.mov";

	//注册封装,解封装格式
	av_register_all();
	//1 打开文件
	AVFormatContext *ic = NULL;
	avformat_open_input(&ic,infile,0,0);
	if (!ic) {
		cout << "avformat_open_input failed !" << endl;
		getchar();
	}
	//2 create output context
	AVFormatContext *oc = NULL;
	avformat_alloc_output_context2(&oc, NULL, NULL, outfile);
	if (!oc)
	{
		cerr << "avformat_alloc_output_context2 " << outfile << " failed!" << endl;
		getchar();
		return -1;
	}

	//3 add the stream
	AVStream *videoStream = avformat_new_stream(oc,NULL);
	AVStream *audioStream = avformat_new_stream(oc,NULL);

	//4 copy para
	avcodec_parameters_copy(videoStream->codecpar, ic->streams[0]->codecpar);
	avcodec_parameters_copy(audioStream->codecpar,ic->streams[1]->codecpar);

	videoStream->codecpar->codec_tag = 0;
	audioStream->codecpar->codec_tag = 0;

	av_dump_format(ic,0,infile,0);
	cout << "================================================" << endl;
	av_dump_format(oc, 0, outfile, 1);

	//5 open out file io,write head
	int ret = avio_open(&oc->pb,outfile,AVIO_FLAG_WRITE);
	if (ret < 0)
	{
		cerr << "avio open failed!" << endl;
		getchar();
		return -1;
	}
	ret = avformat_write_header(oc,NULL);
	if (ret < 0)
	{
		cerr << "avformat_write_header failed!" << endl;
		getchar();
	}
	AVPacket pkt;
	for (;;)
	{
		int re = av_read_frame(ic,&pkt);
		if (re<0)
		{
			break;
		}
		//此函数主要用于对于不同时间戳的转换。
		//具体来说是将以 "时钟基c" 表示的 数值a 转换成以 "时钟基b" 来表示
		pkt.pts = av_rescale_q_rnd(pkt.pts,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
		pkt.dts = av_rescale_q_rnd(pkt.dts,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)
		);
		pkt.pos = -1;
		pkt.duration = av_rescale_q_rnd(pkt.duration,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)
		);
		av_write_frame(oc,&pkt);
		//引用计数减一
		av_packet_unref(&pkt);
		cout << ".";
	}

	//写文件尾
	av_write_trailer(oc);
	avio_close(oc->pb);
	cout << "================end================" << endl;
	getchar();

	return 0;
}

猜你喜欢

转载自blog.csdn.net/hb707934728/article/details/81353960
今日推荐