由于如今的工作比以前忙了,已经有好些日子没有分享技术博文了,还是得继续坚持下去。鉴于如今视频直播如此火爆,那就选个主题,聊聊播放器、聊聊 FFMPEG 那些事吧。
FFMPEG 是个好东西,可以说目前市面上的任何一款”通用型”播放器,都离不开 FFMPEG,因为没有什么其他的库比它支持的格式更加全面了。
这里首先致敬一下雷神,博客地址:《雷霄骅的专栏》,分享了很多音视频方面的技术文章、开源代码以及 FFMPEG 源码的分析,无论对入门者还是资深开发,都有很大的价值。
我要写的主题,与雷神不同,我会测重介绍使用 FFMPEG 开发播放器过程中的一些比较基础的小经验或者说开发笔记,因此,使用 Tips 这个单词,意味小技巧、小帖士,因此,本系列的目标读者是 FFMPEG 的入门者,也欢迎路过的高手们能对分享的内容给出宝贵的建议和意见。
本文则从开发和调试程序最重要的一点:打 LOG 说起,看看基于 FFMPEG 开发,如何打印 LOG,如何设置日志的级别。
- FFMPEG 打印日志的函数
FFMPEG 有一套自己的日志系统,它使用 av_log() 函数来打印日志,其声明位于:
它的函数原型如下:
参数含义:
avcl:指定一个包含 AVClass 的结构体,指定该 log 所属的结构体,如 AVFormatContext、AVCodecContext 等等,可以设置为 NULL
level:log 的级别,下面给出可选的值
fmt:跟 c 语言的 printf() 定义一样
- FFMPEG 日志级别
LOG 的级别是一个 int 类型,其可选的数值及其含义如下:
- FFMPEG 设置和获取当前日志级别
由一个全局的变量来控制哪个级别及以上的日志会打印输出,设置和获取这个全局变量的函数如下:
例如,当全局的日志级别设置为 AV_LOG_ERROR
,那么凡是日志级别高于 AV_LOG_ERROR
的日志,都不会被打印出来。
- FFMPEG 日志打印函数的使用示例
假设要打印 DEBUG 和 ERROR 级别的日志,用法示例如下:
- FFMPEG 日志打印函数的封装
当然,如果你觉得 av_log 用起来不是很顺手,你可以定义个宏封装下,例如:
- Android 中打印 FFMPEG 的日志
由于 FFMPEG 默认使用的是 printf 来打印日志,而 Android 系统有着一套自己的 LOG 系统,因此,需要让 FFMPEG 的日志重定向使用 Android 的日志系统,具体方法描述如下:
通过 FFMPEG 的 av_log_set_callback() 注册一个 LOG callback function,FFMPEG 就会把 LOG 打印功能重定向到 callback function 中,代码示例如下:
在代码初始化的地方调用一下 syslog_init() 后,就可以使用 av_log() 在 Android 平台输出调试日志了。
- FFPlay 设置日志级别
平时自己写的播放器播放某些流播放有问题的话,也可以使用 ffplay 来对比调试一下,看看使用 ffplay 是否可以播放,报错信息是什么,ffplay 打开 DEBUG 日志输出的方法示例如下:
-v 参数是用于配制 ffplay 的日志级别,其定义如下:
- 小结