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

推荐订阅源

S
Schneier on Security
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Threat Research - Cisco Blogs
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cisco Talos Blog
Cisco Talos Blog
The Hacker News
The Hacker News
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
Security Latest
Security Latest
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
C
Cisco Blogs
AWS News Blog
AWS News Blog
T
Threatpost
L
LINUX DO - 热门话题
Simon Willison's Weblog
Simon Willison's Weblog
Scott Helme
Scott Helme
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tor Project blog
Cyberwarzone
Cyberwarzone
P
Proofpoint News Feed
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
The Exploit Database - CXSecurity.com
The Register - Security
The Register - Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
罗磊的独立博客
云风的 BLOG
云风的 BLOG
V
Vulnerabilities – Threatpost
N
News | PayPal Newsroom
Project Zero
Project Zero
NISL@THU
NISL@THU
博客园_首页
MyScale Blog
MyScale Blog
V2EX - 技术
V2EX - 技术
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Full Disclosure
T
Troy Hunt's Blog
Recorded Future
Recorded Future
N
Netflix TechBlog - Medium
P
Privacy International News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
A
Arctic Wolf
C
Check Point Blog
W
WeLiveSecurity
Apple Machine Learning Research
Apple Machine Learning Research
C
CERT Recently Published Vulnerability Notes

音视频开发进阶

音视频教程-第三节 音视频教程-第二节 真的,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视频文件如何缩放分辨率 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 音视频入门项目 【音视频连载-010】第二季 FFmpeg 日志打印 【音视频连载-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 包围盒
002 | 播放器系列专栏-FFmpeg依赖库的配置
音视频开发进阶 · 2022-03-18 · via 音视频开发进阶

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

上回书说道:星球专享 | 关于播放器的一次项目实践 目前已经完成了项目的创建,是怎样一个项目呢? 首先是播放器 SDK ,也是项目最核心的模块,然后是对 SDK 进行单元测试的模块,最后是使用 SDK 做播放器的可视化项目模块。

项目工程的每个目录介绍已经在上篇文章中讲过了,这里会说一下如何打开项目。

如图所示,1 和 2 代表两个 CMakeLists.txt 文件,其中 1 代表的是 SDK 工程 CMake 配置文件,2 代表的是播放器工程 CMake 配置文件。

图标 3 作为新增的库文件目录,后面会介绍。

项目根目录是作为 SDK 的目录,而 demo 是在根目录下的子目录中,同时 demo 依赖根目录 SDK 的编译结果,这种项目配置在一些开源项目中还是很常见的。

当用 CLion 打开工程时如果选择了根目录下的 CMakeLists.txt 就是 SDK 工程了,选择了 demo 目录下的就是播放器项目了,差别就是在 CLion 中能否有 PlanetPlayerDemo 这个构建,如下图所示:

选择 SDK 工程打开方式时就只有 2 和 3 的选项了,其中 2 是 SDK 的构建,3 是单测的构建,而 1 是播放器打开方式才有的,前期很多时候都只要 SDK 打开方式就行了。


打开工程之后,接下来就要添加 FFmpeg 的依赖了。

这里并不打算讲要如何编译 FFmpeg ,因为一开始就被编译困住了,很难接下来的学习,反而有一种简单的方式直接拿编译好的库就行了。

如果是 Mac 电脑的话,使用 brew 安装 ffmepg ,电脑上就已经有编译好的库了,而且还很全面。

众所周知,FFmpeg 是有很多编译选项和依赖选项的,那么上面的命令到底指定了哪些依赖呢?

如上图,✅ 和 ❎ 表示的意思很明确了。

另外箭头所指的 url 地址其实就是 brew 安装 ffmpeg 的编译脚本了,里面指定了哪些依赖内容,比如涉及的 x264、x265 就包含在内了。

我们的播放器项目就是在 Mac 上运行的,所以完全可以直接用 brew 安装好的 ffmpeg 库。

如上命令,在 finder 中打开 ffmpeg 的安装目录。

其中 include 目录就是头文件目录,lib 目录里面放着 ffmpeg 的动态库和静态库。

我们要的就是这两个目录里的东西,直接拷出来用,为此我建立了一个仓库,单独存放这些编译好的库文件(只用静态库就行)。

https://github.com/glumes/lib

这个仓库正好对应之前提的图标 3 的目录。

温馨提示:由于我在家用的 M1 Pro 对应 arm64 架构,所以拿出来的库也是 arm64 架构的,如果你用的非 M1 对应的就是 x86_64 架构,这块等我回公司了补上,也可以自己补上。

