FFMPEG Tips (1) 如何打印日志

简介:

1.  FFMPEG 打印日志的函数


FFMPEG 有一套自己的日志系统,它使用 av_log() 函数来打印日志,其声明位于:<libavutil/log.h>


它的函数原型如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
  * Send the specified message to the log if the level is less than or equal
  * to the current av_log_level. By default, all logging messages are sent to
  * stderr. This behavior can be altered by setting a different logging callback
  * function.
  * @see av_log_set_callback
  *
  * @param avcl A pointer to an arbitrary struct of which the first field is a
  *        pointer to an AVClass struct.
  * @param level The importance level of the message expressed using a @ref
  *        lavu_log_constants "Logging Constant".
  * @param fmt The format string (printf-compatible) that specifies how
  *        subsequent arguments are converted to output.
  */
void  av_log( void  *avcl,  int  level,  const  char  *fmt, …);


参数含义:


avcl:指定一个包含 AVClass 的结构体,指定该 log 所属的结构体,如 AVFormatContext、AVCodecContext 等等,可以设置为 NULL

level:log 的级别,下面给出可选的值

fmt:跟 c 语言的 printf() 定义一样


2.  FFMPEG 日志级别


LOG 的级别是一个 int 类型,其可选的数值及其含义如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
  * Print no output.
  */
#define AV_LOG_QUIET    -8
 
/**
  * Something went really wrong and we will crash now.
  */
#define AV_LOG_PANIC     0
 
/**
  * Something went wrong and recovery is not possible.
  * For example, no header was found for a format which depends
  * on headers or an illegal combination of parameters is used.
  */
#define AV_LOG_FATAL     8
 
/**
  * Something went wrong and cannot losslessly be recovered.
  * However, not all future data is affected.
  */
#define AV_LOG_ERROR    16
 
/**
  * Something somehow does not look correct. This may or may not
  * lead to problems. An example would be the use of '-vstrict -2'.
  */
#define AV_LOG_WARNING  24
 
/**
  * Standard information.
  */
#define AV_LOG_INFO     32
 
/**
  * Detailed information.
  */
#define AV_LOG_VERBOSE  40
 
/**
  * Stuff which is only useful for libav* developers.
  */
#define AV_LOG_DEBUG    48


3.  FFMPEG 设置和获取当前日志级别


由一个全局的变量来控制哪个级别及以上的日志会打印输出,设置和获取这个全局变量的函数如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
  * Get the current log level
  *
  * @see lavu_log_constants
  *
  * @return Current log level
  */
int  av_log_get_level( void );
 
/**
  * Set the log level
  *
  * @see lavu_log_constants
  *
  * @param level Logging level
  */
void  av_log_set_level( int  level);


例如,当全局的日志级别设置为 `AV_LOG_ERROR`,那么凡是日志级别高于 `AV_LOG_ERROR` 的日志,都不会被打印出来。


4.  FFMPEG 日志打印函数的使用示例


假设要打印 DEBUG 和 ERROR 级别的日志,用法示例如下:


1
2
av_log(NULL, AV_LOG_DEBUG,  "Hello World ! \n" );
av_log(NULL, AV_LOG_ERROR,  "Error:%d ! \n" , errorCode);


5.  FFMPEG 日志打印函数的封装


当然,如果你觉得 av_log 用起来不是很顺手,你可以定义个宏封装下,例如:


1
2
3
4
5
6
7
8
9
10
11
12
#ifndef _SYS_LOG_
#define _SYS_LOG_
 
#include <libavutil/log.h>
 
#define LOGD(format, ...) av_log(NULL, AV_LOG_DEBUG, format, ##__VA_ARGS__);
#define LOGV(format, ...) av_log(NULL, AV_LOG_VERBOSE, format, ##__VA_ARGS__);
#define LOGI(format, ...) av_log(NULL, AV_LOG_INFO, format, ##__VA_ARGS__);
#define LOGW(format, ...) av_log(NULL, AV_LOG_WARNING, format, ##__VA_ARGS__);
#define LOGE(format, ...) av_log(NULL, AV_LOG_ERROR, format, ##__VA_ARGS__);
 
#endif


6.  Android 中打印 FFMPEG 的日志


由于 FFMPEG 默认使用的是 printf 来打印日志,而 Android 系统有着一套自己的 LOG 系统,因此,需要让 FFMPEG 的日志重定向使用 Android 的日志系统,具体方法描述如下:


