天天看點

【音視訊連載-011】第二季 FFmpeg 一層一層擷取檔案資訊資訊擷取avformat_alloc_contextavformat_open_inputavformat_find_stream_infoav_dump_format資訊檢視總結

作者:星隕

來源:

音視訊開發進階

首先準備一個檔案,用指令行來檢視它的基本資訊。

檔案位址如下:

https://github.com/glumes/av-beginner/blob/master/resource/video/video-avi-320x320.avi

這個檔案很有意思,它的内容是一個時鐘,每隔一秒,秒針都會跳動,同時還會發出滴答的聲音,很友善後續做音視訊同步處理。

執行指令如下:

ffmpeg -i your_file_path

得到的結果如下圖:

【音視訊連載-011】第二季 FFmpeg 一層一層擷取檔案資訊資訊擷取avformat_alloc_contextavformat_open_inputavformat_find_stream_infoav_dump_format資訊檢視總結

從圖中擷取如下的資訊:

  • 視訊時長 duration 為 12s
  • 開始時間點 start 0s
  • 比特率 bitrate 42 kb/s

另外,還可以得出該檔案有兩路流,一路視訊,一路音頻。

以上這些資訊都可以在一個叫

AVFormatContext

的結構體中得到。

除此之外,還可以看到該視訊檔案的分辨率是

320x320

,音頻采樣率是

8000Hz

,以上資訊需要通過一個叫

AVCodecContext

的結構體去獲得。

資訊擷取

本篇文章就講一講如何獲得

AVFormatContext

并檢視它的資訊。

核心代碼很簡單如下:

// 聲明并初始化 AVFormatContext
    AVFormatContext * fmt_ctx = avformat_alloc_context();

    int ret = RET_OK;
    
    // 打開檔案
    if ((ret = avformat_open_input(&fmt_ctx, filename, nullptr, nullptr)) < 0) {
        logE( "Cannot open input file");
        return ret;
    }
    
    // 擷取檔案流相關資訊
    if ((ret = avformat_find_stream_info(fmt_ctx, nullptr)) < 0) {
        logE("Cannot find stream information");
        return ret;
    }           

隻有三個簡單的函數調用:

avformat_alloc_context

作用如下:

  • 用來初始化 AVFormatContext 結構體的
  • 要配套使用 avformat_free_context 來釋放

avformat_open_input

  • 打開輸入檔案,通過讀取檔案頭 AVFormatContext 就已經能夠擷取部分資訊了,比如檔案位址、檔案封裝格式、有多少路流等等。
  • 但是更多詳細資訊還需要通過其他方法來擷取,比如流資訊
  • 要配套使用 avformat_close_input 來關閉檔案,并且要在 avformat_free_context 之前調用,否則就出問題了。

avformat_find_stream_info

  • 探測得到視訊檔案的具體流資訊。

av_dump_format

  • 通過改方法可以列印相關的檔案資訊,它的輸出和 FFmpeg 指令行輸出的内容基本一樣。

具體使用:

av_dump_format(mFormatContext,0,filename,0);           

最後要進行相關結構體的釋放,不要忘了釋放的順序。

avformat_close_input(&mFormatContext);
avformat_free_context(mFormatContext);           

資訊檢視

當運作成功後,就可以檢視

AVFormatContext

包含的具體資訊了。

先通過 CLion 的

Structure

工具檢視

AVFormatContext

具體包含哪些資訊。

【音視訊連載-011】第二季 FFmpeg 一層一層擷取檔案資訊資訊擷取avformat_alloc_contextavformat_open_inputavformat_find_stream_infoav_dump_format資訊檢視總結
在 Android Studio 中也可以這樣進行檢視,友善快速閱讀源碼。

然後就可以通過打 Log 或者斷點的方式檢視運作後的具體某個資料是否符合預期了。

以下是通過斷點的方式:

【音視訊連載-011】第二季 FFmpeg 一層一層擷取檔案資訊資訊擷取avformat_alloc_contextavformat_open_inputavformat_find_stream_infoav_dump_format資訊檢視總結

以下是通過打 Log 的方式:

logI("file path is %s", mFormatContext->filename);
    logI("iformat name is %s", mFormatContext->iformat->name);
    logI("nb_streams is %d", mFormatContext->nb_streams);
    logI("bitrate is %lld", mFormatContext->bit_rate);
    logI("duration is %lld", mFormatContext->duration);
    logI("start time is %lld",mFormatContext->start_time);           

列印的結果如下:

[av-beginner]: iformat name is avi
 [av-beginner]: nb_streams is 2
 [av-beginner]: bitrate is 42912
 [av-beginner]: duration is 12000000
 [av-beginner]: start time is 0           

可以看到和通過指令行顯示的内容基本一緻,除了在比特率上在有着些許誤差,總的來說符合預期。

想要看更多資訊的話,自己也可以去列印或者斷點檢視。

總結

以上就是音視訊基礎學習連載的

011

篇。

通過代碼來檢視檔案資訊,資訊都存儲在

AVFormatContext

的各個字段上,隻是通過一些方法去擷取、填充這些字段。

後面會繼續講到如何建立和擷取

AVCodecContext

,敬請期待~~~

本文具體代碼見倉庫:

https://github.com/glumes/av-beginner

倉庫的代碼會比文章提前更新,想要搶先知道後續内容,就關注代碼吧,歡迎 star 。

能力有限,文中有不對之處,歡迎加我微信 ezglumes 進行交流~~

FFmpeg 系列文章
「視訊雲技術」你最值得關注的音視訊技術公衆号,每周推送來自阿裡雲一線的實踐技術文章,在這裡與音視訊領域一流工程師交流切磋。
【音視訊連載-011】第二季 FFmpeg 一層一層擷取檔案資訊資訊擷取avformat_alloc_contextavformat_open_inputavformat_find_stream_infoav_dump_format資訊檢視總結

繼續閱讀