
音视频开发
文章平均质量分 89
实时音视频通信开发。
hanpfei
实时音视频开发。
展开
-
PipeWire 音频设计与实现分析四——事件循环的设计与实现
PipeWire 的事件循环基于两个插件的 4 个接口实现,它们是插件的接口,插件的和。PipeWire 的 SPA 系统功能,即接口,用对象描述,系统功能方法集用对象描述,这两个类型定义 (位于对象的字段将指向对象。PipeWire 提供了一些宏,由对象调用的各个方法,这些宏的定义 (位于SPA 系统功能用来执行文件操作以及访问时钟,包括文件读写、poll、关闭、pollfd 操作、timerfd 操作、eventfd 操作和 signalfd 操作等。插件的和接口,分别用和。原创 2025-03-29 09:37:39 · 792 阅读 · 0 评论 -
PipeWire 音频设计与实现分析三——日志子系统
SPA 框架中,避免插件内部执行分配内存的操作,以避免不同的内存分配机制可能引入的分配内存的时间消耗不可控的问题。PipeWire 的绝大部分功能组件都设计为可动态加载的,可动态加载的对象分为两类,一是插件,默认位于。函数尝试打开插件目录下的插件库文件,直到打开成功或遍历完了所有插件目录。函数接受传入的 SPA 插件库路径为空,当为空时,库路径取。库路径是插件的动态链接库文件相对于插件目录的路径,但去掉。的链表中取下来,关闭动态链接库的 handle,释放。函数,它是插件的入口点,这个函数的声明 (位于。原创 2025-03-29 09:34:40 · 829 阅读 · 0 评论 -
PipeWire 音频设计与实现分析二——SPA 插件
SPA 框架中,避免插件内部执行分配内存的操作,以避免不同的内存分配机制可能引入的分配内存的时间消耗不可控的问题。PipeWire 的绝大部分功能组件都设计为可动态加载的,可动态加载的对象分为两类,一是插件,默认位于。函数尝试打开插件目录下的插件库文件,直到打开成功或遍历完了所有插件目录。函数接受传入的 SPA 插件库路径为空,当为空时,库路径取。库路径是插件的动态链接库文件相对于插件目录的路径,但去掉。的链表中取下来,关闭动态链接库的 handle,释放。函数,它是插件的入口点,这个函数的声明 (位于。原创 2025-03-29 09:33:03 · 835 阅读 · 0 评论 -
核心 Android 调节音量的过程
由上面这些调节音量的方法可以看到,Android Automotive 调节音量的动作有意在 Car 服务中直接对设备调节了音量,而没有继续经过核心 Android 系统的 audio 服务。Audio policy service 接收 index 形式的音量值,将音量的 index 值转为db 值,又转为增益值,最后将音量增益设置给 audio flinger。然后发送消息去设置设备的音量。设置设备的音量时,先设置传入的设备的音量,然后设置别名设备的音量,之后发送消息将音量设置持久化。原创 2023-03-06 18:51:32 · 4397 阅读 · 0 评论 -
Android Audio HAL 服务
在 Android 系统中,Audio HAL 服务用于管理对音频硬件的访问,AudioFlinger 通过 Audio HAL 服务访问音频硬件。这里以 Android Automotive (AAOS) 版模拟器为例,来看 Audio HAL 服务的设计、实现和访问,代码分析基于 android-12.1.0_r27 进行。AAOS 版模拟器的 Audio HAL 服务的实现位于,在 android 设备中,它将以名为的进程存在,这个进程的主函数定义 (位于。原创 2023-03-09 20:00:16 · 3640 阅读 · 0 评论 -
Audio HAL 提供的操作
这个线程执行的主要任务为,周期性地唤醒,遍历所有的输出音频流的数据,把它们做混音,并将混音之后的数据通过 ALSA 的接口写入设备。这里输出音频流的数据和混音之后的音频数据都用。是音频输出设备的抽象接口,它提供了关于音频输出硬件驱动的各种属性的信息,同样提供了更加丰富的操作,其定义 (位于。对象,且如果输入音频流的数据来源指定为音频发生器设备,则初始化相关的状态;单例对象时,会起一个线程,用于将各个输出流的音频数据,通过 ALSA 的接口写入设备;这个操作完成的主要的事情为创建一个单实例的定制版的。原创 2023-03-18 10:53:00 · 2857 阅读 · 0 评论 -
PipeWire 音频设计与实现分析一——介绍
PipeWire 是一个基于图的媒体处理引擎,一个可以运行多媒体节点图的媒体服务器,是 Linux 的音频/视频总线,它管理 Linux 系统中,不同应用程序对音频和视频设备的共享访问。它提供了一个本地客户端音频 API,但也提供兼容层来支持使用常见的音频 API,包括 ALSA、PulseAudio 和 JACK。PipeWire 在媒体节点图的处理方面,采用机制与策略分离的设计。PipeWire 主守护进程运行媒体节点图,是机制而不是策略。原创 2025-03-29 09:20:23 · 901 阅读 · 0 评论 -
Linux 系统蓝牙音频服务实现分析
HSP 是蓝牙协议栈中最早的耳机配置文件,主要用于支持蓝牙耳机和手机之间的基本音频通信,它支持单声道音频传输(通常用于语音通话),和基本的远程控制功能(如接听/挂断电话),主要用于简单的蓝牙耳机,功能较为基础。HFP 是 HSP 的升级版,提供了更丰富的功能,主要用于支持免提设备(如车载蓝牙系统)与手机之间的通信,它支持单声道音频传输(语音通话),更复杂的远程控制功能(如音量控制、重拨、拒接电话等),电话状态信息(如电池电量、信号强度等),及多方通话和语音识别,主要用于车载蓝牙系统、高端蓝牙耳机等。原创 2025-03-15 18:46:11 · 975 阅读 · 0 评论 -
深入 PipeWire
随着它的成熟,PipeWire 项目正在慢慢地变得流行。它的文档依然相对稀少,但正在逐渐增长。然而,让项目外部的人尝试用他们自己的语言来理解和解释它总是一个好主意,重申想法,从他们自己的角度来看待它。在之前的一篇文章中,我讨论了 Unix 上的通用音频栈,并有一节提到了 PipeWire。不幸的是,因为当时我没有找到足够的文档,并且无法理解一些概念,我认为我没有对项目进行公正的处理,甚至可能混淆了某些部分。原创 2025-03-04 23:19:22 · 834 阅读 · 0 评论 -
Android 中的混音器 AudioMixer 实现分析
Android 混音器 AudioMixer 实现分析。原创 2023-04-12 18:56:19 · 3761 阅读 · 0 评论 -
Android 中打开音频流所用的配置
对于通道掩码(通道数),如果是直接输出 (Direct Output),则通道数越小优先级越高,否则,通道数越大优先级越高;对于采样率,如果是直接输出 (Direct Output),则采样率越小优先级越高,否则,采样率越大优先级越高。Android 中打开音频输出流,所需的主要参数采样率、通道掩码(通道数)、采样格式、增益和标记来自于传入的。音频策略配置文件,更具地说,来自于音频策略配置文件中的。的标记和增益直接来自于音频策略配置文件的。对象,后者的构造函数的定义 (位于。在音频策略配置文件中,原创 2023-04-08 18:44:21 · 1200 阅读 · 0 评论 -
WebRTC 媒体数据传输控制之平滑发送实现
WebRTC 的平滑发送 pacer 模块用于更有节奏地发送音视频媒体数据及音视频媒体传输控制数据,更具体地说,由于音频数据包大多比较小,一般不会超过 MTU,因而 pacer 模块主要用于控制视频数据包的发送。WebRTC 官方有一份文档对 pacer 的背景及主要设计思路做了简要介绍,其中文版翻译可以参考。这里分析 WebRTC pacer 模块的实现。原创 2022-10-20 14:06:17 · 1685 阅读 · 0 评论 -
WebRTC 一对一语音通话中音频端到端分段延迟分析
WebRTC 一对一语音通话中的音频端到端延迟指从一个音频信号被发送端采集,到同一个信号被接收端播放出来这整个过程的时间。音频端到端延迟由多个阶段组成。音频端到端处理的冲采样、混音、回声和降噪等操作会使音频数据在数值上变得面目全非,变得难以比较。真正的音频端到端延迟一般使用专业的声卡设备配上专门的音频处理软件来测,这种测试在线上环境中是难以实现的。音频端到端分段延迟常常也能在很大程度上反应音频端到端延迟,分段延迟的分析甚至可以帮我找到造成延迟的瓶颈所在。原创 2022-09-03 10:47:35 · 2415 阅读 · 2 评论 -
WebRTC 的平滑发送
Paced sender,也常常被称为 “pacer”,它是 WebRTC RTP 栈的一部分,主要用于平缓发送到网络的数据包流。原创 2022-06-16 08:20:17 · 825 阅读 · 1 评论 -
WebRTC 的音频网络对抗概述
WebRTC 音频数据处理中,期望可以实现音频数据处理及传输,延时低,互动性好,声音平稳无抖动,码率低消耗带宽少等。在数据传输上,WebRTC 采用基于 UDP 的 RTP/RTCP 协议,RTP/RTCP 本身不提供数据的可靠传输及质量保障。公共互联网这种分组交换网络,天然具有数据包传输的丢失、重复、乱序及延时等问题。WebRTC 音频数据处理的这些目标很难同时实现,WebRTC 的音频网络对抗实现中针对不同情况对这些目标进行平衡。这里更仔细地看一下 WebRTC 音频数据处理管线,并特别关注与音频网.原创 2022-06-10 21:23:38 · 945 阅读 · 0 评论 -
WebRTC 的音频弱网对抗之 NACK
本文梳理 WebRTC 的音频弱网对抗中的 NACK 机制的实现。音频的 NACK 机制在 WebRTC 中默认是关闭的,本文会介绍开启 NACK 机制的方法。原创 2022-06-08 21:15:29 · 1458 阅读 · 0 评论 -
WebRTC 的音频数据编码及发送控制管线
WebRTC 的音频数据处理发送的概念抽象层面的完整流程如下: 用于控制各个操作系统平台的音频设备,主要用来做音频的采集和播放。 是一个适配和胶水模块,它把 的音频数据采集和 的音频数据处理及 / 的音频数据编码和发送控制粘起来, 把采集的音频数据送给 处理,之后再把处理后的数据给到 / 编码发送出去。 用于做音频数据处理,如降噪、自动增益控制和回声消除等。/ 用于对音频数据做编码,比如 OPUS、AAC 等,RTP 打包和发送控制。原创 2022-06-02 07:43:15 · 957 阅读 · 0 评论 -
ALSA 音频 API 使用入门
文章目录理解音频接口典型的音频应用做了什么最小的播放程序最小的采集程序最小的中断驱动程序最小的全双工程序术语如何做 . . .打开设别设置参数硬件参数软件参数为什么你可以忘掉这里的一切本文尝试提供一些对 ALSA 音频 API 的介绍。它不是 ALSA API 的完整参考手册,它也不包含更复杂的软件需要解决的许多特有问题。然而,它确实尝试为技能娴熟,但对 ALSA API 不熟悉的程序员提供充足的背景和信息,来编写使用 ALSA API 的简单程序。理解音频接口让我们先回顾一下一个音频接口的基本原创 2022-05-28 21:35:37 · 2422 阅读 · 0 评论 -
WebRTC iOS Native SDK 接入
借助于 OpenRTCClient 项目,我们可以非常方便地编译出 WebRTC iOS native SDK,通过 OpenRTCClient 项目提供的 webrtc_pack 工具,我们可以很方便地创建包含了 arm64、和 x64 两种还在广泛使用的 CPU 架构二进制代码的 webrtc 静态库文件。这里说明为 iOS 应用接入 webrtc 静态库文件的过程。(WebRTC 构建系统默认也提供了构建 Framework 的 target,具体的构建 target 为 framework_objc原创 2022-04-26 20:37:33 · 2769 阅读 · 0 评论 -
向 WebRTC 项目贡献代码
许可协议WebRTC 欢迎针对功能和缺陷修复的补丁和拉取!对于 Google 外部的贡献者,需要按照 Google 个人贡献者许可协议 中给出的指示完成操作。在所有情况下,贡献者在贡献的代码可以被接受之前,必须签署一份贡献者许可协议。请酌情为 个人 或 公司 填写协议。贡献示例如果你想要添加一个新示例,或对一个已有的示例做出修改,我们建议你先创建一个 新问题,我们可以在那里讨论一些细节。当要创建一个新的示例,或更新一个已有的,请确保你也创建,或更新任何已有的,测试。那个仓库中的所有测试都实现为 N原创 2022-04-20 20:59:20 · 922 阅读 · 0 评论 -
在 Mac 上为 Android 编译 WebRTC
在 Mac 上为 Android 编译 WebRTC 的基本流程和在任意平台上编译任何其它目标平台的 WebRTC 大体一致,但在 Mac 上为 Android 编译 WebRTC 不是 WebRTC 官方正式支持的 WebRTC 的构建方式,因而需要针对这种构建方式,对 WebRTC 构建系统中的部分配置和工具做一些适当的调整。本文将描述在 Mac 上为 Android 编译 WebRTC 的流程,流程中各个步骤将会遇到的问题,问题发生原因的简单解释,以及问题的解决方法。在 Mac 上为 Android原创 2022-04-11 21:45:31 · 4870 阅读 · 5 评论 -
Windows 平台编译 WebRTC
Windows 平台编译 WebRTC 的过程,包括安装依赖的开发工具等,主要要参考 chromium 浏览器的 Windows 平台编译文档,Checking out and Building Chromium for Windows。这里编译 WebRTC 的 M96 版。系统要求具有至少 8GB 内存的 64 位 Intel 机器。强烈建议内存大于 16GB。至少 100GB 的空余磁盘空间,且用 NTFS 格式化的分区。不能用 FAT32,因为某些 Git 打包文件可能大于 4GB。一个合原创 2022-01-10 23:08:35 · 3862 阅读 · 2 评论 -
WebRTC 的传输协议
WebRTC 的实现中媒体数据和媒体控制数据通过 RTP/RTCP 来传,媒体数据的处理及媒体数据传输控制基于 RTP/RTCP 来实现。除了 RTP/RTCP 外,连接建立,参数协商,RTP/RTCP 包的传输等过程由信令协议、peer connection 和 p2p 完成,这部分也用到了非常多的协议,包括 ICE,STUN,TURN,SDP,DTLS 等,这些协议有许多的 RFC 定义。这些协议大多也都随着时间在更新优化。这里梳理一下相关的协议及它们的变化发展。ICE 相关协议RFC 5245,原创 2022-01-05 20:46:56 · 1096 阅读 · 0 评论 -
WebRTC 中收集音视频编解码能力
在 WebRTC 中,交互的两端在建立连接过程中,需要通过 ICE 协议,交换各自的音视频编解码能力,如编解码器和编解码器的一些参数配置,并协商出一组配置和参数,用于后续的音视频传输过程。对于音频,编解码能力的一部分信息从 audio 的 encoder 和 decoder factory 中获取。Audio encoder 和 decoder factory 在创建 PeerConnectionFactoryInterface 的时候,由 webrtc 的用户传入,如在 webrtc 示例应用 peer原创 2022-01-04 21:54:09 · 1565 阅读 · 0 评论 -
mediasoup-client 和 libmediasoupclient 指南
mediasoup 是一个 SFU,先来看一下 mediasoup 的架构,看一下 mediasoup 的主要概念和抽象,如 Transport,Producer,Consumer,DataProducer,DataConsumer 在 mediasoup 的媒体数据转发系统中的位置和作用:一般来说,这些抽象在 mediasoup SFU 中有实体对象与之对应。这些抽象在 libmediasoupclient 中对应 C++ 类的含义可以参考 API 文档。这些抽象的名称是以 mediasoup SFU原创 2022-01-01 08:27:48 · 2720 阅读 · 0 评论 -
WebRTC 视频发送和接收处理过程
这里看下视频发送和接收处理过程。分析所基于的应用程序,依然选择 WebRTC 的示例应用 peerconnection_client,代码版本 M96。应用层创建 VideoTrackSource,创建 VideoTrackInterface,启动本地渲染,并将 VideoTrack 添加进 PeerConnection 中:void Conductor::AddTracks() { if (!peer_connection_->GetSenders().empty()) { retu原创 2022-01-01 08:26:09 · 3508 阅读 · 3 评论 -
WebRTC 的 AudioSource/AudioTrack
按照 WebRTC 的设计,AudioSource 是一个音频源,它可以向外提供 PCM 音频帧数据,比如麦克风录制可以提供 PCM 音频帧数据,它应该是一个 AudioSource。然而在 WebRTC 实际的实现中,AudioSource 的作用相对于设计,有一些不一样的地方。这里以 WebRTC 的示例应用 peerconnection_client 的代码为例,来看 AudioSource/AudioTrack 的角色和作用。Conductor::InitializePeerConnection(原创 2021-12-28 21:16:06 · 4187 阅读 · 0 评论 -
WebRTC 音频发送和接收处理过程
曾经整理过一个 WebRTC 音频发送和接收处理的关键过程,WebRTC Audio 接收和发送的关键过程 ,不过之前的分析是基于比较老的版本做的。分析所基于的应用程序,依然选择 WebRTC 的示例应用 peerconnection_client。这里基于 WebRTC 比较新的 M96 版的代码,再来看下音频发送和接收处理过程。1. 创建 JsepTransportController#0 webrtc::JsepTransportController::JsepTransportControl原创 2021-12-28 21:14:38 · 3185 阅读 · 0 评论 -
mediasoup-demo 运行实战
mediasoup 是一个强大的 WebRTC SFU 服务。mediasoup-demo 则是 mediasoup 的一个很不错的入门演示程序。这里记录把 mediasoup-demo 跑起来的过程。操作系统平台以 Ubuntu 20.04 为例。mediasoup 主要以 JavaScript 开发,运行环境为 Node.js,它一般作为 Node.js 模块运行于 Node.js 应用中。准备环境mediasoup v3 的 安装指南 中有安装要求:node version >原创 2021-12-28 21:06:20 · 2552 阅读 · 4 评论 -
WebRTC 的版本号与代码分支
WebRTC Release Notes 中描述的版本与代码库实际的分支好之间的对应关系如 chromium 项目的博客文章 branches 所示:MilestoneChromiumBranch Pos.SkiaV8WebRTCPdfiumDevtoolsANGLEDawn984758950365m989.8-lkgr47584758475847584758974692938553m979.7-lkgr4692469246924原创 2021-12-22 23:05:05 · 4521 阅读 · 0 评论 -
基于 FFmpeg 的播放器 demo
这里的播放器演示程序用于播放一个本地文件,因而不需要关心播放网络上的媒体数据时的网络传输问题。对于播放本地媒体文件的播放器来说,所要完成的工作主要包括:解封装 -> 音频解码/视频解码 -> 对于音频来说,还需要做格式转换和重采样 -> 音频渲染和视频渲染。本文的代码位于 GitHub ffmpeg-mediaplayer-android。音频渲染音频播放通过 Android 的 OpenSL ES 接口实现。具体的代码基于 ndk-samples 中的 audio-echo 修改原创 2021-12-16 18:31:02 · 3110 阅读 · 0 评论 -
GStreamer 的调试工具
目标有时一些事情没有按照预期的运行,但从总线(bus)获得的错误消息也没有提供足够的信息。幸运地是,GStreamer 带有大量的调试信息,它们通常可以对哪里出了问题给出一些提示。这里将介绍:如何从 GStreamer 获得更多调试信息。如何把自己的调试信息打印到 GStreamer 日志里。如何获得管线图。打印调试信息调试日志GStreamer 和它的插件充满了调试追踪,即,放置在有趣的特定代码片段处,信息片段将被打印到终端,伴随着时间戳,进程,种类,源码文件,函数,和元素信息。调试输原创 2021-10-31 10:16:06 · 1946 阅读 · 0 评论 -
GStreamer 入门 - Hello,World
GStreamer 是一个用于构建媒体处理组件图(也可以称为 pipeline,或管道)的库。它支持的应用非常广泛,从简单的 Ogg/Vorbis 播放,音频/视频流到复杂的音频(混音)和视频(非线性编辑)处理。应用程序可以透明地利用编解码和过滤器技术的进步。开发者可以通过编写简单的基于一个干净、通用的接口的插件,来添加新的编解码器和过滤器。GStreamer 可以运行于所有主要的操作系统平台,如 Linux,Android,Windows,Max OS X,iOS,以及大部分 BSDs,商业 Unix原创 2021-10-22 18:53:43 · 1289 阅读 · 0 评论 -
Android OpenSL ES 对象结构
OpenSL ES 是 Khronos Group 为嵌入式系统开发的调优的免版权费、跨平台、硬件加速的音频 API 规范。Android 提供了这一 API 规范的 Android 专有实现,并允许应用程序通过 NDK 调用这些 API。Android 应用可以借助这一 API,使用 C 或 C++ 实现高性能、低延迟的音频。OpenSL ES™ 标准与 Android Java 框架中的 MediaPlayer 和 MediaRecorderAPI 提供类似的音频原创 2020-11-10 23:09:34 · 545 阅读 · 0 评论 -
WebRTC Audio Encoder/Decoder Factory 的实现
Audio encoder factory 用于创建完成各种 audio codec 编码的 encoder 对象,audio decoder factory 则用于创建完成各种 audio codec 解码的 decoder 对象。WebRTC 的 Audio Encoder Factory 接口的定义(位于 webrtc/src/api/audio_codecs/audio_encoder_factory.h)如下:namespace webrtc {// A factory that crea原创 2020-08-31 20:22:39 · 1236 阅读 · 0 评论 -
WebRTC Linux ADM 实现中的符号延迟加载机制
ADM(AudioDeviceModule)在 WebRTC 中主要用于音频数据的录制采集和音频数据的播放,这里是 WebRTC 的实时音视频系统与系统的音频硬件衔接的地方。WebRTC 为 Linux 平台实现了 ALSA 和 Pulse 等类型的 ADM AudioDeviceLinuxALSA 和 AudioDeviceLinuxPulse,它们分别基于 Linux 系统提供的库 libasound 和 libpulse 实现。WebRTC 为做到 Linux ADM 实现的高度灵活性,实现了一套符原创 2020-08-17 20:22:01 · 508 阅读 · 3 评论 -
WebRTC 的音频处理流水线
基于 RTC 场景下要解决的声音的问题,WebRTC 有一个大体如下图所示的音频处理流水线:WebRTC 的音频处理流水线,不是一次性建立起来的,而是分阶段分步骤建立的。整体而言,可以认为这个流水线分两个阶段建立,或者可以认为这个流水线分为两部分:一部分可称为静态流水线,另一部分可称为动态流水线,或者也可以称为前端和后端。静态流水线,在某个时间点建立一次,随后在整个 WebRTC 通信过程中基...原创 2019-12-24 16:09:48 · 2774 阅读 · 7 评论 -
WebRTC Audio 接收和发送的关键过程
本文基于 WebRTC 中的示例应用 peerconnection_client 分析 WebRTC Audio 接收和发送的关键过程。首先是发送的过程,然后是接收的过程。创建 webrtc::AudioState应用程序择机初始化 PeerConnectionFactory:#0 Init () at webrtc/src/pc/channel_manager.cc:121#1 In...原创 2019-07-21 12:36:09 · 5191 阅读 · 0 评论 -
[转]I,P,B帧和PTS,DTS的关系
基本概念I frame :帧内编码帧 又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象。I帧可以看成是一个图像经过压缩后的产物。P frame: 前向预测编码帧 又称predictive-frame,通过充分将低于图像序列中前面已编码帧的时间冗余信息来压缩传输数据量的编码图像,也叫预测帧;B转载 2017-09-28 17:00:28 · 294 阅读 · 0 评论 -
live555 源码分析:播放启动
本文分析 live555 中,流媒体播放启动,数据开始通过 RTP/RTCP 传输的过程。如我们在 live555 源码分析:子会话 SETUP 中看到的,一个流媒体子会话的播放启动,由 StreamState::startPlaying 完成:void OnDemandServerMediaSubsession::startStream(unsigned clientSessionId,原创 2017-09-08 19:42:10 · 1791 阅读 · 0 评论