1、背景
FFmpeg 是音视频开发中最常用到的开源软件,许多商业软件都以 FFmpeg 为基础进行开发定制。 由于近期工作中的项目涉及到了音视频相关开发,本系列文章用来整理和记录在使用 FFmpeg 开发过程中的一些学习经验,以备之后的查阅。
2、视频播放基本原理
上图来源于网上,描述了视频播放的基本原理。即:要实现一个视频播放器,需要完整实现上图中的每一个过程。 本文先从打开视频文件开始,记录怎么使用 FFmpeg 打开一个视频文件。
3、打开视频文件
3.1 概述
在进行音视频解码之前,需要先打开媒体文件,以获取其中包含的音/视频流的相关信息。打开音视频文件包含以下步骤:
3.2 创建 FFmpegPlayer 类
C++音视频学习资料免费获取方法:关注音视频开发T哥,点击「链接」即可免费获取2023年最新C++音视频开发进阶独家免费学习大礼包!
创建一个 FFmpegPlayer 类用于对相关资源进行管理:
class FFmpegPlayer {
public:
explicit FFmpegPlayer(const char* m_url);
~FFmpegPlayer();
public:
bool openFile();//打开文件
private:
std::string url;//文件路径
AVFormatContext* formatContext = nullptr;//封装格式上下文
};
实现 openFile 接口:
bool FFmpegPlayer::openFile() {
// 创建 formatContext
formatContext = avformat_alloc_context();
if( !formatContext )
{
avformat_close_input(&formatContext);
return false;
}
// 打开文件
if (avformat_open_input(&formatContext, url.c_str(), nullptr, nullptr) != 0)
{
if( !formatContext ) {
avformat_close_input(&formatContext);
}
return false;
}
// 查找输入流信息
if (avformat_find_stream_info(formatContext, nullptr) < 0)
{
if( !formatContext ) {
avformat_close_input(&formatContext);
}
return false;
}
// 查找音视频流索引
int video_index = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
int audio_index = av_find_best_stream(formatContext, AVMEDIA_TYPE_AUDIO, -1, video_index, nullptr, 0);
//打印视频信息
std::cout <<"视频流索引:" << video_index <<std::endl;
std::cout <<"音频流索引:" << audio_index<<std::endl;
std::cout <<"时长:"<< formatContext->duration / AV_TIME_BASE <<std::endl;
std::cout <<"视频宽度:" << formatContext->streams[video_index]->codecpar->width << std::endl;
std::cout <<"视频高度:" << formatContext->streams[video_index]->codecpar->height << std::endl;
auto frame_rate = av_guess_frame_rate(formatContext, formatContext->streams[video_index], nullptr);
std::cout <<"帧率:" << (double )frame_rate.num / frame_rate.den << std::endl;
return true;
}
3.3 运行示例
传入视频文件路径,打开文件:
#include "FFmpegPlayer.h"
int main() {
const char * url = "C:\\Users\\111111\\Desktop\\ts\\0.ts";
FFmpegPlayer * player = new FFmpegPlayer(url);
if( player->openFile())
{
std::cout << "文件打开成功!"<<std::endl;
}
return 0;
}
代码运行结果如下:
原文链接:FFmpeg 入门学习 01--打开视频文件