用FFmpeg获取视频流+音频流的信息(编码格式、分辨率、帧率、播放时长...)

我们经常需要知道一个媒体文件所包含的媒体流的信息,比如文件格式、播放时长、码率、视音频编码格式,视频分辨率,帧率,音频属性等信息。如何使用FFmpeg API获取这些信息呢?下面我会给出一个完善的类,这个类封装了FFmpeg读取文件信息的相关的API,读者只需要调类的方法就可以获得相关的信息。

这个类能够读取媒体文件的哪些信息呢?假如我们给出一个媒体文件(MP4,AVI,MKV。。。),里面至少要包含一个音频轨或视频轨,则调用该类的方法可以获得的信息如下:

  • 媒体容器封装格式
  • 文件播放时长
  • 文件平均码率(视频+音频)
  • 视频属性(编码器名称、视频分辨率、帧率、视频帧数、编码码率)
  • 音频属性(编码器名称、采样率、声道数、编码码率)

我自己写了一个工具来调用这个类,能够批量获取一个目录里的媒体文件的信息,看下图:

(这个工具的源码读者可以从我的资源里下载)

下面先附上这个类(FFMediaInfoReader)的代码,后面再逐个部分讲解一下。

类头文件代码:

#ifndef _FFMediaInfoReader_H
#define _FFMediaInfoReader_H

#include <string>
using namespace std;

#ifdef __cplusplus
extern "C" {
#endif 

#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif

#include "./include/libavcodec/avcodec.h"
#include "./include/libavutil/mathematics.h"
#include "./include/libavutil/avutil.h"
#include "./include/libswscale/swscale.h"
#include "./include/libavutil/fifo.h"
#include "./include/libavformat/avformat.h"
#include "./include/libavutil/opt.h"
#include "./include/libavutil/error.h"
#include "./include/libavutil/pixfmt.h"
#include "./include/libswresample/swresample.h"  
#ifdef __cplusplus
}
#endif

#pragma comment( lib, "avcodec.lib")
#pragma comment( lib, "avutil.lib")
#pragma comment( lib, "avformat.lib")
#pragma comment(lib, "swresample.lib")
#pragma comment( lib, "swscale.lib" )

#define PIX_FMT_BGR24    AV_PIX_FMT_BGR24
#define PIX_FMT_YUV420P  AV_PIX_FMT_YUV420P

#define nullptr NULL

class FFMediaInfoReader
{
public:
    FFMediaInfoReader();
    virtual ~FFMediaInfoReader();

    BOOL OpenFileStream(const char* szFilePath);
    void CloseFileStream();

	//获取视频分辨率
	void GetVideoSize(int & width, int & height) 
	{
		width  = m_width;
		height = m_height;
	}

	string GetMediaFormatName(); //获取媒体封装格式描述

	//获取媒体轨道数目
	int    GetTrackNum()
	{
		int n = 0;

		if(HasVideoTrack())
			n += 1;
		if(HasAudioTrack())
			n += 1;
		return n;
	}

	//是否有视频流
	bool    HasVideoTrack()
	{
		if( m_videoStreamIndex == -1)
			return false;

		if(m_width > 0 && m_height > 0)
			return true;

		return false;
	}

	//是否有音频流
	bool    HasAudioTrack()
	{
		if(m_audioStreamIndex == -1)
			return false;

		return true;
	}

	//获取视频帧数
	int  GetVideoFrameNumber()
	{
		return m_video_frame_count;
	}

	//获取文件总的码率
	int GetFormatBitrate()
	{
		if(m_inputAVFormatCxt == NULL)
			return -1;

		return m_inputAVFormatCxt->bit_rate;
	}

	//文件播放时长(单位:秒)
	int  GetFileDuration()
	{
		if(m_inputAVFormatCxt == NULL)
			return -1;

		return (m_inputAVFormatCxt->duration)/1000000; //以微秒为单位,转换为秒为单位
	}

	string GetVideoCodecName()
	{
		return m_vcodec_name;
	}

	string GetAudioCodecName()
	{
		return m_acodec_name;
	}

private:
 
    BOOL openMediaFile();
    void closeMediaFile();

private:

    string m_filePath;

    AVFormatContext* m_inputAVFormatCxt;

	int m_videoStreamIndex;
	int m_audioStreamIndex;

	string   m_vcodec_name;
	string   m_acodec_name;

    char m_tmpErrString[64];
    bool m_stop_status;

	BOOL   m_bInited;

	int m_width, m_height; //视频分辨率
    int   m_video_frame_count; //视频总帧数
	int   m_frame_rate; //视频帧率

	int  m_audio_samplerate;
	int  m_audio_channels;
   
};

#endif // _FFMediaInfoReader_H

源文件代码:

#include "stdafx.h"
#include "FFMediaInfoReader.h"
#include <sstream>
//#include <mmsystem.h>

string to_string(int n)
{
	std::ostringstream stm;
	string str;
	stm << n;
	str = stm.str();
	//std::cout << str << std::endl;
	return str;
}


//

FFMediaInfoReader::FFMediaInfoReader()
{
    m_stop_status 
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值