接下来就是要在工程中链接 FFmpeg 库了。

首先新建了一个 vendor.cmake 作辅助,判断当前系统是什么平台和架构的:

if (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
    set(arch arm64)
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
    set(arch x64)
endif ()

if (WIN32)
    set(platform win)
elseif (APPLE)
    set(platform mac)
else ()
    message(FATAL_ERROR "not support current platform")
endif ()

然后添加链接 FFmpeg 库的方法:

可以看到链接库时用到了上面指定的平台和架构信息,这和我们的目录结构是相互依赖的。

有了这两个方法,在 SDK 工程和播放器工程都可以复用了。

接下来在 SDK 工程中的配置就和平常配置一样了,依赖好 ffmpeg 的库。

set(path ${CMAKE_CURRENT_SOURCE_DIR})

# SDK 的头文件
set(PLANET_INCLUDES ./ include src)

include(${CMAKE_CURRENT_SOURCE_DIR}/vendor.cmake)

# 模拟第三方库依赖
add_subdirectory(3rdparty/test1)
list(APPEND PLANET_INCLUDES 3rdparty/test1/src)

add_subdirectory(3rdparty/test2)
list(APPEND PLANET_INCLUDES 3rdparty/test2/src)

# 添加 FFmpeg 头文件的依赖
list(APPEND PLANET_INCLUDES ${path}/lib/ffmpeg/${platform}/${arch}/include)
# 自定义方法 链接 ffmpeg 库目录
link_ffmpeg_directory(${path})

# SDK 的源文件
file(GLOB_RECURSE PLANET_FILES
        src/*.*)

# 编译 SDK 的静态库
add_library(PlanetPlayer STATIC ${PLANET_FILES})

# 包含头文件内容
target_include_directories(PlanetPlayer PUBLIC ${PLANET_INCLUDES})

# 链接三方库
target_link_libraries(PlanetPlayer  gtest TEST1 TEST2)

# 自定义方法 链接 ffmpeg
link_ffmpeg_library(PlanetPlayer ${path})

同样在播放器项目中也要做配置,依赖 SDK 以及 ffmpeg 的库。

# 设置 SDK 的根目录
set(ProjectPath ${CMAKE_CURRENT_SOURCE_DIR}/../../PlanetPlayer)

# 自定义方法 链接 ffmpeg 库目录
link_ffmpeg_directory(${path})

# 播放器项目的头文件
set(DEMO_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/src)

# SDK 提供的头文件
list(APPEND DEMO_INCLUDES ${ProjectPath}/include)

# 播放器项目的源文件
file(GLOB_RECURSE DEMO_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.*)

# 添加 SDK 的目录
add_subdirectory(${ProjectPath}/ PlanetPlayer)

# 播放器项目
add_executable(PlanetPlayerDemo ${DEMO_SOURCE_FILES})

# 包含头文件内容
target_include_directories(PlanetPlayerDemo PUBLIC ${DEMO_INCLUDES})

# 链接三方库
target_link_libraries(PlanetPlayerDemo PlanetPlayer)

# 自定义方法 链接 ffmpeg
link_ffmpeg_library(PlanetPlayerDemo ${path})

这里有个问题,就是既然 SDK 依赖了 ffmepg ,播放器依赖了 SDK ,为什么播放器还有依赖 ffmpeg ?

这是因为编译的 SDK 是个静态库,但是并没有把 ffmpeg 的静态库合并进来,导致播放器仅链接了 SDK 的库会找不到 ffmpeg 函数的符号表,后续再把这个功能补上。

另外也说明了,音视频做工程搭建也是有很多学问的。

以上就是本篇文章的内容了,搞定了库依赖就可以开始撸代码啦!!!

关于播放器实践的专栏,后续大部分进展都会放在知识星球里面了,尤其是源码会在星球内同步更新,当然也会挑一些干货在公众号同步。

目前 音视频开发进阶知识星球 还在让利中,非常低的价格就可以获得业内一线开发人员的答疑解惑。

与其在群里面提问石沉大海,不如来星球有问必答,而且这个价格还是管一年的哦,一年的时间可以说是相当划算了。

同时星球内非常欢迎大家提问,尤其是我不会的问题,我会去找业内好朋友请教,既回答了你的问题又帮助了我提高。

想要加入的可以通过扫如下二维码进星球哦,iPhone 用户如果不能访问小程序的话,也可以加我微信 ezglumes 拉你进星球。

原创文章,转载请注明来源:    002 | 播放器系列专栏-FFmpeg依赖库的配置