通过 FFMPEG 的 av_log_set_callback() 注册一个 LOG callback function,FFMPEG 就会把 LOG 打印功能重定向到 callback function 中,代码示例如下(你也可以到我的 Github 查看封装好的源代码:  https://github.com/Jhuster/clib):


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifdef __ANDROID_API__
#include <android/log.h>
 
#define ALOG(level, TAG, ...)    ((void)__android_log_vprint(level, TAG, __VA_ARGS__))
 
#define SYS_LOG_TAG "nmplayer"
 
static  void  syslog_print( void  *ptr,  int  level,  const  char  *fmt,  va_list  vl)
{
     switch (level) {
     case  AV_LOG_DEBUG:
         ALOG(ANDROID_LOG_VERBOSE, SYS_LOG_TAG, fmt, vl);
         break ;
     case  AV_LOG_VERBOSE:
         ALOG(ANDROID_LOG_DEBUG, SYS_LOG_TAG, fmt, vl);
         break ;
     case  AV_LOG_INFO:
         ALOG(ANDROID_LOG_INFO, SYS_LOG_TAG, fmt, vl);
         break ;
     case  AV_LOG_WARNING:
         ALOG(ANDROID_LOG_WARN, SYS_LOG_TAG, fmt, vl);
         break ;
     case  AV_LOG_ERROR:
         ALOG(ANDROID_LOG_ERROR, SYS_LOG_TAG, fmt, vl);
         break ;
     }
}
 
static  void  syslog_init()
{
     av_log_set_callback(syslog_print);
}
 
#endif // __ANDROID_API__


在代码初始化的地方调用一下 syslog_init() 后,就可以使用 av_log() 在 Android 平台输出调试日志了。


7.  FFPlay 设置日志级别


平时自己写的播放器播放某些流播放有问题的话,也可以使用 ffplay 来对比调试一下,看看使用 ffplay 是否可以播放,报错信息是什么,ffplay 打开 DEBUG 日志输出的方法示例如下:


1
$ ffplay -v debug $URL


-v 参数是用于配制 ffplay 的日志级别,其定义如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-loglevel [repeat+]loglevel | -v [repeat+]loglevel
 
Set the logging level used by the library. Adding  "repeat+"  indicates that repeated  log  output should not be compressed to the first line and the  "Last message repeated n times"  line will be omitted.  "repeat"  can also be used alone. If  "repeat"  is used alone, and with no prior loglevel set, the  default  loglevel will be used. If multiple loglevel parameters are given,  using  ’repeat’ will not change the loglevel. loglevel is a string or a number containing one of the following values:
 
‘quiet, -8’
Show nothing at all; be silent.
 
‘panic, 0’
Only show fatal errors which could lead the process to crash, such as an assertion failure. This is not currently used  for  anything.
 
‘fatal, 8’
Only show fatal errors. These are errors after which the process absolutely cannot  continue .
 
‘error, 16’
Show all errors, including ones which can be recovered from.
 
‘warning, 24’
Show all warnings and errors. Any message related to possibly incorrect or unexpected events will be shown.
 
‘info, 32’
Show informative messages during processing. This is in addition to warnings and errors. This is the  default  value.
 
‘verbose, 40’
Same as info, except more verbose.
 
‘debug, 48’
Show everything, including debugging information.
 
‘trace, 56’
By  default  the program logs to stderr. If coloring is supported by the terminal, colors are used to mark errors and warnings. Log coloring can be disabled setting the environment variable AV_LOG_FORCE_NOCOLOR or NO_COLOR, or can be forced setting the environment variable AV_LOG_FORCE_COLOR. The use of the environment variable NO_COLOR is  deprecated  and will be dropped in a future FFmpeg version.


本文转自 Jhuster 51CTO博客,原文链接:http://blog.51cto.com/ticktick/1867059,如需转载请自行联系原作者

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
9月前
ffmpeg的日志系统
ffmpeg的日志系统
34 0
ffmpeg的日志系统
|
API
音视频系列三:ffmpeg之日志打印
在上一篇 Visual Studio2019集成ffmpeg之hello world中,我们已经配置好visual studio的开发环境,接下来继续根据上一篇的环境来学习ffmpeg的日志打印;
510 0
音视频系列三:ffmpeg之日志打印
|
Android开发
【音视频连载-010】第二季 FFmpeg 日志打印
音视频连载系列已经停更一段时间,再这么停下去估计就要掉粉了,捡起来继续更新~~~ 接下来主要是讲解 FFmpeg 相关的内容,比如这篇就从简单的日志打印开始说起。
222 0
【音视频连载-010】第二季 FFmpeg 日志打印
|
数据库
zt:Tips--归档日志常用格式说明
归档日志常用格式说明%s: 日志序列号%S: 日志序列号(带有前导0)%t: 重做线程编号.%T: 重做线程编号(带有前导0)%a: 活动ID号%d: 数据库ID号%r: RESETLOGS的ID值.
827 0
|
6天前
|
开发工具
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(三)
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(三)
21 0
|
6天前
|
Linux 编译器 数据安全/隐私保护
Windows10 使用MSYS2和VS2019编译FFmpeg源代码-测试通过
FFmpeg作为一个流媒体的整体解决方案,在很多项目中都使用了它,如果我们也需要使用FFmpeg进行开发,很多时候我们需要将源码编译成动态库或者静态库,然后将库放入到我们的项目中,这样我们就能在我们的项目中使用FFmpeg提供的接口进行开发。关于FFmpeg的介绍这里就不过多说明。
91 0

热门文章

最新文章