為了加深大家的印象,每篇FFmpeg初級(jí)開發(fā)的文章開頭會(huì)出現(xiàn)FFmpeg的代碼結(jié)構(gòu)和初級(jí)開發(fā)我們的學(xué)習(xí)大綱,
FFmpeg的代碼結(jié)構(gòu):
libavcodec: 編碼器的實(shí)現(xiàn)
libavformat: 流協(xié)議,容器格式及基本IO訪問的實(shí)現(xiàn)
libavfilter:音視頻過濾器
libavutil:hash器,解碼器和各種工具函數(shù)
libavdevice:訪問捕獲設(shè)備和回訪設(shè)備的借口
libswresample:實(shí)現(xiàn)混音和重采樣
libswscale:實(shí)現(xiàn)色彩轉(zhuǎn)換和縮放功能
FFmpeg初級(jí)開發(fā)包括:
1. FFmpeg日志Log;
2. FFmpeg文件操作;
3. FFmpeg目錄操作;
4. FFmpeg Meta信息;
5. FFmpeg抽取音頻數(shù)據(jù);
6. FFmpeg抽取視頻H264數(shù)據(jù);
7. FFmpeg格式轉(zhuǎn)換;
8. FFmpeg音視頻裁剪。
上一篇文章我們講解了FFmpeg文件目錄的操作并且編寫了一個(gè)模仿ls功能的小程序,今天我們來講一下如何打印音視頻的Meta信息
通過本篇文章的學(xué)習(xí),你可以打印出一個(gè)視頻文件的視頻流信息,包括時(shí)長,幀率,碼率,分辨率等信息;音頻流的編碼,采樣率,聲道等信息。
那么打印Meta信息主要用到的函數(shù)為:
av_register_all(); // 獲取所有的格式,協(xié)議等信息到程序中
// 打開一個(gè)多媒體文件,并且將這個(gè)多媒體文件的信息保存到AVFormatContext這樣一個(gè)上下文中
// 第一個(gè)參數(shù):一個(gè)上下文,用來存儲(chǔ)當(dāng)前多媒體文件所有的信息
// 第二個(gè)參數(shù):要打開的多媒體文件名
// 第三個(gè)參數(shù):要指定的格式,如果不需要特殊指定會(huì)根據(jù)第二個(gè)參數(shù)的文件格式來指定,這個(gè)就可以填NULL
// 第四個(gè)參數(shù):命令行的參數(shù),一般為NULL
int avformat_open_input ( AVFormatContext ** ps,
const char * url,
AVInputFormat * fmt,
AVDictionary ** options
)
// 關(guān)閉這個(gè)多媒體文件,釋放資源
// 參數(shù):上下文,用來告訴程序需要釋放那個(gè)多媒體文件資源
void avformat_close_input ( AVFormatContext ** s )
AVFormatContext // 上下文,用來存儲(chǔ)多媒體文件的音視頻信息
那么下面是我們使用上面的函數(shù)和結(jié)構(gòu)體做的一個(gè)小程序,獲取一個(gè)mp4文件的音視頻信息:
#include<libavutil/log.h>
#include<libavformat/avformat.h>
#include<stdio.h>
int main(int argc, char* argv[]){
int result;
AVFormatContext *fmt_cxt = NULL;
// log打印級(jí)別是INFO及以上
av_log_set_level(AV_LOG_INFO);
// 獲取所有的協(xié)議和格式信息
av_register_all();
// 獲取輸入信息,第一個(gè)參數(shù):上下文地址,第二個(gè)參數(shù):文件,第三個(gè)參數(shù):文件的格式,如果不需要特殊指定就為NULL,第四個(gè)參數(shù):命令行參數(shù),一般設(shè)為NULL
result = avformat_open_input(&fmt_cxt, "./demo.mp4", NULL, NULL);
if(result < 0){
av_log(NULL, AV_LOG_ERROR, "Cant open input file: %s!", av_err2str(result));
return -1;
}
// 打印demo.mp4音視頻信息,第一個(gè)參數(shù):format上下文,第二個(gè)參數(shù):index序號(hào),第三個(gè)參數(shù):文件名,第四個(gè)參數(shù):輸入流為0,輸出流為1
av_dump_format(fmt_cxt, 0, "./demo.mp4", 0);
avformat_close_input(&fmt_cxt);
return 0;
}
運(yùn)行之后的結(jié)果就是:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from './demo.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.71.100
description : Codec by Bilibili XCode Worker v4.6.27(fixed_gap:False)
Duration: 00:05:49.40, bitrate: N/A
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), none, 426x240, 194 kb/s, 25 fps, 25 tbr, 16k tbn (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, 1 channels, 32 kb/s (default)
Metadata:
handler_name : SoundHandler
Input#0:是音視頻的index序號(hào)。
Stream #0:0:第一個(gè)0代表輸入流,如果是輸出流那么就是1;第二個(gè)0代表視頻。
Stream #0:1:第一個(gè)0代表輸入流,如果是輸出流那么就是1;第二個(gè)1代表音頻。
從Duration開始是比較重要的信息,我們可以看到這個(gè)視頻的時(shí)長是"00:05:49.40",視頻的格式是h264,分辨率是426x240,幀率25fps;音頻的格式是aac,采樣率是48000Hz,單聲道等。
這樣我們就可以獲取這些信息,將來放到App中方便用戶查看。