[音视频开发]FFmpeg基本使用及实战操作

音视频应用场景:

  • 直播类:音视频会议、教育直播、娱乐/游戏直播等
  • 短时频:抖音、快手、小咖秀
  • 网络视频:优酷、腾讯视频、爱奇艺
  • 音视频通话:微信、QQ、Skype等
  • 视频监控
  • 人工智能:人脸识别、智能音箱等,更关注算法。

一. FFmpeg日志

3个步骤:

  • 包含include <libavutil/log.h>
  • 设置打印级别:av_log_set_level(AV_LOG_DEBUG)
  • 打印函数: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环境变量的设置

pkg-config 命令可以到 PKG_CONFIG_PATH 指定的路径下找指定库的 .pc 文件,然后从.pc 文件中拿到需要的库路径,名称以及头文件。比如执行:

 clang -g -o test test.c `pkg-config --cflags --libs libavformat`

相当于执行:

clang -g -o ffmpeg_del ffmpeg_file.c -I/usr/local/ffmpeg/include  -L/usr/local/ffmpeg/lib -lavformat

可以通过 pkg-config 找到需要的库路径和头文件,也可以单独执行查看是否有该 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环境变量:

#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

保存退出再执行以下命令让设置立即生效:

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文件代码如下:

三. 操作目录的函数

核心函数:

avio_open_dir() 
avio_read_dir()
avio_close_dir()

相关类:

  • AVIODirContext:操作目录的上下文
  • AVIODirEntry:目录项,用于存放文件名、文件大小等信息

实战:实现一个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位操作系统。PRld64表示64位整数,在32位系统中表示long long int,在64位系统中表示long int:

printf("%" "ld" "\n", value); 
printf("%" "lld" "\n", value); 

2. 编译
clang -g -o list ffmpeg_list.c `pkg-config --libs libavformat libavutil`

四. 处理数据流的基本概念

1. 多媒体文件的基本概念
  • 多媒体文件其实是个容器。
  • 在容器里有很多流(Stream/Track)。
  • 每种流是由不同的编码器编码的,比如音频mp3,视频H264、H265等等。
  • 从流中读出的数据称为包。
  • 在一个包中包含着一个或多个帧。
2. 几个重要的结构体
  • AVFormatContext:格式上下文,连接api间的桥梁,多媒体文件的信息会存在这个结构体中,用来在调用不同api时辨别是哪个多媒体文件。
  • AVStream:通过此结构体可以读取流。
  • AVPacket:通过它获取数据包。
3. FFmpeg 操作流数据的基本步骤

总结:多媒体文件是个容器,里面包含了许多流,如音频、视频、字幕等等,通过解复用获取流,流中读取出数据包,数据包中存着一个或多个被压缩的数据帧。

五. FFmpeg实战

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容