IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> FFmpeg之MOV_to_MP4 -> 正文阅读

[C++知识库]FFmpeg之MOV_to_MP4

之前遇到了一个BUG:是avcodec_parameters_copy(audioStream->codecpar, ic->streams[1]->codecpar);一直报错,最后发现是原来的视频材料就没有音频,所以会报错!!

记下这个BUG了

/*MP4_to_MOV*/
//命令行错误 : 宏定义无效: MSVCRTD.lib
//LNK1104	无法打开文件“MSVCRTD.lib”	test	D : \to2021\003 - FFmpeg\配置FFmpeg\src\test\LINK	1
//E0992	命令行错误 : 宏定义无效: MSVCRTD.lib	test	D : \to2021\003 - FFmpeg\配置FFmpeg\src\test\源.cpp	1

#include <iostream>
using namespace std;
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
extern "C"
{
#include <libavformat/avformat.h>//缺少会发生编译错误
}
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")//缺少时会出现LNK错误

//int main()
//{
//	//cout << AVClass::version << endl;
//	cout << avcodec_configuration() << endl;
//	return 0;
//}
int main()
{
	char infile[] = "test.mp4";
	char outfile[] = "000.mov";//名字可以随意换:兼容
	av_register_all();//注册所有的封装器+解封器,这个可以识别各种封装格式

	//1:打开封装
	AVFormatContext *ic = NULL;//ic是输入的
	//AVFormatContext 内容包括两个:
							//AVIOContext *pb:输入输出上下文(写入文件时需要,读取文件时不需要)   
							//AVStream **streams:每个stream存放一个流:视频/音频/字幕
	avformat_open_input(&ic,infile,0,0);
	//4个参数:
		//AVFormatContext**ps:存放整个封装格式的上下文
		//const char *url:路径(本地文件/http网站流/rtsp摄像头流)
		//AVInputFormat *fmt:输入格式的打开方式(一般置空:让url自己识别)
		//AVDictionary **options:设置格式的对应参数(一般置空)
	if (!ic)
	{
		cout << "avformat_open_input failed!" << endl;
		getchar();
		return -1;
	}
	cout << "open" << infile << "success!" << endl;

	///2:创建输出上下文--新建空间
	AVFormatContext *oc = NULL;//oc是输出
	avformat_alloc_output_context2(&oc, NULL, NULL, outfile);
	//内容与avformat_open_input类似:
								//第二个参数:指定输出格式(一般置空)
								//第三个参数:格式命(一般置空)
	if (!oc)
	{
		cerr << "avformat_alloc_output_context2 " << outfile << " failed!" << endl;
		getchar();
		return -1;
	}

	//3:创建放入流信息(视频+音频)空间--空间  这两个函数一写:就把配置的视频+音频信息写入到oc里了
	AVStream *videoStream = avformat_new_stream(oc, NULL);//两个参数:输出上下文+编码格式(因为只转封装,不做编码,所以置空)
	AVStream *audioStream = avformat_new_stream(oc, NULL);

	///4:通过copy配置参数信息
	//videoStream->codecpar出的问题
	avcodec_parameters_copy(videoStream->codecpar, ic->streams[0]->codecpar);//两个参数:目标文件<-------源文件
	avcodec_parameters_copy(audioStream->codecpar, ic->streams[1]->codecpar);//1是音频,0是视频

	videoStream->codecpar->codec_tag = 0;//因为不做编码,所以置空
	audioStream->codecpar->codec_tag = 0;

	av_dump_format(ic, 0, infile, 0);//打印信息  4个参数:第二个参数:索引值,第四个参数:0是输入,1是输出
	cout<<endl;//上一行:方便调试(经验),这次的参数是copy的,以后学的手动配置,尤其是在音频上
	cout << "—————————以上输出的是输入的内容信息(视频+音频),下面是新生成的文件的视频+信息——————————" << endl;
	cout << endl;
	av_dump_format(oc, 0, outfile, 1);

	//5:打开输出的文件,开始写入头部信息
	int ret = avio_open(&oc->pb, outfile, AVIO_FLAG_WRITE);//三个参数:输出文件的上下文,url,写入的标志
	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();
	}

	//6:开始死循环写每一帧的信息
	AVPacket pkt;//死循环前的单独信息配置
	for (;;)//无限循环
	{
		int re = av_read_frame(ic, &pkt);//读取一帧开始写入,两个参数:上写文+压缩的一帧(因为每帧不同,所以读取一帧就释放一帧,使用unref防止内存泄漏)
		if (re < 0)//读完所有帧:re<0
			break;

		//要是不写下面的直接报错!!!
		//接下来的pkt开头的代码(三段代码很像,就是参数不同)作用是:调试时间基准:time_base,让输入的视频与输出的视频时间对应一致
		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)//(AVRounding)是强转的意思,不整除时取临界值
			);
		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);//写入一帧:与read_frame对应
		av_packet_unref(&pkt);//成对编程:与读取一帧写入对应,防止内存泄漏
		cout << "帧";//每读一帧,打印一个"帧"
	}
	av_write_trailer(oc);//写入尾部索引,否则时长为0
	avio_close(oc->pb);//成对编程:与第五步写入头部对应,才能正常输出
	cout << endl;
	cout <<"——运行成功,程序结束——" << endl;
	getchar();
	return 0;
}


  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-13 09:05:31  更:2021-09-13 09:06:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 21:34:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码