天天看點

FFmpeg 入門學習 01--打開視訊檔案

1、背景

FFmpeg 是音視訊開發中最常用到的開源軟體,許多商業軟體都以 FFmpeg 為基礎進行開發定制。 由于近期工作中的項目涉及到了音視訊相關開發,本系列文章用來整理和記錄在使用 FFmpeg 開發過程中的一些學習經驗,以備之後的查閱。

2、視訊播放基本原理

FFmpeg 入門學習 01--打開視訊檔案

上圖來源于網上,描述了視訊播放的基本原理。即:要實作一個視訊播放器,需要完整實作上圖中的每一個過程。 本文先從打開視訊檔案開始,記錄怎麼使用 FFmpeg 打開一個視訊檔案。

3、打開視訊檔案

3.1 概述

在進行音視訊解碼之前,需要先打開媒體檔案,以擷取其中包含的音/視訊流的相關資訊。打開音視訊檔案包含以下步驟:

FFmpeg 入門學習 01--打開視訊檔案

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--打開視訊檔案

原文連結:FFmpeg 入門學習 01--打開視訊檔案

繼續閱讀