播放器实战05 avformat_find_stream_info探测获取封装上下文的格式信息并打印

1.这个函数做了什么?

avformat_find_stream_info主要是读一些包(packets ),然后从中提取出流的信息。有一些文件格式没有头,这个时候,这个函数就很有用,因为它可以从读取到的包中获得到流的信息。在MPEG-2重复帧模式的情况下,该函数还计算真实的帧率。
该函数将读取媒体文件的音视频包去获取流信息。本函数常用于avformat_open_input()函数之后,在avformat_open_input()函数中会调用输入文件格式的read_header()函数,比如flv格式的flv_read_header()函数来读取文件头,由于flv格式的头很简单,只能知道是否存在音频流和视频流,获取不到流的编码信息,因此,对于flv格式来说,本函数就非常重要,本函数会读取flv文件中的音视频包,从这些包中获知流的编解码信息。对于没有文件头的MPEG格式来说存在同样的情况

2.代码

#include<iostream>

extern "C"
{
#include "libavformat/avformat.h" //头文件不仅要在项目中鼠标点击配置,在代码中也要引入

}
using namespace std;
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")

int main(int argc, char* argv[])
{
	const char* path = "E:\\ffmpeg\\test.mp4";
	cout << "TEST DEMUX" << endl;

	//初始化封装库
	//av_register_all()被弃用了

	AVDictionary* opts = NULL;//参数设置,比如rtsp的延时时间
	av_dict_set(&opts, "rtsp_transport", "tcp", 0);//设置rtsp流以tcp协议打开
	av_dict_set(&opts, "max_delay", "500", 0);//网络延迟时间

	//初始化网络库(可以打开rtsp,rtmp,http协议的流媒体视频)
	avformat_network_init();

	//解封装上下文
	AVFormatContext* ic = NULL;//将其地址做为输入,会申请一块空间,将这块空间的地址赋给ic
	//解封装上下文AVFormatContext,是存储音视频封装格式中包含信息的结构体。

	int re = avformat_open_input(&ic, path, 0, &opts);//0表示自动选择解封装器,设置一个返回值知道有无错误
	
	if (re != 0)
	{
		char buf[1024] = { 0 };
		av_strerror(re, buf, sizeof(buf) - 1);
		cout << "open" << path << "failed!:" << buf << endl;
		getchar();
		return -1;
	}
	cout << "open " << path << " success!" << endl;

	//获取流信息
	re = avformat_find_stream_info(ic, 0);

	//总时长 
	int total = ic->duration /(AV_TIME_BASE / 1000);//毫秒
	cout << "total ms =" << total << endl;

	//视频流详细信息
	av_dump_format(ic,1,"2",0);



	if (ic)
	{
		//释放封装上下文,并且把ic置0
		avformat_close_input(&ic);
	}
	getchar();
	return 0;
}

}

int re = avformat_open_input(&ic, path, 0, &opts);
re = avformat_find_stream_info(ic, 0);
虽然返回值都是re,但是re只是一个标志位,用于判断过后可以继续使用,没有再去开辟一个变量,节省了空间,我们想要的是将指针(ic)传进去,让ic指向开辟的空间,该空间放的是结构体AVformatcontext,里面有视频的相关信息。
有些格式,比如MP4,
在int re = avformat_open_input(&ic, path, 0, &opts);中就能获得全部的格式信息。
但也有些格式,比如flv,
格式信息不在头索引文件中,在下面视频流中存放视频格式信息

总时长有时候会存放两份,在AVformatcontext中会存放,在流信息AVstream中也会存放
总时长 duration:经历时长,不是以秒或者毫秒为单位,而是以AV_TIME_BASE为单位,duration /(AV_TIME_BASE / 1000),除出来的结果为秒

3.结果

av_dump_format(ic,1,“2”,0); 1 和"2"为显示出来的东西,无影响,最后的0表示input。
在这里插入图片描述
5.使用flv文件
未读取流信息:
int re = avformat_open_input(&ic, path, 0, &opts);在这里插入图片描述
读取流信息:
int re = avformat_open_input(&ic, path, 0, &opts);
re = avformat_find_stream_info(ic, 0);
在这里插入图片描述
观察可以发现FLV文件中的duration和比特率参数在流信息中放着在。

补充:https://blog.csdn.net/h514434485/article/details/77802382

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值