h265web.js PRO 快速开始
h265web.js PRO已经是当前正式发布主线,并且现在免费使用。
这一页只保留最小、最实用的播放器创建流程,方便最快跑通第一个页面。
1. 需要哪些文件
浏览器运行时通常需要下面这些文件:
h265web.jsh265web_wasm.jsh265web_wasm.wasmextjs.jsextwasm.js
一个常见目录结构如下:
root/
├── index.html
├── index.js
├── resource/
│ └── demo.mp4
└── output/
├── h265web.js
├── h265web_wasm.js
├── h265web_wasm.wasm
├── extjs.js
└── extwasm.js2. 引入 SDK
<head>
<meta charset="utf-8" />
<script src="./output/h265web.js"></script>
</head>3. 创建播放器容器
<div id="canvas111"></div>4. 设置资源路径
SDK 资源路径现在支持三种写法:
- 完整 URL:
https://cdn.example.com/output/h265web_wasm.js - 站点绝对路径:
/output/h265web_wasm.js - 相对路径:
./output/h265web_wasm.js
如果希望四个 SDK 资源都从同一个目录解析,可以使用 base_url。
const playerConfig = {
player_id: 'canvas111',
base_url: './output/',
wasm_js_uri: 'h265web_wasm.js',
wasm_wasm_uri: 'h265web_wasm.wasm',
ext_src_js_uri: 'extjs.js',
ext_wasm_js_uri: 'extwasm.js',
width: '100%',
height: 480,
color: '#101318',
auto_play: true,
readframe_multi_times: -1,
ignore_audio: false
};5. 创建播放器
const ylplayer = H265webjsPlayer();
ylplayer.build(playerConfig);6. 最小必需回调
建议最先接这两个回调:
ylplayer.on_ready_show_done_callback = function () {
console.log('on_ready_show_done_callback');
};
ylplayer.video_probe_callback = function (mediaInfo) {
console.log('video_probe_callback', mediaInfo);
};
ylplayer.on_error_callback = function (error) {
console.error('player error', error);
};WebRTC 不增加第二套回调 API。请继续在 build() 前绑定原有的 probe、首帧、播放时间、loading、release、render 和 error 回调。
其他常用回调
如果你需要进度、缓存状态或者 seek 状态,可以继续接这些:
ylplayer.on_cache_process_callback = function (timestamp) {
console.log('on_cache_process_callback', timestamp);
};
ylplayer.on_load_caching_callback = function () {
console.log('on_load_caching_callback');
};
ylplayer.on_finish_cache_callback = function (data) {
console.log('on_finish_cache_callback', data);
};
ylplayer.on_play_finished = function () {
console.log('on_play_finished');
};
ylplayer.on_play_time = function (pts) {
console.log('on_play_time', pts);
};
ylplayer.on_seek_start_callback = function (seekTarget) {
console.log('on_seek_start_callback', seekTarget);
};
ylplayer.on_seek_done_callback = function (seekTarget) {
console.log('on_seek_done_callback', seekTarget);
};如果你的流里带有额外 SEI 元数据,可以单独接这类功能回调。
ylplayer.video_sei_raw_callback = function (rawSei, pts, dts, codec) {
console.log('video_sei_raw_callback', rawSei, pts, dts, codec);
};
ylplayer.video_sei_text_callback = function (text, pts, dts, codec) {
console.log('video_sei_text_callback', text, pts, dts, codec);
};7. 加载媒体
媒体地址同样支持三种写法:
- 完整 URL:
https://example.com/media/demo.mp4 - 站点绝对路径:
/resource/demo.mp4 - 相对路径:
./resource/demo.mp4
const mediaUrl = './resource/demo.mp4';
ylplayer.load_media(mediaUrl);8. WebRTC 直播播放
WHIP 是标准 WebRTC HTTP 推流信令协议,WHEP 是对应的标准拉流信令协议,因此播放器通常应当接收 WHEP 地址。
SDK 可以识别以下三种播放地址:
http://127.0.0.1/index/api/whep?app=live&stream=test
webrtc://127.0.0.1/live/test
http://127.0.0.1/index/api/webrtc?app=live&stream=test&type=play第一种是标准 WHEP,推荐使用。webrtc:// 是 SDK 兼容地址,内部转换为 WHEP。第三种是 ZLMediaKit 私有信令接口。HTTP(S) 地址负责交换 SDP,协商后的媒体仍通过 WebRTC ICE/DTLS/SRTP 传输。
自动选链不需要增加配置:
ylplayer.load_media('http://127.0.0.1/index/api/whep?app=live&stream=test');如果需要明确强制 WebRTC,继续使用原有 API,只增加普通 core 字段:
playerConfig.core = 'webrtc';
ylplayer.build(playerConfig);
ylplayer.load_media('http://127.0.0.1/index/api/whep?app=live&stream=test');ZLMediaKit 将 RTMP 转换为 WebRTC 时,应使用已经验证的时间戳策略:
[protocol]
modify_stamp=1
paced_sender_ms=0modify_stamp=1 使用 ZLMediaKit 接收数据时的系统时钟重建并平滑时间戳。modify_stamp=2 下,RTMP 输入可能仍以正常帧率完成解码,但 Chrome 会把原生 WebRTC 时间轴上的帧判定为过期帧并丢弃,画面因此出现跳动。这个配置修正的是服务端 RTMP 到 RTP 的时间轴,不是浏览器端解码选项。
原生 WebRTC 直播固定 1x,不支持 Seek;支持协商得到的音视频、仅视频和仅音频结果。标准 WebRTC 只能接收浏览器 WebRTC 栈接受的编码。未协商编码必须由媒体服务器实现可选的 h265web-rtc-encoded/v1 编码媒体传输后,才可能进入 WebCodecs/WASM 链路。
9. 开始播放
如果 auto_play 为 false,建议在首帧就绪后再调用 play()。
ylplayer.on_ready_show_done_callback = function () {
ylplayer.play();
};10. 最小可运行示例
const ylplayer = H265webjsPlayer();
ylplayer.on_ready_show_done_callback = function () {
console.log('first frame ready');
};
ylplayer.video_probe_callback = function (mediaInfo) {
console.log('mediaInfo', mediaInfo);
};
ylplayer.build({
player_id: 'canvas111',
base_url: './output/',
wasm_js_uri: 'h265web_wasm.js',
wasm_wasm_uri: 'h265web_wasm.wasm',
ext_src_js_uri: 'extjs.js',
ext_wasm_js_uri: 'extwasm.js',
width: '100%',
height: 480,
auto_play: true,
ignore_audio: false
});
ylplayer.load_media('./resource/demo.mp4');