当前位置: 首页 > news >正文

【音视频连载-010】第二季 FFmpeg 日志打印

公众号回复:OpenGL,领取学习资源大礼包

音视频学习入门技术文章连载:

  • 技术开发故事会连载

  • 【音视频连载-001】基础学习篇-SDL 介绍以及工程配置

  • 【音视频连载-002】基础学习篇-SDL 创建窗口并显示颜色

  • 【音视频连载-003】基础学习篇-SDL 消息循环和事件响应

  • 【音视频连载-004】基础学习篇-SDL 加载图片并显示

  • 【音视频连载-005】基础学习篇-SDL 加载 YUV 文件并显示

  • 【音视频连载-006】基础学习篇-SDL 播放 YUV 视频文件

  • 【音视频连载-007】基础学习篇-SDL 播放 PCM 音频文件(上)

  • 【音视频连载-008】基础学习篇-SDL 播放 PCM 音频文件(下)

  • 【音视频连载-009】第二季 FFmpeg 打造简易播放器

﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌﹌

音视频连载系列已经停更一段时间,再这么停下去估计就要掉粉了,捡起来继续更新~~~

接下来主要是讲解 FFmpeg 相关的内容,比如这篇就从简单的日志打印开始说起。

日志打印基础使用

在 FFmpeg 中提供了 av_log() 方法去打印日志,它的函数声明如下:

void av_log(void *avcl, int level, const char *fmt, ...)

其中 level 参数指的是日志级别,后面的 fmt... 代表日志内容,和调用 print 打印信息一样。

具体使用如下:

av_log(nullptr,AV_LOG_INFO,"this is INFO log color");
av_log(nullptr,AV_LOG_DEBUG,"this is DEBUG log color");
av_log(nullptr,AV_LOG_WARNING,"this is WARNING log color");
av_log(nullptr,AV_LOG_ERROR,"this is ERROR log color");

与 Android 日志类似,FFmpeg 也有多种级别的日志。

#define AV_LOG_FATAL     8
#define AV_LOG_ERROR    16
#define AV_LOG_WARNING  24
#define AV_LOG_INFO     32
#define AV_LOG_VERBOSE  40
#define AV_LOG_DEBUG    48
#define AV_LOG_TRACE    56

看到 INFODEBUGERROR 这些级别是不是有似曾相识的感觉。

这些数值都是 8 的倍数,按照从小到大的顺序递增。

日志打印级别设置

在 FFmpeg 中可以设置和获取当前日志打印的级别。

// 设置日志打印级别
void av_log_set_level(int level);
// 获取日志打印级别
int av_log_get_level(void);

比如设置了当前级别是 AV_LOG_INFO ,那么凡是级别低于它的都不会打印出来了。

那么什么级别算是更低的呢?数字越小的级别越高,数字越大的级别越低。

比如设置了 AV_LOG_INFO 级别,它的值是 32 ,那么 AV_LOG_DEBUG 级别的日志就不会打印,它的值是 48 ,级别更低。而 AV_LOG_ERROR 就会被打印,它的值是 16 ,级别更高。

自定义日志打印

在 FFmpeg 中可以通过 av_log_set_callback 函数来注册一个日志回调,在回调中自定义日志打印方式。

av_log_set_callback 的函数声明如下:

void av_log_set_callback(void (*callback)(void*, int level, const char* fmt, va_list));

它的参数是传一个函数指针,其中 level 指定了日志回调的级别,根据不同级别做不同操作,fmtva_list 就是回调的日志内容了,和 print 函数相似。

以下就是具体的操作:

static void log_callback(void *ptr, int level, const char *fmt, va_list vaList) {
    switch (level) {
        case AV_LOG_DEBUG:
            logD(fmt, vaList);
            break;
        case AV_LOG_VERBOSE:
            logV(LOG_MAGENTA, fmt, vaList);
            break;
        case AV_LOG_INFO:
            logI(fmt, vaList);
            break;
        case AV_LOG_WARNING:
            logW(fmt, vaList);
            break;
        case AV_LOG_ERROR:
            logE(fmt, vaList);
            break;
        default:
            log(fmt, vaList);
            break;
    }
}

switch 做日志级别的分发处理,具体的打印方法交给宏定义的函数。

在这里主要是根据不同级别,调整日志打印输出的颜色,如下图所示:

