ESP-Player 组件

[English]

ESP Player 简介

ESP Player 是乐鑫推出的嵌入式多媒体播放组件,在单个实例内完成 解封装 → 解码 → 渲染 的完整播放链路,面向资源受限的 IoT 与多媒体产品。

ESP Player 作为应用与底层 GMF 多媒体管线之间的协调层,负责状态机、命令分发与音视频同步,应用只需通过简洁的 API 设置播放源并进行播放控制,即可支持本地文件、HTTP(S) 流、HLS 以及无容器的外部帧喂入等多种场景。

功能特性

能力

说明

多种输入源

本地文件、HTTP/HTTPS 流、HLS(点播/直播,自动识别 .m3u8),以及无容器的外部帧喂入(蓝牙 A2DP 裸帧、麦克风 PCM、自定义编码帧;亦可同时喂入音视频)

丰富的格式支持

支持常见封装容器与主流音视频编码格式,覆盖音乐播放、语音提示、影音/监控播放等需求

音视频同步

支持系统时钟、以音频为主钟、以视频为主钟、无同步(freerun)四种模式,满足不同同步精度需求

完整播放控制

播放、暂停、继续、停止、Seek(毫秒级,可预置下次起播位置)、倍速播放

音视频轨选择

可分别开关音频/视频通路,多轨容器支持轨道枚举与切换(如多语言音轨)

ID3 元数据

支持解析裸 MP3 的 ID3 信息(如歌名、封面)

状态查询

可查询当前播放状态,不必只依赖事件回调

网络缓冲

基于队列水位的启动预缓冲与运行期重缓冲,改善网络流媒体播放的流畅度

事件通知

支持同步回调与异步事件队列两种模式,覆盖播放状态、缓冲、错误、轨道信息等事件

灵活裁剪与调优

可按格式和硬件在 menuconfig 中裁剪功能以降低内存;支持多实例并各自配置 task/buffer;支持注册自定义解码器

支持的媒体格式

类别

支持内容

输入源

