惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
S
Securelist
J
Java Code Geeks
Recorded Future
Recorded Future
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
S
Secure Thoughts
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
Martin Fowler
Martin Fowler
The Last Watchdog
The Last Watchdog
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
Vercel News
Vercel News
O
OpenAI News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
PCI Perspectives
PCI Perspectives
N
News and Events Feed by Topic
H
Heimdal Security Blog
SecWiki News
SecWiki News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园 - 【当耐特】
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
Hacker News: Ask HN
Hacker News: Ask HN
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
Netflix TechBlog - Medium
A
Arctic Wolf
The Hacker News
The Hacker News
I
Intezer
S
Schneier on Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Apple Machine Learning Research
Apple Machine Learning Research
L
Lohrmann on Cybersecurity
宝玉的分享
宝玉的分享
P
Privacy & Cybersecurity Law Blog
Stack Overflow Blog
Stack Overflow Blog
T
Tor Project blog
小众软件
小众软件
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
Jina AI
Jina AI

音视频开发进阶

音视频教程-第三节 音视频教程-第二节 真的,AI 可能就是新时代的信息差 充值 Cursor 之后,工作有了哪些变化?🤔 个人'蒸馏'大模型能做哪些有意思的事情 DeepSeek 大模型在 Mac 上的部署和运行 音视频教程-第一节 【WebRTC 专栏】-- Android 开发集成 WebRTC 库的几种方式 【WebRTC 专栏】-- 在 Mac M1 等系列芯片编译和开发 WebRTC-Android 库 Meta Llama3 大模型在 Mac 上的部署和运行 iOS VideoToolBox 解码 HEVC Open-GOP 视频的问题排查 Flutter 状态管理之 InheritedWidget 使用和分析 用 ChatGPT 回答技术问题怎么样 ? 音视频开发系统入门大致路线 UE 4.27 添加自定义 ShadingModel 用 UE4 虚幻引擎做个捏脸小功能~~ UE4 材质练习 之 凹凸贴图偏移的使用 UE4 材质练习系列基础 OpenGL上下文创建以及共享机制 007 | 播放器系列专栏-解析 MP4 文件读取信息 006 | 播放器系列专栏-在 Mac 上查看 MP4 格式信息 干货 | 快速抽取缩略图是怎么练成的? 关于直播、WebRTC、FFmpeg 的那些事 005 | 播放器系列专栏-在 Windows 上查看 MP4 格式信息 将音视频中的花屏、绿屏、黑屏问题一网打尽 关于音视频里面的解码帧率和渲染帧率 004 | 播放器系列专栏-认识MP4视频(下) 003 | 播放器系列专栏-认识MP4视频(上) 入门或者转行音视频,应该要怎么做? H264视频文件如何缩放分辨率 002 | 播放器系列专栏-FFmpeg依赖库的配置 001 | 播放器系列专栏-关于播放器项目的一个小实践 Seek策略以及在有B帧情况下的处理 目前流媒体开发工程师工作内容主要是什么? 一个音视频领域专业问答的小圈子 干货收藏 || Vulkan Game Engine 视频教程 音视频春节假期内卷指南(实操) Vulkan 在 FFmpeg 中的支持 Windows 下 FFmpeg 和 LibX264 的编译和配置 Metal 开发 | 使用 C++ 进行接口调用 音视频开发工作经验分享 || 视频版 FFmpeg 调用 MediaCodec 硬解码到 Surface 上 代码吸猫 | 用 OpenGL 图像渲染的养猫计划 百倍变速--解码到底能不能丢 非参考帧 ?FFmpeg 有话说!!! 老生常谈-FFmpeg 的编译问题轻松搞定 FFmpeg 调用 Android MediaCodec 进行硬解码(附源码) 【WebRTC 专栏】--创建相机预览 Unity Shader 光照基础之 Half Lambert 光照模型 Unity Shader 光照基础之Lambert光照模型 Unity Shader 光照基础内容 Unity Shader 显示一张图片纹理 UnityShader 的基本概念 Unity 物体的基本操作 C++ 模板系列小结07-尾置返回类型 C++ 模板系列小结06-可变参数模板特性 C++ 中的多线程的使用和线程池建设 C++ 模板系列小结05-模板类型作为模板参数 C++ 模板系列小结04-类模板中的成员模板 C++ 模板系列小结03-在模板中指定变量类型 C++ 模板系列小结02-非类型模板参数 C++ 模板系列小结01-函数模板和类模板 从零打造渲染引擎系列01-什么是渲染引擎 iOS开发 - 在 Swift 中去调用 C/C++ 代码 2021 技术新番 - 从零打造渲染引擎系列 iOS 音视频开发的一些基础准备工作 音视频交流群又来啦~~~ 【WebRTC 专栏】WebRTC & Android 开发学习环境搭建~ 【喜大普奔】域名终于备案通过啦 Shader 优化 | OpenGL 绘制网格效果 【音视频连载-011】第二季 FFmpeg 一层一层获取文件信息 KodeLife | Shader 实时编辑预览的强大工具使用实践 推荐几个堪称教科书级别的 Android 音视频入门项目 【音视频连载-008】基础学习篇-SDL 播放 PCM 音频文件(下) 【音视频连载-007】基础学习篇-SDL 播放 PCM 音频文件(上) 【音视频连载-006】基础学习篇-SDL 播放 YUV 视频文件 【音视频连载-005】基础学习篇-SDL 加载 YUV 文件并显示 【音视频连载-004】基础学习篇-SDL 加载图片并显示 【音视频连载-003】基础学习篇-SDL 消息循环和事件响应 【音视频连载-002】基础学习篇-SDL 创建窗口并显示颜色 【音视频连载-001】基础学习篇- SDL 介绍以及工程配置 LearnOpenGL 源码在 MAC 上的编译与调试 2019 年终总结与回顾 Android NDK 开发的免费技术视频来啦~~ OpenGL 实现视频编辑中的转场效果 OpenGL 实践之贝塞尔曲线绘制 图像库 libjpeg-turbo 编译与实践 图像库 libpng 编译与实践 rust 开发编译 Android 动态库实践 Android NDK 开发 —— 从 Assets 文件夹加载图片并上传纹理 简单易用的图像解码库介绍 —— stb_image 博客图床迁移记 进击的 Vulkan 移动开发之 SwapChain 进击的 Vulkan 移动开发之 Command Buffer 进击的 Vulkan 移动开发之 Instance & Device & Queue 进击的 Vulkan 移动开发(一)之今生前世 Java 显式锁 Lock 与条件队列 C++ 标准容器库小结 MediaCodec 硬编码之相机内容编码成 H264 文件 一文读懂 YUV 的采样与格式 《OpenGL ES 3.x 游戏开发》碰撞检测之 AABB 包围盒
【音视频连载-010】第二季 FFmpeg 日志打印
音视频开发进阶 · 2020-04-27 · via 音视频开发进阶

一个专注音视频领域的小圈子

音视频连载系列已经停更一段时间,再这么停下去估计就要掉粉了,捡起来继续更新~~~ 接下来主要是讲解 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 进行交流~~

原创文章,转载请注明来源:    【音视频连载-010】第二季 FFmpeg 日志打印