注意的是,如果注册了自定义日志打印,那么除了我们调用 av_log 方法会打印日志之外,FFmpeg 内部的一些日志信息也会通过自定义的方法打印出来。

自定义日志打印颜色

一般来说,日志打印都是通过宏函数来定义的。

#define logD(format,...)        \
logging(LOG_GREEN,format,##__VA_ARGS__)     

其中 ##__VA_ARGS__ 意思就是可变参数宏,对应函数里面的三个点可变参数 ...

具体的函数实现如下:

static void logging(const char * color ,const char *fmt, va_list vaList)
{
    // 设置日志打印颜色
    printf("%s [av-beginner]: ",color);
    // 打印内容
    vprintf( fmt, vaList );
    // 结束日志颜色设定
    printf(LOG_NONE "\n" );
}

static void logging(const char * color ,const char *fmt, ...)
{
    va_list vaList;
    va_start( vaList, fmt );
    logging(color,fmt,vaList);
    va_end(vaList);
}

这里面涉及到可变参数以及日志颜色打印的内容,展开说一下日志颜色打印。

在终端的字符颜色是由转义序列控制的,比如终端中要换行,那么转义序列就是 \n 操作,对于颜色控制同样如此。

具体的显示格式如下:

\033[显示方式;前景色;背景色m输出字符串\033[0m

\e[显示方式;前景色;背景色m输出字符串\e[0m

在调用 print 函数打印信息时,就按照以上的方式即可,比如:

// 打印红色的日志内容
printf("\033[0;31m print red color log \033[0m\n") ;

以上就可以打印出红色的日志信息,具体的关于显示方式、前景色、背景色这些内容,后续的文章再接着说了。

总结

以上就是音视频基础学习连载的 010 篇。

简单讲解了 FFmpeg 中的日志打印内容,本文具体代码见仓库:

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

仓库的代码会比文章提前更新,想要抢先知道后续内容,就关注代码吧,欢迎 star 。

能力有限,文中有不对之处,欢迎加我微信 ezglumes 进行交流~~


技术交流,欢迎加我微信:ezglumes ,拉你入技术交流群。

扫码关注公众号【音视频开发进阶】,一起学习多媒体音视频开发~~~

喜欢就点个「在看」吧 ▽

相关文章:

  • 如何将ijkplayer引入AS工程中进行二次开发
  • Android 性能优化必知必会
  • 音视频面试基础题
  • 2020年中国音频产业生态发展分析
  • 疫情下的网络视频行业观察 | 从疫情看网络视频领域竞争方向
  • 为什么小姐姐能摇一晚上不倒?
  • Android 热修复 AndFix 原理,看这篇就够了
  • 推荐几个堪称教科书级别的 Android 音视频入门项目
  • ffmpeg音视频同步的几种策略
  • 【Jetpack更新之Fragment】1.3.0-alpha04 来袭,Fragment 间通信的新姿势
  • Android使用OpenGL渲染ffmpeg解码的YUV数据
  • 详解Handler机制中消息队列的出队逻辑
  • 详解Handler中消息队列的入队逻辑
  • 视频无缝续播的一些解决方案
  • 移动端技术交流喊你入群啦~~~
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 《Java编程思想》读书笔记-对象导论
  • 「译」Node.js Streams 基础
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • docker python 配置
  • echarts的各种常用效果展示
  • Java IO学习笔记一
  • Java基本数据类型之Number
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • learning koa2.x
  • Mysql优化
  • spring + angular 实现导出excel
  • TypeScript实现数据结构(一)栈,队列,链表
  • 后端_MYSQL
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 记一次用 NodeJs 实现模拟登录的思路
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 使用Swoole加速Laravel(正式环境中)
  • 我是如何设计 Upload 上传组件的
  • 新书推荐|Windows黑客编程技术详解
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • # Panda3d 碰撞检测系统介绍
  • ###STL(标准模板库)
  • #ifdef 的技巧用法
  • #单片机(TB6600驱动42步进电机)
  • (1)虚拟机的安装与使用,linux系统安装
  • (145)光线追踪距离场柔和阴影
  • (poj1.2.1)1970(筛选法模拟)
  • (办公)springboot配置aop处理请求.
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (强烈推荐)移动端音视频从零到上手(下)
  • (三)uboot源码分析