欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ffmpeg格式转换之MP4转mov

程序员文章站 2022-03-20 08:25:20
...

原MP4格式视频文件

ffmpeg格式转换之MP4转mov

格式转换后mov格式文件

ffmpeg格式转换之MP4转mov

转换成功

ffmpeg格式转换之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;
}