原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;
}