音視頻應用場景:
- 直播類:音視頻會議侵俗、教育直播、娛樂/游戲直播等
- 短時頻:抖音丰刊、快手隘谣、小咖秀
- 網(wǎng)絡視頻:優(yōu)酷、騰訊視頻啄巧、愛奇藝
- 音視頻通話:微信寻歧、QQ、Skype等
- 視頻監(jiān)控
- 人工智能:人臉識別秩仆、智能音箱等码泛,更關注算法。
一. FFmpeg日志
3個步驟:
- 包含include <libavutil/log.h>
- 設置打印級別:av_log_set_level(AV_LOG_DEBUG)
- 打印函數(shù):av_log(NULL, AV_LOG_INFO, "...%s\n", p)
常用日志級別由高到低:
- AV_LOG_ERROR
- AV_LOG_WARNING
- AV_LOG_INFO
- AV_LOG_DEBUG
實例展示澄耍,建一個ffmpeg_log.c文件
#include<stdio.h>
#include<libavutil/log.h>
int main(int argc, char* argv[]){
av_log_set_level(AV_LOG_DEBUG);
av_log(NULL, AV_LOG_INFO, "Hello world: %s!\n", "shenfeng");
return 0;
}
編譯該c文件:
clang -g -o ffmpeg_log ffmpeg_log.c -lavutil
運行:
./ffmpeg_log
PKG_CONFIG_PATH環(huán)境變量的設置
pkg-config
命令可以到 PKG_CONFIG_PATH 指定的路徑下找指定庫的 .pc 文件噪珊,然后從.pc 文件中拿到需要的庫路徑,名稱以及頭文件齐莲。比如執(zhí)行:
clang -g -o test test.c `pkg-config --cflags --libs libavformat`
相當于執(zhí)行:
clang -g -o ffmpeg_del ffmpeg_file.c -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavformat
可以通過 pkg-config 找到需要的庫路徑和頭文件痢站,也可以單獨執(zhí)行查看是否有該 pkg-config 的配置,沒有的話找不到相應頭文件:
pkg-config --libs libavutil
Package libavutil was not found in the pkg-config search path.
Perhaps you should add the directory containing `libavutil.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavutil' found
需要配置PKG_CONFIG_PATH環(huán)境變量:
#ffmpeg
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/ffmpeg/lib/pkgconfig
#libssl
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opt/openssl/lib/pkgconfig
保存退出再執(zhí)行以下命令讓設置立即生效:
source ~/.bash_profile
二. 文件的刪除與重命名
1. 刪除
avpriv_io_delete()
編譯語句:
clang -g -o ffmpeg_del ffmpeg_file.c `pkg-config --libs libavformat`
ffmpeg_file.c文件代碼如下:
2. 重命名
avpriv_io_move()
編譯語句:
clang -g -o ffmpeg_del ffmpeg_file.c `pkg-config --libs libavformat`
ffmpeg_file.c文件代碼如下:
三. 操作目錄的函數(shù)
核心函數(shù):
avio_open_dir()
avio_read_dir()
avio_close_dir()
相關類:
- AVIODirContext:操作目錄的上下文
- AVIODirEntry:目錄項选酗,用于存放文件名阵难、文件大小等信息
實戰(zhàn):實現(xiàn)一個ls命令。
1. 新建一個ffmpeg_list.c文件
#include <libavutil/log.h>
#include <libavformat/avformat.h>
int main (int argc, char* argv[]) {
int res;
AVIODirContext *ctx = NULL;
AVIODirEntry *entry = NULL;
av_log_set_level(AV_LOG_INFO);
res = avio_open_dir(&ctx, "./", NULL);
if (res < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't open dir:%s\n", av_err2str(res));
goto __fail;
}
while (1) {
res = avio_read_dir(ctx, &entry);
if (res < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't read dir: %s\n", av_err2str(res));
goto __fail;
}
if (!entry) {
break;
}
av_log(NULL, AV_LOG_INFO, "%12"PRId64" %s \n", entry -> size, entry -> name);
avio_free_directory_entry(&entry);
}
__fail:
avio_close_dir(&ctx);
return 0;
}
其中芒填,PRld:是一種跨平臺的書寫方式呜叫,主要是為了通知支持32位和64位操作系統(tǒng)。PRld64表示64位整數(shù)殿衰,在32位系統(tǒng)中表示long long int怀偷,在64位系統(tǒng)中表示long int:
printf("%" "ld" "\n", value);
printf("%" "lld" "\n", value);
2. 編譯
clang -g -o list ffmpeg_list.c `pkg-config --libs libavformat libavutil`
四. 處理數(shù)據(jù)流的基本概念
1. 多媒體文件的基本概念
- 多媒體文件其實是個容器。
- 在容器里有很多流(Stream/Track)播玖。
- 每種流是由不同的編碼器編碼的椎工,比如音頻mp3,視頻H264蜀踏、H265等等维蒙。
- 從流中讀出的數(shù)據(jù)稱為包。
- 在一個包中包含著一個或多個幀果覆。
2. 幾個重要的結構體
- AVFormatContext:格式上下文颅痊,連接api間的橋梁,多媒體文件的信息會存在這個結構體中局待,用來在調用不同api時辨別是哪個多媒體文件斑响。
- AVStream:通過此結構體可以讀取流菱属。
- AVPacket:通過它獲取數(shù)據(jù)包。
3. FFmpeg 操作流數(shù)據(jù)的基本步驟
總結:多媒體文件是個容器舰罚,里面包含了許多流纽门,如音頻、視頻营罢、字幕等等赏陵,通過解復用獲取流,流中讀取出數(shù)據(jù)包饲漾,數(shù)據(jù)包中存著一個或多個被壓縮的數(shù)據(jù)幀蝙搔。