pplayer 播放器集成指南¶
pplayer 是 PPCDN 的 Web 播放器 SDK,基于 WHEP / WebRTC,内置 Simulcast/ABR、HEVC/H264 多轨支持、P2P 与 Edge 竞速、端到端时延显示、播放缓冲调节、截图与录像等能力。
- 在线 Demo:https://pplayer.pp-cdn.org/
本文面向要在自己页面里集成播放能力的开发者。只想快速看效果,直接打开上面的在线地址、
在 webrtc: 输入框填入 WHEP 拉流地址即可。
1. 能力概览¶
| 组件 | 作用 |
|---|---|
MediaMTXWebRTCReader |
WHEP 协议交互、WebRTC 建连、RTP 接收与 SDP 协商 |
ABREngine |
记录当前有哪些画质层级、正在播哪一层、是否由服务端自动选层 |
MMXControlClient |
WebSocket 信令通道,与服务端进行层级切换通信 |
TimeSync |
向 ppcenter 做应用层时钟校准,供端到端时延计算(可选) |
codec-capability |
检测浏览器能否解码 HEVC,决定连 h264/whep 还是 hevc/whep(可选) |
buffer-config |
播放缓冲时长(jitter buffer)配置(可选) |
自适应码率(ABR)的判定在服务端完成,SDK 只负责记录状态并执行服务端建议的切换。
2. 快速集成¶
2.1 引入¶
SDK 使用 ES module。把 SDK 文件放到你的静态资源目录,用普通 <script type="module"> 引入
入口即可,无需打包工具:
<script type="module" src="main.js"></script>
ES module 必须经 HTTP(S) 提供,直接双击
file://打开会被浏览器的 CORS 策略拒绝。
如果只需要某个组件而非整个页面,按需 import:
import { MediaMTXWebRTCReader, MMXControlClient } from './ppplayer.mjs';
import { ABREngine } from './abr-engine.mjs';
2.2 最小示例¶
import { MediaMTXWebRTCReader, MMXControlClient } from './ppplayer.mjs';
import { ABREngine } from './abr-engine.mjs';
const abrEngine = new ABREngine();
const reader = new MediaMTXWebRTCReader({
url: 'https://edge-1.edge.pp-cdn.org/{appId}/{stream}/whep',
maxBitrate: 2500, // 可选:初始带宽上限 (kbps)
onTrack: (evt) => {
const videoEl = document.getElementById('video');
if (videoEl.srcObject !== evt.streams[0]) {
videoEl.srcObject = evt.streams[0];
}
},
onConnected: () => initControlClient(reader.sessionId),
onError: (err) => console.error('播放错误:', err),
});
function initControlClient(sessionId) {
const controlClient = new MMXControlClient(reader.url, sessionId, {
onTracksInfo: (tracks, activeId) => abrEngine.setTracks(tracks, activeId),
onLayerSwitched: (id) => abrEngine.notifyLayerSwitched(id),
onABRMode: (auto) => abrEngine.notifyAutoMode(auto),
onBandwidthEstimate: (bps) => abrEngine.notifyBandwidthEstimate(bps),
});
}
不需要把
getStats()的 fps / 码率喂给 ABR——层级选择已由服务端根据链路丢包与 RTT 决定。
3. 由推流地址组装拉流地址(WHEP)¶
播放需要的是 WHEP 拉流地址,不是 WHIP 推流地址。两者只差一个字母,按下面的规则改写:
| 示例 | |
|---|---|
| 推流地址(WHIP) | https://origin.pp-cdn.org/{appId}/{stream}/whip |
| 拉流地址(WHEP) | https://edge-1.edge.pp-cdn.org/{appId}/{stream}/whep |
需要改两处:
- host:
origin.pp-cdn.org→ 任一 Edge 域名(由控制台或播放决策接口给出); - 结尾:
/whip→/whep。
固定编解码器时,在 /whep 前插入 /h264 或 /hevc:
https://edge-1.edge.pp-cdn.org/{appId}/{stream}/hevc/whep
若把
whip推流地址误填进 pplayer,它会识别出来并提示应改成的whep地址。
4. 可选:浏览器自动选择 HEVC / H264¶
开启多轨同播后,服务端同时提供 h264 与 hevc 两条独立路径,编解码器必须在建连前一次性选定,
播放中途不能像 ABR 切层那样切换 codec。
codec-capability 会检测浏览器能否解码 HEVC(优先 mediaCapabilities.decodingInfo(),回退
RTCRtpReceiver.getCapabilities('video')),并把选中的 codec 作为 URL 段插入 WHEP 地址:
.../{stream}/whep → .../{stream}/hevc/whep (支持 HEVC)
.../{stream}/whep → .../{stream}/h264/whep (不支持或未引入该模块)
- 若地址里已经显式带
/h264/whep或/hevc/whep,则跳过检测、直接使用。 - 也可用 URL 参数强制指定:
?codecType=hevc。 - 选了 HEVC 但建连失败且原因疑似 codec/SDP 协商时,同一次播放内会自动降级 H264 重连一次。
5. 可选:播放缓冲(时延 vs 抗抖动)¶
播放缓冲决定渲染前先缓存多少毫秒媒体:调大更抗抖动但时延更高,调小延迟低但更易卡顿。 这是纯本地参数,不与服务端协商。
- 默认 200ms,可用范围 100–1000ms;
- URL 参数
?bufferMs=300预设,界面滑块可实时覆盖; - 底层优先
RTCRtpReceiver.jitterBufferTarget,不支持时回退 Chrome 的playoutDelayHint。
import { applyPlayoutBuffer } from './buffer-config.mjs';
const applied = applyPlayoutBuffer(pc, 300); // 返回实际生效的 API 名,或 null
6. 可选:端到端时延(TimeSync)¶
ppobs 会在码流内嵌入经 UTC 校准的时间戳。播放端要计算「端到端时延 = 本地校时后的当前时间 −
帧内时间戳」,就必须先把自己的时钟对齐到 UTC——直接用未校正的 Date.now() 会得到错误结果。
TimeSync 向 ppcenter 做一次应用层时钟偏移估算(NTP 四时间戳算法,多轮采样取 RTT 最小的一次,
默认每 45 秒重新校准):
import { TimeSync } from './time-sync.mjs';
const timeSync = new TimeSync({ ppcenter: 'https://api.pp-cdn.org' });
timeSync.start().catch((e) => console.warn('校准不可用:', e.message));
const now = timeSync.now(); // 未完成校准时为 null
if (now !== null) {
const delayMs = now - embeddedTimestamp;
}
关键约定:now() 在校准完成前返回 null,此时应视为「还不能算时延」,不要退化成裸的
Date.now()。未加载该校准模块或 ppcenter 不可达时,播放不受影响,时延显示退回估算值。
TimeSync 也可通过 reportLatency(path, delayMs) 上报时延,path 取 'edge' 或 'p2p'。
7. P2P 加速与 Edge/P2P 竞速¶
启用后播放器同时发起两条连接,采用先出帧的那条:
- Edge 路:常规 WHEP,连到边缘节点;
- P2P 路:经 ppcenter 中转信令,直连推流端。
判定以首个可解码视频帧为准,而不是 ICE connected。NAT 穿透没有公网成功保证(对称型 NAT、 CGNAT 常失败),竞速把「先试 P2P、失败再连 Edge」的等待降为 0。
启用需要在 URL 上带齐五个参数(缺一会明确报错,而不是静默降级):
index.html?ppcenter=https://api.pp-cdn.org&appId=<appId>&streamName=<stream>&txTime=<hex>&txSecret=<hmac>
流程:先做 NAT 探测并上报 → 向 ppcenter 请求播放决策 → 返回 edge-only(只给 WHEP)或
p2p-connect(额外给 P2P 会话参数)。是否走 P2P 完全由服务端判定。
不带这些参数时,播放器直接使用输入框里的 WHEP URL,P2P 相关代码不会执行——这是仅做边缘 播放的集成方式。
txTime/txSecret由appSecret派生,不要把appSecret放进播放页或分享链接。 需要给播放端签发短时 token 时,应由你的服务端调用 ppcenter 的开放接口完成。
8. 截图与录像¶
页面控制栏提供 📷 截图与 ⏺ 录像按钮,逻辑全在 main.js 内:
- 截图:用
<canvas>抓取当前帧并下载为 PNG; - 录像:用
MediaRecorder录制当前画面为 WebM,最长 60 秒,可提前停止; - ABR Auto 模式下两者被禁用:分辨率/码率随时切换会导致截帧/录像跳变,须先手动选定画质层级。
9. 文件清单¶
| 文件 | 作用 |
|---|---|
main.js |
入口:UI 绑定、播放流程编排 |
ppplayer.mjs |
MediaMTXWebRTCReader + MMXControlClient |
abr-engine.mjs |
层级状态记录 |
time-sync.mjs |
时钟校准 |
obs-timestamp.mjs |
端到端时延计算 |
sei-timestamp.mjs |
码流内 SEI 时间戳解析(Chromium) |
codec-capability.mjs |
HEVC/H264 能力检测 |
buffer-config.mjs |
播放缓冲时长 |
play-request.mjs |
向 ppcenter 请求播放决策 |
nat-probe.mjs |
NAT 类型探测 |
playback-paths.mjs |
Edge / P2P 两条播放路径 |
playback-race-controller.mjs |
竞速状态机 |
play-decision-runner.mjs |
按决策组装竞速 |
10. API 速查¶
MediaMTXWebRTCReader(config)¶
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
url |
String | 是 | 完整 WHEP URL |
maxBitrate |
Number | 否 | 初始最大带宽 (kbps),用于 SDP b=AS |
user / pass |
String | 否 | Basic Auth |
token |
String | 否 | Bearer Token |
onTrack / onConnected / onError |
Function | 否 | 媒体轨道 / 建连完成 / 错误回调 |
属性 sessionId(只读)、pc(底层 RTCPeerConnection);方法 close()。
MMXControlClient(whepUrl, sessionId, callbacks)¶
回调:onConnected、onDisconnected、onTracksInfo(tracks, activeId)、onLayerSwitched(id)、
onABRMode(auto)、onBandwidthEstimate(bps)、onAbrRecommend(targetTrackId)。
方法:
selectLayer(trackId, reason):请求切换层级。reason用导出的常量ABR_REASON_AUTO_BANDWIDTH表示「执行服务端建议」,不会退出 Auto;其余任何值都表示用户手动选层。setABRMode(auto):把选层权交还服务端(true)或收回(false)。close():关闭连接。
ABREngine¶
属性 isAutoMode、currentTrackId、lastBandwidthEstimate;方法 setTracks、notifyLayerSwitched、
notifyManualSwitch、notifyAutoMode、setAutoMode、selectedTrackId()。
11. 常见问题¶
Q:页面白屏 / 报 CORS? ES module 必须经 HTTP(S) 加载,不能用 file:// 打开。
Q:Safari / iOS 不自动播放? 受自动播放策略限制,需一次用户手势触发播放。
Q:时延显示为空? 时钟尚未校准完成(TimeSync.now() 返回 null),稍等校准完成即可。
Q:P2P 没连上? 对称型 NAT / CGNAT 下 P2P 无法直连属正常,播放器会自动走 Edge,不影响观看。