跳转至

pplayer 播放器集成指南

pplayer 是 PPCDN 的 Web 播放器 SDK,基于 WHEP / WebRTC,内置 Simulcast/ABR、HEVC/H264 多轨支持、P2P 与 Edge 竞速、端到端时延显示、播放缓冲调节、截图与录像等能力。

本文面向要在自己页面里集成播放能力的开发者。只想快速看效果,直接打开上面的在线地址、 在 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

需要改两处:

  1. host:origin.pp-cdn.org → 任一 Edge 域名(由控制台或播放决策接口给出);
  2. 结尾:/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,不影响观看。