本地文件(file:///)、HTTP/HTTPS 流、HLS(.m3u8)、外部帧模式(fill:///、block:///)

封装容器

WAV、MP4、M4A、TS、OGG、AVI、FLV、CAF;以及裸 ES 流文件(.mp3/.aac/.flac/.amr,无容器头)

音频解码

AAC、MP3、Vorbis、Opus、FLAC、AMR-NB/WB、G.711 A-law/μ-law、ALAC、ADPCM、SBC、LC3

视频解码

H.264、MJPEG

输入源与 URL

ESP Player 通过统一的 URL 指定播放源:scheme 决定输入通道,文件后缀(.codec)决定解码器。URL 分为标准 URI(本地/网络)与外部帧模式(无容器)两大类。

标准 URI(本地与网络)

类型

URL 示例

说明

本地文件

file:///sdcard/music/test.mp3

标准三斜杠形式;也可直接写裸路径 /sdcard/music/test.mp3,内部会规范为 file:///

本地无头 PCM

file:///sdcard/test.pcm?sr=48000&ch=2&bits=16

无容器头的裸 PCM 必须通过 ?query 指定采样率、声道数与位宽

HTTP(S) 流

https://host/audio/test.mp4

网络点播;支持指定端口,如 http://192.168.1.10:8080/stream.aac

HTTP(S) 基本鉴权

https://user:pass@host/audio/test.mp4

可选的 user:pass@ 基本认证

HLS

https://host/live/playlist.m3u8

路径含 .m3u8 自动识别为 HLS,支持点播与直播

网络无头 PCM

http://host/audio/test.pcm?sr=48000&ch=2&bits=16

网络裸 PCM 同样须带 ?query

外部帧模式(无容器喂帧)

由应用直接把裸帧送入解码,适用于蓝牙 A2DP 裸帧、麦克风 PCM、自定义编码帧,以及无容器的音视频双路喂入。URL 形如 fill:///name.codec[?params] 或 block:///name.codec[?params]:

  • fill:每次调用完整拷贝一帧,使用简单;

  • block:零拷贝,调用方须保证 buffer 在解码完成前有效;

  • name 无实际语义,扩展名 .codec 决定解码器;

  • 同时喂入音视频时,每帧需标明是音频还是视频。

运行后通过 esp_player_submit_frame() 送帧。常见示例:

场景

URL 示例

说明

裸 PCM

fill:///test.pcm?sr=16000&ch=1&bits=16

整帧拷贝

裸 PCM(零拷贝)

block:///test.pcm?sr=16000&ch=1&bits=16

省一次内存拷贝

AAC(标准 ADTS)

fill:///test.aac

带 ADTS 头

AAC(无 ADTS 头,如 BT A2DP)

fill:///test.aac?no_adts=1

蓝牙 A2DP 等无头 AAC

HE-AAC 裸帧

fill:///test.aac?no_adts=1&aac_plus=1

HE-AAC(AAC+)

OPUS 裸帧

fill:///test.opus?sr=16000&ch=2&frame_dms=20

指定采样率/声道/帧时长

常用 query 参数

参数

含义

sr

采样率(Hz)

ch

声道数

bits

位宽(bit)

no_adts

AAC 无 ADTS 头(如蓝牙 A2DP 裸帧)

aac_plus

HE-AAC(AAC+)

frame_dms

OPUS/LC3 帧时长

plc

SBC/LC3 丢包补偿

完整参数列表见 esp_player_set_url()。网络、HLS 等输入还需在 menuconfig 的 ESP Player → Input IO sources 中开启对应 IO,未开启的输入类型在设置 URL 时会返回错误。

典型应用场景

应用场景

说明

音频播放产品

音乐播放器、故事机、有声读物等,支持本地与网络音源、倍速与 Seek

语音提示与通知音

设备开机音、操作提示音、告警提示等,可通过多实例混音同时播放

带屏影音播放

在带 LCD + 音频的设备上播放本地或网络 MP4(H.264 + AAC),音视频同步输出

网络流媒体与直播

通过 HTTP(S)/HLS 播放点播或直播内容

蓝牙音频与自定义帧

通过外部帧模式播放蓝牙 A2DP 裸帧、麦克风 PCM 或自定义编码帧(无需容器;亦可同时喂入音视频)

多路音频混音

多个 player 实例并行解码,混音输出到同一 DAC

进阶业务用法

无缝换源

播放列表切歌、切换频道等场景,无需重新初始化播放器:依次调用 esp_player_stop() → esp_player_set_url() → esp_player_run() 即可,ESP Player 会自动拆除旧管线并按新源重建。源设置完成后也可先 Seek 再播放,用于续播或书签。

多实例混音

可创建多个 player 实例并行播放,并混音输出到同一路 DAC。适用于背景音乐与提示音/语音播报同时播放、多路音源叠加等场景。

外部帧模式

没有标准容器时,可由应用直接把裸帧喂给播放器解码播放:通过 fill:///(整帧拷贝)或 block:///(零拷贝)指定,运行后调用 esp_player_submit_frame() 送帧。单路或音视频同时喂入均可。典型场景为蓝牙 A2DP 裸帧、麦克风 PCM、自定义编码帧,以及无容器的音视频同步播放。

与周边组件的配合

ESP Player 只负责播放核心,实际方案中通常与其它 GMF 组件配合,各司其职:

组件

职责

esp_board_manager

初始化 LCD、音频 DAC、SD 卡等板级资源

esp_player

解封装、解码、音视频同步与播放控制(核心)

esp_audio_render

将解码后的音频 PCM 输出到扬声器/DAC,支持多路混音

esp_video_render

将解码后的视频帧经 LCD backend 显示到屏幕

数据流:数据源 → esp_player(解封装 → 解码 → 同步)→ esp_audio_render / esp_video_render → 扬声器 / LCD。

性能数据

以下数据来自组件 README,播放本地 SD 卡文件。内存区分为 内建 SRAM 与外扩 PSRAM (MALLOC_CAP_SPIRAM)。

测试环境

芯片

CPU

SPI RAM

Flash

ESP32-S3

240 MHz

80 MHz

QIO

ESP32-S31

320 MHz

200 MHz

QIO

ESP32-P4

400 MHz

250 MHz

QIO

音频播放性能

芯片

格式

SRAM (KB)

PSRAM (KB)

合计 (KB)

CPU (%)

启播延时 (ms)

复播延时 (ms)

ESP32-S3

MP3

8.8

91.8

100.6

5

32

27

ESP32-S3

AAC

10.1

106.4

116.5

3

19

6

ESP32-S31

MP3

7.2

91.8

99.0

4

16

6

ESP32-S31

AAC

8.6

106.4

115.0

5

16

6

ESP32-P4

MP3

7.2

91.8

99.0

3

15

3

ESP32-P4

AAC

10.1

106.4

116.5

3

11

2

  • 启播延时:esp_player_run() 到第一帧音频输出的时间

  • 复播延时:esp_player_stop() + esp_player_run()(不换 URL)到第一帧音频输出的时间

与 ADF v2.x esp_audio 对比(ESP32-S3,相同格式与测试条件;括号内为相对 esp_audio 的降幅):

格式

组件

内建 SRAM (KB)

PSRAM (KB)

合计 (KB)

CPU (%)

启播 (ms)

复播 (ms)

MP3

esp_audio

19.0

109.1

128.1

8

74

74

MP3

esp_player

8.8(53.7%)

91.8(15.9%)

100.6(21.5%)

5(37.5%)

32(56.8%)

27(63.5%)

AAC

esp_audio

35.7

182.9

218.6

5

80

80

AAC

esp_player

10.1(71.7%)

106.4(41.8%)

116.5(46.7%)

3(40.0%)

19(76.3%)

6(92.5%)

视频播放性能

ESP Player 的视频播放为端到端流程(IO + 解封装 + 解码 + 渲染),下表为组件 README 给出的最大端到端性能:

芯片

格式

最大性能

ESP32-S3

H.264

320×240@18 fps

ESP32-S31

H.264

320×240@55 fps;640×480@13 fps

ESP32-P4

H.264

320×240@68 fps;640×480@18 fps

ESP32-S3

MJPEG

320×240@28 fps

ESP32-S31

MJPEG

320×240@>120 fps;640×480@66 fps;1280×720@30 fps

ESP32-P4

MJPEG

320×240@>120 fps;640×480@91 fps;1280×720@32 fps

  • 上表 H.264 均为软件解码;MJPEG 在 ESP32-S3 为软件解码,在 ESP32-S31 / ESP32-P4 为硬件解码。

  • 视频播放对内存和算力要求较高,建议使用带 PSRAM 的 ESP32-S31、ESP32-P4;较高分辨率 MJPEG 推荐这两款的硬件 JPEG 解码。

  • 各解码器在不同芯片、分辨率下的单独解码帧率,请参考对应解码组件文档(如 esp_h264、esp_new_jpeg、esp_video_codec)。

影响帧率的主要环节

端到端帧率通常受以下环节制约(按常见影响程度排列):

环节

说明

视频解码

通常是主要瓶颈。软件解码(如 H.264、软解 MJPEG)分辨率越高开销越大;ESP32-P4/S31 的硬件 JPEG 解码可大幅降低 CPU 占用、提升帧率

显示 / 渲染

解码输出多为 YUV,送屏前常需色彩空间转换(如 YUV→RGB565)并将整帧搬运到屏幕,受 LCD 接口带宽(SPI/8080/RGB/MIPI-DSI)与刷新率限制,高分辨率下尤为明显

输入 / IO

本地播放受 SD 卡/Flash 读取速度影响;网络播放受带宽、时延与抖动影响

内存带宽

帧缓冲较大时多放在 PSRAM,其读写带宽与 Cache 命中会直接影响解码与渲染速度

任务调度与同步

任务优先级、双核分配、缓冲水位与音视频同步策略都会影响实际吞吐

内存优化建议

  • 在 menuconfig 中只开启实际使用的封装容器、解码器与板载 codec,未使用的一律关闭;

  • 纯本地音频场景可关闭视频通路与网络缓冲相关配置;

  • 开启 PSRAM(SPIRAM、FREERTOS_TASK_CREATE_ALLOW_EXT_MEM)可将较大的栈和缓冲放到片外,降低内建 SRAM 占用;默认 player 任务栈已放到 PSRAM;

  • 多实例且各路资源差异较大时,可对各 handle 单独配置 task 与 buffer。

如何使用 ESP Player

ESP Player 托管在 GitHub。可以通过在工程中输入以下命令 idf.py add-dependency “espressif/esp_player”,将 ESP Player 添加到你的工程中。

基本使用流程为:初始化播放器并配置音/视频渲染 handle → 设置播放源(AV mask、URL、同步模式)→ 开始播放,并通过事件回调处理播放结束、错误等状态。

组件 examples 文件夹下提供了可运行的示例工程,建议在使用前先参考和调试:

更多 API 说明、URL 格式与高级用法请参考 README。

FAQ

ESP Player 的能力边界是什么?

ESP Player 只负责 播放 链路(解封装 → 解码 → 渲染),本身不包含网络传输协议栈。它既可以直接播放本地文件、HTTP(S)/HLS 流,也可以通过外部帧模式接收上游送入的裸帧进行解码播放。因此,涉及 实时双向通话、协议信令交互或推拉流(如 SIP、RTSP、RTMP、WebRTC)时,由对应的传输/通信组件负责收发媒体数据,ESP Player 与其属于不同环节,可按需配合使用。

ESP Player、Audio Simple Player 与裸 GMF 如何选择?

三者都能“播放/处理媒体”,但封装程度与定位不同:Audio Simple Player(esp_audio_simple_player)是轻量的纯音频播放器,解码/变换后经回调把 PCM 交给应用;ESP Player(esp_player)是端到端的完整音视频播放器;裸 GMF 则是直接基于 esp-gmf 的 pipeline/element/task 自行编排,灵活度最高但需自行实现各种能力。

能力

Audio Simple Player

ESP Player

裸 GMF(自建)

纯音频本地 / HTTP

支持

支持

支持(自搭)

音视频(MP4 等)

不支持

支持

支持(自搭)

HLS

不支持

支持

需自集成

Seek

不支持

支持(毫秒级)

自实现

暂停 / 继续

支持

支持

自实现

音视频同步

—(仅音频)

支持(4 种模式)

自实现

网络缓冲 / 重缓冲

弱

支持

自实现

多轨 / 换轨

不支持

支持

自实现

fill/block 喂帧

不支持

支持

可自搭

输出方式

PCM 回调

render 直出(扬声器/屏幕)

任意

自定义处理元素

支持(注册 element)

支持(注册自定义解码器 element)

支持(任意 element)

多 pipeline / 混音

不支持(单链)

单实例(音视频一体)

支持

开发量

低

低

高(需自行编排)

简言之:只做音频播放,无额外能力需求选 Audio Simple Player;要开箱即用的完整音视频播放选 ESP Player;需要非标准、高度定制的媒体处理链路才考虑**裸 GMF 自建**。若还要多路混音、播放列表,或与采集/SIP/RTSP 等服务直连,见 ESP-Player-Service 组件。

支持哪些芯片?

支持乐鑫全系列芯片。纯音频播放对资源要求较低,可在更广泛的芯片上运行;视频播放对内存和算力要求较高,建议使用带 PSRAM 的 ESP32-S3、ESP32-S31、ESP32-P4 等芯片。若需要较高分辨率的 MJPEG 视频,推荐使用支持硬件 JPEG 解码的 ESP32-P4/S31。

如何降低内存占用?

参考上文 “内存优化建议”:在 menuconfig 中按实际格式和硬件裁剪容器/解码器/codec,关闭不需要的视频通路与网络缓冲,并开启 PSRAM(默认任务栈已在 PSRAM)。

相关资源