@kwai-video-team/kwai-player-web
Version:
<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
1,500 lines (1,154 loc) • 54.9 kB
Markdown
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [简介](#%E7%AE%80%E4%BB%8B)
- [功能列表](#%E5%8A%9F%E8%83%BD%E5%88%97%E8%A1%A8)
- [音视频格式支持](#%E9%9F%B3%E8%A7%86%E9%A2%91%E6%A0%BC%E5%BC%8F%E6%94%AF%E6%8C%81)
- [浏览器适配](#%E6%B5%8F%E8%A7%88%E5%99%A8%E9%80%82%E9%85%8D)
- [桌面端浏览器](#%E6%A1%8C%E9%9D%A2%E7%AB%AF%E6%B5%8F%E8%A7%88%E5%99%A8)
- [Android端浏览器](#android%E7%AB%AF%E6%B5%8F%E8%A7%88%E5%99%A8)
- [iOS端浏览器](#ios%E7%AB%AF%E6%B5%8F%E8%A7%88%E5%99%A8)
- [H5 功能说明](#h5-%E5%8A%9F%E8%83%BD%E8%AF%B4%E6%98%8E)
- [快速开始](#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B)
- [如何使用](#%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8)
- [NPM方式接入](#npm%E6%96%B9%E5%BC%8F%E6%8E%A5%E5%85%A5)
- [导出包类型](#%E5%AF%BC%E5%87%BA%E5%8C%85%E7%B1%BB%E5%9E%8B)
- [组件示例](#%E7%BB%84%E4%BB%B6%E7%A4%BA%E4%BE%8B)
- [原生库](#%E5%8E%9F%E7%94%9F%E5%BA%93)
- [React](#react)
- [Vue2](#vue2)
- [Vue3](#vue3)
- [需要参考的文档:](#%E9%9C%80%E8%A6%81%E5%8F%82%E8%80%83%E7%9A%84%E6%96%87%E6%A1%A3)
- [Server-side-rendering (SSR)](#server-side-rendering-ssr)
- [CORS](#cors)
- [播放H.265/KVC/VVC说明](#%E6%92%AD%E6%94%BEh265kvcvvc%E8%AF%B4%E6%98%8E)
- [wasm解码器兼容性:](#wasm%E8%A7%A3%E7%A0%81%E5%99%A8%E5%85%BC%E5%AE%B9%E6%80%A7)
- [wasm解码器性能优化](#wasm%E8%A7%A3%E7%A0%81%E5%99%A8%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96)
- [插件](#%E6%8F%92%E4%BB%B6)
- [插件使用](#%E6%8F%92%E4%BB%B6%E4%BD%BF%E7%94%A8)
- [向插件传入配置](#%E5%90%91%E6%8F%92%E4%BB%B6%E4%BC%A0%E5%85%A5%E9%85%8D%E7%BD%AE)
- [获取插件实例](#%E8%8E%B7%E5%8F%96%E6%8F%92%E4%BB%B6%E5%AE%9E%E4%BE%8B)
- [获取所有插件实例](#%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E6%8F%92%E4%BB%B6%E5%AE%9E%E4%BE%8B)
- [内置插件说明](#%E5%86%85%E7%BD%AE%E6%8F%92%E4%BB%B6%E8%AF%B4%E6%98%8E)
- [I18nPlugin](#i18nplugin)
- [LoggerPlugin](#loggerplugin)
- [WaterMarkPlugin(水印)](#watermarkplugin%E6%B0%B4%E5%8D%B0)
- [原生库 示例](#%E5%8E%9F%E7%94%9F%E5%BA%93-%E7%A4%BA%E4%BE%8B)
- [Vue 示例](#vue-%E7%A4%BA%E4%BE%8B)
- [React 示例](#react-%E7%A4%BA%E4%BE%8B)
- [ControlsPlugin](#controlsplugin)
- [PlayInfoPlugin](#playinfoplugin)
- [PrefetchPlugin](#prefetchplugin)
- [PreviewPlugin](#previewplugin)
- [HotkeyPlugin](#hotkeyplugin)
- [RotatePlugin](#rotateplugin)
- [AlphaVideoPlugin](#alphavideoplugin)
- [API](#api)
- [active](#active)
- [type](#type)
- [自定义插件](#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8F%92%E4%BB%B6)
- [利用钩子](#%E5%88%A9%E7%94%A8%E9%92%A9%E5%AD%90)
- [注册销毁插件](#%E6%B3%A8%E5%86%8C%E9%94%80%E6%AF%81%E6%8F%92%E4%BB%B6)
- [插件实现示例](#%E6%8F%92%E4%BB%B6%E5%AE%9E%E7%8E%B0%E7%A4%BA%E4%BE%8B)
- [API](#api-1)
- [原生库属性](#%E5%8E%9F%E7%94%9F%E5%BA%93%E5%B1%9E%E6%80%A7)
- [src](#src)
- [controls](#controls)
- [showInfoPanel](#showinfopanel)
- [productName](#productname)
- [bizData](#bizdata)
- [disableHotkey](#disablehotkey)
- [disableDownload](#disabledownload)
- [disableAdaptive](#disableadaptive)
- [currentLevel](#currentlevel)
- [nextLevel](#nextlevel)
- [audioTrack](#audiotrack)
- [totalVideoFrames](#totalvideoframes)
- [currentVideoFrame](#currentvideoframe)
- [showProgress](#showprogress)
- [API](#api-2)
- [constructor(id: string, data?: Partial<KwaiPlayer.KwaiPlayerData>)](#constructorid-string-data-partialkwaiplayerkwaiplayerdata)
- [destroy(): void](#destroy-void)
- [isFullscreen(): boolean;](#isfullscreen-boolean)
- [requestFullscreen: (type?: "window" | "system" | undefined) => void;](#requestfullscreen-type-window--system--undefined--void)
- [exitFullscreen: (type?: "window" | "system" | undefined) => void;](#exitfullscreen-type-window--system--undefined--void)
- [requestPictureInPicture(): Promise<PictureInPictureWindow> | undefined;](#requestpictureinpicture-promisepictureinpicturewindow--undefined)
- [screenshot(): Promise<ImageData | void>](#screenshot-promiseimagedata--void)
- [refresh(): void;](#refresh-void)
- [getPluginInstance<pluginLabel extends keyof PluginMap>(label: string | pluginLabel): PluginMap[pluginLabel] | undefined;](#getplugininstancepluginlabel-extends-keyof-pluginmaplabel-string--pluginlabel-pluginmappluginlabel--undefined)
- [KwaiPlayer.register(plugin: typeof PluginModule, method: RegisterMethod = 'append');](#kwaiplayerregisterplugin-typeof-pluginmodule-method-registermethod--append)
- [KwaiPlayer.deregister(plugin: typeof PluginModule | string);](#kwaiplayerderegisterplugin-typeof-pluginmodule--string)
- [createSubContainer(layer = KwaiPlayerLayer.DEFAULT): HTMLDivElement](#createsubcontainerlayer--kwaiplayerlayerdefault-htmldivelement)
- [原生js组件事件](#%E5%8E%9F%E7%94%9Fjs%E7%BB%84%E4%BB%B6%E4%BA%8B%E4%BB%B6)
- [manifestparsed](#manifestparsed)
- [levelswitching](#levelswitching)
- [levelswitched](#levelswitched)
- [levelswitchplaying](#levelswitchplaying)
- [levelswitchfailed](#levelswitchfailed)
- [audiotrackswitching](#audiotrackswitching)
- [audiotrackswitched](#audiotrackswitched)
- [React组件与原生js组件差异](#react%E7%BB%84%E4%BB%B6%E4%B8%8E%E5%8E%9F%E7%94%9Fjs%E7%BB%84%E4%BB%B6%E5%B7%AE%E5%BC%82)
- [React事件对应表](#react%E4%BA%8B%E4%BB%B6%E5%AF%B9%E5%BA%94%E8%A1%A8)
- [Vue组件与原生js组件差异](#vue%E7%BB%84%E4%BB%B6%E4%B8%8E%E5%8E%9F%E7%94%9Fjs%E7%BB%84%E4%BB%B6%E5%B7%AE%E5%BC%82)
- [在页面中引入](#%E5%9C%A8%E9%A1%B5%E9%9D%A2%E4%B8%AD%E5%BC%95%E5%85%A5)
- [错误码](#%E9%94%99%E8%AF%AF%E7%A0%81)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# 简介
快手Web播放组件基于HTML5的[HTMLVideoElement(\<video \/>)](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLVideoElement)。
提供适配Vue2/Vue3/React/原生JS的多个版本接入。
同时支持桌面端和移动端浏览器环境。
npm:https://www.npmjs.com/package/@kwai-video-team/kwai-player-web
Demo和文档:https://s2-10895.kwimgs.com/kos/nlav10895/kwaiplayer-web/index.html
## 功能列表
| 功能点 | 功能说明 |
| :-------------- | :--------------------------------------------------------------------------- |
| 支持协议 | 支持 FLV、HLS、MP4、WebRTC、裸流 等丰富的音视频格式 |
| 播放-URL | 支持网络视频的 URL 方式播放 |
| 播放-Manifest | 支持快手协议,更多咨询问题请联系我们。 |
| 播放-本地文件 | 本地文件方式播放 |
| 播放-videoID | 支持vid播放(开发中) |
| 基本功能 | 支持开始、结束、暂停、自动播放、循环播放、断点续播、重播、倍速等播放控制功能 |
| 清晰度切换-手动 | 支持开始、结束、暂停、自动播放、循环播放、断点续播、重播、倍速等播放控制功能 |
| 清晰度切换-平滑 | 配合GOP对齐HLS/快手协议,支持无停顿平滑切换 |
| 清晰度切换-自动 | 配合GOP对齐HLS/快手协议,支持根据网速自动切换清晰度 |
| 预览图 | 支持预览图功能 |
| 弹幕防挡 | 支持弹幕防挡 |
| 水印 | 支持在播放组件中添加自定义水印 |
| H.265支持 | 快手web端265解决方案 |
| 自定义启播时间 | 支持自定义视频开启播放的时间 |
| 多实例 | 支持在一个界面添加多个播放器同时播放 |
| 边下边播 | 支持视频播放的同时缓存下载后面的内容 |
| HLS标准加密 | 支持基于 HLS 提供的 AES encryption 方案,使用密钥对视频数据加密 |
| DRM | widevine |
| 逐帧播放 | MP4支持上下帧逐帧播放 |
## 音视频格式支持
| 协议 | H.264 | H.265 | H.266 | AV1 | KVC | AAC | MP3 | Opus |
| ------------- | :---- | :---------------: | :---: | :--------: | :---: | :---: | :---: | :---: |
| flv + flv切片 | 支持 | 依赖浏览器 + wasm | x | 依赖浏览器 | x | x | 支持 | x |
| mp4 | 支持 | 依赖浏览器 + wasm | wasm | 依赖浏览器 | wasm | wasm | 支持 | 支持 |
| HLS | 支持 | 依赖浏览器 + wasm | x | x | wasm | x | 支持 | - |
| 裸流 | 支持 | 依赖浏览器 + wasm | x | 依赖浏览器 | wasm | x | - | - |
| webRTC直播 | 支持 | - | x | - | - | - | - | - |
YUV支持: 8bit/10bit yuv420p/yuv422p/yuv444p。YUV文件命名需要符合模板:name_WxH_FPS_BITDEPTH_CHROMA.yuv。
> 面向普通用户的场景不推荐使用wasm解码器。如果要使用H.265/AV1编码,推荐采用快手web端H.265整体解决方案,更多咨询问题请联系我们。
## 浏览器适配
### 桌面端浏览器
| 浏览器 | MP4 | FLV | HLS |
| ----------- | :--- | :---: | :---: |
| Chrome 39+ | 支持 | 支持 | 支持 |
| Edge win10 | 支持 | 支持 | 支持 |
| IE11+ | 支持 | 支持 | 支持 |
| Firefox 42+ | 支持 | 支持 | 支持 |
| Safari 8+ | 支持 | 支持 | 支持 |
### Android端浏览器
| 浏览器 | MP4 | FLV | HLS |
| ---------- | :--- | :---: | :---: |
| Chrome 39+ | 支持 | 支持 | 支持 |
| 微信 | 支持 | 支持 | 支持 |
| Edge | 支持 | 支持 | 支持 |
### iOS端浏览器
| 浏览器 | MP4 | FLV | HLS |
| ------ | :--- | :----: | :---: |
| Chrome | 支持 | 不支持 | 支持 |
| 微信 | 支持 | 不支持 | 支持 |
| Safari | 支持 | 不支持 | 支持 |
| Edge | 支持 | 不支持 | 支持 |
## H5 功能说明
| 功能 | 桌面端 | Android | iOS |
| -------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------- | :---------------------------------------------------------------------------- |
| 全屏 | 支持 | 不支持 | 1. iOS 10以下版本的Safari浏览器无法禁止视频自动全屏播放;<br>2. 仅支持网页全屏 |
| 自动播放 | 播放组件会按照以下规则尝试自动播放:有声音自动播放,失败后尝试静音自动播放,失败后不自动播放。<br>1. Chrome遵循以下播放规则:https://developer.chrome.com/blog/autoplay/<br>2. Safari依赖浏览器设置 | 策略同桌面端 | 策略同桌面端 |
| 音量 | 支持 | 依赖设备音量 | 依赖设备音量 |
| 倍速 | 支持 | 部分移动端浏览器不支持设置倍速 | 不支持 |
# 快速开始
播放组件提供原生js组件,React组件,Vue2/Vue3组件。可以通过NPM使用或者在页面引入的方式引入。
## 如何使用
### NPM方式接入
```js
npm i @ks-video/kwai-player-web
import KwaiPlayer from '@ks-video/kwai-player-web';
player = new KwaiPlayer('#player', {
src: 'http://xxxx.mp4',
autoplay: true,
productName: 'KPN', // 用于区分上报
});
// 上报数据如果不是国内生产环境,需要设置上报插件环境,查看LoggerPlugin插件的说明
```
### 导出包类型
**推荐使用** 默认导出(full)或各框架对应的导出包含了大部分常用插件,
基础导出(basic)减少了基本控件以外的插件,对于不需要使用过多功能的情况使用
| 类型 | npm引用 | 备注 | ES5 UMD | ES6 UMD | ES6 Module |
| ---------------- | ------------------------------------ | ----------------------------------- | ------- | ------- | ---------- |
| 完整版-原生库 | @ks-video/kwai-player-web | 包含完整功能,原生库 | ✓ | ✕ | ✓ |
| 完整版-Vue2版本 | @ks-video/kwai-player-web/vue2 | 包含完整功能,vue2版本 | ✓ | ✕ | ✓ |
| 完整版-Vue3版本 | @ks-video/kwai-player-web/vue3 | 包含完整功能,vue3版本 | ✕ | ✓ | ✓ |
| 完整版-React版本 | @ks-video/kwai-player-web/react | react | ✓ | ✕ | ✓ |
| 小包版-原生库 | @ks-video/kwai-player-web/mini | 不包含控制条的最小功能包,原生库 | ✓ | ✕ | ✓ |
| 小包版-vue2 | @ks-video/kwai-player-web/vue2-mini | 不包含控制条的最小功能包,vue2版本 | ✓ | ✕ | ✓ |
| 小包版-vue3 | @ks-video/kwai-player-web/vue3-mini | 不包含控制条的最小功能包 vue3版本 | ✕ | ✓ | ✓ |
| 小包版-react | @ks-video/kwai-player-web/react-mini | 不包含控制条的最小功能包,react版本 | ✓ | ✕ | ✓ |
| 基础版-原生库 | @ks-video/kwai-player-web/basic | 包含控制条的最小功能包,原生库 | ✓ | ✕ | ✓ |
> 各包包含插件情况、详见插件文档
## 组件示例
### 原生库
```js
import KwaiPlayer from '@ks-video/kwai-player-web';
player = new KwaiPlayer('#player', {
src: 'http://xxxx.mp4',
autoplay: true,
});
```
```html
<body>
<div id="player"></div>
</body>
```
### React
```js
import KwaiPlayerReact from '@ks-video/kwai-player-web/react';
function App() {
const videoRef = useRef(null);
useEffect(() => {
if (videoRef.current) {
videoRef.current.play();
}
}, [videoRef]);
function onLoadedMetadata(){
const duration = videoRef?.current?.duration//总时长
const videoheight = videoRef?.current?.videoHeight//视频资源的高度
const videowidth = videoRef?.current?.videoWidth//视频资源的宽度
console.log(duration, videoheight, videowidth)
}
function onerror(val){
console.log(val)
}
function onTimeUpdate() {
console.log(videoRef?.current?.currentTime);//打印当前时间
}
return (
<div className="App">
<KwaiPlayerReact
className="kwai-player-react"
ref={videoRef}
src={'http://xxxx.mp4'}
autoPlay={true}
controls={true}
onTimeUpdate={onTimeUpdate}
preload="auto"
onError={onerror}
onLoadedMetadata={onLoadedMetadata}
></KwaiPlayerReact>
</div>
);
}
```
### Vue2
```js
import KwaiPlayerVue2 from '@ks-video/kwai-player-web/vue2';
import poster from '../xxxx@2x.png'
export default {
name: 'App',
data() {
return {
src: 'http://xxxx.mp4',
autoplay: true,
controls:true,
loop:true,
poster:poster
};
},
components: {
'kwai-player-vue2': KwaiPlayerVue2,
},
methods:{
error(val){
console.log(val)
},
loadedmetadata(){
let duration = this.$refs['videoRef'].getDuration()
let videoheight = this.$refs['videoRef'].getVideoHeight()
let videowidth = this.$refs['videoRef'].getVideoWidth()
},
timeupdate(){
console.log(this.$refs['videoRef'].getCurrentTime())//当前时间
}
}
};
```
```html
<kwai-player-vue2
class="player"
:src="src"
:controls="controls"
:autoplay="autoplay"
:loop="loop"
:poster="poster"
@error="error"
@loadedmetadata="loadedmetadata"
@timeupdate="timeupdate"
>
</kwai-player-vue2>
```
### Vue3
```js
import KwaiPlayerVue3 from '@ks-video/kwai-player-web/vue3';
import poster from '../xxxx@2x.png'
import {ref} from'vue'
export default {
name: "demo",
components: {
'kwai-player-vue3': KwaiPlayerVue3,
},
setup(){
const src = ref('https://playurl')
const autoplay = ref(true)
const controls = ref(true)
const loop = ref(true)
const videoRef = ref(null)
const timeupdate = ()=>{
console.log(videoRef._value.getCurrentTime())//当前时间
}
const loadedmetadata = ()=>{
const duration = videoRef._value.getDuration()
const videoheight = videoRef._value.getVideoHeight()
const videowidth = videoRef._value.getVideoWidth()
}
const error = (val)=>{
console.log(val)
}
return {
videoRef,
src,
autoplay,
controls,
poster,
timeupdate,
loadedmetadata,
error
}
}
}
```
```html
<kwai-player-vue3
class="player"
:src="src"
:controls="controls"
:autoplay="autoplay"
:loop="loop"
:poster="poster"
@error="error"
@loadedmetadata="loadedmetadata"
@timeupdate="timeupdate"
/>
```
### 需要参考的文档:
播放组件的属性、API及事件参考了HTMLVideoElement的实现。
1. [HTMLVideoElement](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLVideoElement)
2. [HTMLMediaElement](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement)
## Server-side-rendering (SSR)
可以安全地在Node中require此库
## CORS
视频资源必须允许GET请求,且包含[CORS](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS)响应头。
## 播放H.265/KVC/VVC说明
> 面向普通用户的场景不推荐使用wasm解码器。如果要使用H.265/AV1编码,推荐采用快手web端H.265整体解决方案,更多咨询问题请联系我们。
浏览器不支持H.265/KVC/VVC解码时,会采用wasm解码器。
采用wasm解码器时,上层业务是无感知的。
### wasm解码器兼容性:
chrome 67+
### wasm解码器性能优化
播放组件在使用wasm解码器器时支持多线程解码及SIMD,且会根据浏览器能力开启对应的加速解码功能。
多线程解码用到了SharedArrayBuffer,chrome 92+需要对播放页增加两个响应头,推荐添加
```
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
```
[chrome 92相关说明](https://developer.chrome.com/blog/enabling-shared-array-buffer/)
[Cross-Origin-Opener-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy)
[Cross-Origin-Embedder-Policy](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy)
播放页中的部分标签可能需要添加[crossorigin](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Attributes/crossorigin)属性
> 页面增加这两个头会导致无法加载跨域资源。以下是以图片为例的解决方案。
>
> 1. 解决方案A:在图片的响应头中添加:Cross-Origin-Resource-Policy: cross-origin;
> 2. 解决方案B:img标签中增加crossorigin属性
# 插件
播放组件实现了插件系统,用与解耦功能,增加各功能之间的组合能力。
播放组件已内置了很多插件,如**控制条**、**水印**、**信息面板**等插件。
> 播放组件中已经生成了多个版本的插件组合产物
| 插件名称 | 功能 | 完整版 | 小包版 | 基础版 |
| ----------------- | ------------ | ------ | ------ | ------ |
| I18nPlugin | 国际化 | ✓ | ✓ | ✕ |
| PlayInfoPlugin | 信息面板 | ✓ | ✓ | ✓ |
| ControlsPlugin | 控制条 | ✓ | ✕ | ✓ |
| LoggerPlugin | 日志上报 | ✓ | ✓ | ✓ |
| WaterMarkPlugin | 水印 | ✓ | ✕ | ✕ |
| PrefetchPlugin | 预热 | ✓ | ✕ | ✕ |
| PreviewPlugin | 进度条预览图 | ✓ | ✕ | ✕ |
| HotkeyPlugin | 快捷键 | ✓ | ✕ | ✕ |
| RotatePlugin | 旋转画面 | ✓ | ✕ | ✕ |
| AlphaVideoPlugin | 透明视频 | ✓ | ✕ | ✕ |
## 插件使用
### 向插件传入配置
通过player的plugins参数传入配置
数据格式:
```
{
'插件名称': Record<string, any>
}
```
示例:
```
import { KwaiPlayer } from '@ks-video/kwai-player-web';
// 示例,设置语言插件为英文
new KwaiPlayer('#player-1', {
plugins: {
I18nPlugin: {
lang: 'en',
}
}
}
```
### 获取插件实例
```ts
const plugin = player.getPluginInstance('I18nPlugin');
```
### 获取所有插件实例
```ts
const plugin = player.getAllPlugins();
```
## 内置插件说明
### I18nPlugin
多语言功能,默认包含中英,根据浏览器语言自动切换
参数:
plugins: {
I18nPlugin: {
lang?: string // 选择语言名
langDict?: { // 多语言字典
lang: string, // 语言名
map: Record<string, Record<string, string>> // 字典内容,区分插件 Record<插件名, Record<字典key, 字典value>>
}[],
}
}
```ts
import { KwaiPlayer } from '@ks-video/kwai-player-web;
new KwaiPlayer('#player-1', {
plugins: {
I18nPlugin: {
lang: 'en'
}
}
}
```
通过传入插件配置的方式新增语言
```ts
import { ControlsPluginLabel, LangDict, ControlsLangDictKey } from '@ks-video/kwai-player-web;
const langDict:LangDict = {
{
lang: 'en', // 指定语言
map: {
[ControlsPluginLabel]: { // 用于控制条插件
[ControlsLangDictKey.PLAY]: 'Play', // 指定对应key显示的文字
[ControlsLangDictKey.PAUSE]: 'Pause',
}
}
}
};
new KwaiPlayer('#player-1', {
plugins: {
I18nPlugin: {
langDict,
}
}
}
```
### LoggerPlugin
播放组件数据上报
### WaterMarkPlugin(水印)
可以通过在播放器容器中增加子元素的方式添加水印
> 水印<div>必须包含属性 kwai-player-watermark
#### 原生库 示例
```html
<style>
.wm {
background-repeat: repeat;
background-image: url(data:image/svg+xml;base64,.......);
}
</style>
<div id="player">
<div class="wm" kwai-player-watermark></div>
</div>
```
#### Vue 示例
```js
<style>
.wm {
background-repeat: repeat;
background-image: url(data:image/svg+xml;base64,.......)
}
</style>
<kwai-player-vue2
class="player"
:src="src"
:autoplay="autoplay"
>
<div className="wm" kwai-player-watermark></div>
</kwai-player-vue2>
```
#### React 示例
```js
<style>
.wm {
background-repeat: repeat;
background-image: url(data:image/svg+xml;base64,.......)
}
</style>
<KwaiPlayerReact
className="kwai-player-react"
src={src}
autoPlay={true}
>
<div className="wm" kwai-player-watermark="true"></div>
</KwaiPlayerReact>
```
### ControlsPlugin
实现了默认控制条 UI 交互
参数:
```
plugins: {
ControlsPlugin: {
danmakuControls?: DanmakuControlsPos, // 弹幕插件在非全屏时显示的位置 / 依赖弹幕插件
danmakuControlsFull?: DanmakuControlsPos, // 弹幕插件在全屏时的显示位置 / 依赖弹幕插件
showBottomButtonBar?: boolean, // 是否按时下方播放按钮
showProgress?: boolean, // 是否显示进度条
showTime?: boolean, // 是否显示播放时间
showWindowFullScreen?: boolean, // 是否显示窗口全屏按钮
seekMode?: 'onDragChange' | 'onDragEnd', // seek 模式,拖动进度条实时seek/拖动进度条完成时seek
showProgressTime?: boolean, // 是否在进度条上显示时间,默认不显示
showPlaybackRate?: boolean, // 是否展示倍速功能
showContextMenu?: boolean, // 是否展示右键菜单功能
stateChange?: (data: StateChangeData) => void, // UI状态回调
}
}
type StateChangeData = { type: 'controlsVisibility', value: boolean }; // 控制条显示隐藏状态变化
```
### PlayInfoPlugin
提供播放信息面板
### PrefetchPlugin
提供播放地址链接预热功能,用于不自动播放且不预加载情况下的起播速度
### PreviewPlugin
增加控制条上的预览画面,需要指定预览图地址;需要配合streamlake服务使用
```ts
import { KwaiPlayer } from '@ks-video/kwai-player-web;
const player = new KwaiPlayer('#player-1' {
src: 'xxx',
previewUrl: 'xxxx', // 设置预览图url
});
```
### HotkeyPlugin
可利用键盘快进快退、暂停播放、音量高低调节
| 键位 | 单击 | 长按 |
| ---------- | ------------------------------------------------------------- | ----------------------------------- |
| ArrowRight | 前进 10s | 3 倍速 |
| ArrowLeft | 回退进度的两百分之 1 秒(若大于 10s 则为 10s、小于 5s 则为 5s) | 每 100ms 出发一次回退(时长如单击) |
| ArrowUp | 增加音量的 5% | 每 100ms 增加音量的 5% |
| ArrowDown | 减少音量的 5% | 每 100ms 减少音量的 5% |
| Space | 播放/暂停 | -- |
### RotatePlugin
画面旋转插件
参数:
```
// 配置类型
type OptionType = 'mirror' | 'counterClockwise' | 'clockwise';
type OptionValue = 'pc' | 'mobile' | 'always';
type OptionShow = OptionValue | Record<OptionType, OptionValue>;
type RotatePluginOption = {
showInPlayBar?: OptionShow,
showInContextMenu?: OptionShow,
svgRaw?: {
mirror?: string,
counterClockwise?: string,
clockwise?: string,
}
}
// 配置传入
plugins: {
AlphaVideoPlugin: RotatePluginOption,
}
```
### AlphaVideoPlugin
透明视频插件,支持透明视频的播放
参数:
```
plugins: {
AlphaVideoPlugin: {
active?: boolean, // 是否启动。默认:undefined,自动识别
type?: undefined | "2:1" | "1:1", // 透明视频类型。默认:undefined,自动识别
}
}
```
#### API
##### active
set: 是否启动。默认:undefined,自动识别
#### type
set: 透明视频类型。默认:undefined,自动识别
可选值:undefined | "2:1" | "1:1"
## 自定义插件
可以自定义插件
+ 插件名唯一,注册同名插件仅最后一次注册生效,故可采用这种方法替换已有插件。
+ 例如:自定义名称为ControlsPlugin的插件,注册在完整包中,会替换默认的播控UI
+ 自定义插件实现需要继承PluginModule或其他基础插件的抽象类
+ 自定义插件需要在实例化之前完成注册
+ 注册方法仅需要执行一次
+ 注销方法和销毁播放器无关,正常情况不需要调用
播放组件中的DOM分为以下三层,添加子容器需要指定一个层级,从下向上依次为VIDEO/VIDEO_INTERACTIVE/DEFAULT
### 利用钩子
- 挂载前
```ts
beforeInstall(player: IKwaiPlayer, options?: any): void
```
数据准备完成,还未开始实例化播放内核前触发
- 挂载后
```ts
afterInstall(player: IKwaiPlayer, options?: any): void
```
实例化播放内核后触发
- 销毁前
```ts
beforeUninstall(player: IKwaiPlayer): void
```
销毁播放内核前触发
- 销毁后
```ts
afterUninstall(player: IKwaiPlayer): void
```
销毁播放内核后触发
### 注册销毁插件
实现一个插件后需要在**KwaiPlayer**对象上注册
1. 注册插件方法只用调用一次
2. 销毁播放器不需要调用注销
```ts
KwaiPlayer.register(WaterMarkPlugin); //注册
KwaiPlayer.deregister(WaterMarkPlugin); //注销
```
### 插件实现示例
```ts
import { IKwaiPlayer, KwaiPlayerEvent, PluginModule } from '@ks-video/kwai-player-web';
// 新插件替换已有的logger插件
// export default class ExamplePlugin extends LoggerPluginModule {
// 新插件与已有插件共存
export default class ExamplePlugin extends PluginModule {
private _player: IKwaiPlayer | undefined;
/**
* 播放器实例化前钩子
* @param player 播放器实例
* @param options 实例化播放器时指定的当前插件的参数
*/
public beforeInstall(player: IKwaiPlayer, options?: any | undefined): void {
this._player = player;
console.log('beforeInstall', options);
// 播放事件处理
this._player.on(KwaiPlayerEvent.REPORT, this._onReport);
// 切换视频事件处理
this._player.on(KwaiPlayerEvent.ATTRIBUTE_CHANGE_SRC, this._onSrcChange);
}
/**
* 播放器实例化后钩子
* @param player 播放器实例
* @param options 实例化播放器时指定的当前插件的参数
*/
public afterInstall(_player: IKwaiPlayer, _options?: any): void {
console.log('afterInstall');
}
/**
* 播放器销毁前钩子
* @param player 播放器实例
*/
public beforeUninstall(_player: IKwaiPlayer): void {
console.log('beforeUninstall');
}
/**
* 播放器销毁后钩子
* @param player 播放器实例
*/
public afterUninstall(_player: IKwaiPlayer): void {
console.log('afterUninstall');
this._player?.off(KwaiPlayerEvent.REPORT, this._onReport);
this._player?.off(KwaiPlayerEvent.ATTRIBUTE_CHANGE_SRC, this._onSrcChange);
}
/**
* 插件id,获取插件,传入参数等操作的标识
* 同名插件只会同时存在一个
*/
public getLabel(): string {
// LoggerPluginLabel
return 'ExamplePlugin';
}
private _onReport = (e: { type: string, value: any }): void => {
}
private _onSrcChange = (): void => {
}
}
```
# API
播放组件提供原生js方式接入,React组件方式接入,Vue2/Vue3组件方式接入。原生js、React、Vue的API和事件名称有差异,需要注意。
播放器的属性、API及事件参考了HTMLVideoElement的实现。
需要参考的文档:
1. [HTMLVideoElement](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLVideoElement)
2. [HTMLMediaElement](https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement)
## 原生库属性
**以下属性同HTMLVideoElement**
| 属性 | 定义 | 备注 |
| :---------------------- | :------------------- | ---- |
| crossOrigin | 跨域设置 | |
| preload | 当前视频预加载设置 | |
| defaultPlaybackRate | 默认播放速度 | |
| playbackRate | 播放速度 | |
| autoplay | 自动播放 | |
| loop | 循环播放开关 | |
| controls | 播放控件显示开关 | |
| volume | 音量 | |
| muted | 静音 | |
| defaultMuted | 默认静音 | |
| poster | 封面图 | |
| disablePictureInPicture | 画中画是否可用开关 | |
| playsinline | 手机H5小窗播放开关 | |
| buffered | 缓存范围 | 只读 |
| duration | 视频时长 | 只读 |
| ended | 是否播放结束 | 只读 |
| error | 错误信息 | 只读 |
| played | 已播放范围 | 只读 |
| readyState | 视频状态 | 只读 |
| seekable | 可seek范围 | 只读 |
| seeking | 是否处于seek状态中 | 只读 |
| networkState | 当前视频加载网络状态 | 只读 |
| paused | 是否暂停状态 | 只读 |
| videoWidth | 视频源宽 | 只读 |
| videoHeight | 视频源高 | 只读 |
**暂未实现的属性**
+ audioTracks
+ currentSrc 只读
+ initialTime 只读
+ mediaGroup
+ mediaKeys
+ moz*
+ sinkId
+ textTracks
+ videoTracks
+ width
+ height
> width/height暂不支持,需要使用样式控制
**与HTMLVideoElement有差异的属性**
### src
可传入视频URL、manifest JSON、File。可传入空字符串进入停止状态
### controls
依赖插件: ControlsPlugin
定义同HTMLVideoElement,用于控制播放控件,可选值有不同
+ controls可选值说明
+ false:关闭播放控件,如果需要自定义播放控件请使用该选项
+ true:使用默认播放控件
+ 'default':使用默认播放控件
### showInfoPanel
依赖插件: PlayInfoPlugin
get: 返回是否显示信息面板
set: 设置是否显示信息面板
### productName
依赖插件: LoggerPlugin
业务名,用于从上报数据中区分业务
### bizData
依赖插件: LoggerPlugin
业务数据,会加入到上报中
```ts
type BizData = {
resourceId?: string | number, // 资源ID
userId?: string | number, // 用户id
photoId?: string, // yoda上报
activityTag?: string, // yoda上报
// eslint-disable-next-line @typescript-eslint/no-explicit-any
request?: { header: Record<string, any> },
secretId?: string, // 不会加入上报
secretKey?: string, // 不会加入上报
isVip?: boolean | number,
} & Record<string, unknown>;
```
### disableHotkey
依赖插件: HotkeyPlugin
get: 返回当前热键功能是否开启
set: 设置当前热键功能是否开启
### disableDownload
依赖插件: ControlsPlugin
controls===‘origin’时是否使下载功能可用
### disableAdaptive
自适应码率是否可用,默认:true
> 以上已实现的可写属性均可在构造函数中传入
### currentLevel
get: 返回当前正在加载的流index
set: 立即切换至指定的流index
设置为-1,切换至自动码率
### nextLevel
get: 返回下一个加载的流index
set: 下一个切换的视频流index
设置为-1,切换至自动码率
### audioTrack
get: 返回当前的音频轨index
set: 立即切换至指定的音频轨index
### totalVideoFrames
get: 返回当前播视频总帧数
### currentVideoFrame
get: 返回当前播放位置对应的帧index
set: seek至指定帧
### showProgress
get: 设置是否显示进度条
set: 获取当前是否显示进度条
> totalVideoFrames>0时可用
## API
**以下API同HTMLVideoElement**
+ load()
+ play()
+ pause()
+ requestPictureInPicture();
**以下API暂未实现**
+ ms*
+ canPlayType()
+ captureStream()
+ fastSeek()
+ setMediaKeys()
+ setSinkId()
**与HTMLVideoElement有差异的API**
### constructor(id: string, data?: Partial<KwaiPlayer.KwaiPlayerData>)
构造函数
参数说明:
+ id: 播放器容器id
+ data: 播放器参数,与HTMLVideoElement相同的API定义也可同data传入
```js
type KwaiPlayerData = {
src: any;
crossOrigin?: string;
preload?: string;
defaultPlaybackRate?: number;
playbackRate?: number;
autoplay?: boolean;
loop?: boolean;
controls?: boolean | string;
volume?: number;
muted?: boolean;
defaultMuted?: boolean;
poster?: string;
disablePictureInPicture?: boolean;
disableDownload?: boolean;
disableAdaptive?: boolean;
playsinline?: boolean;
plugins: { [key in string]: object }; // 参见插件说明
};
```
### destroy(): void
销毁
### isFullscreen(): boolean;
是否全屏
### requestFullscreen: (type?: "window" | "system" | undefined) => void;
请求全屏
```type?: "window" | "system"``` 窗口全屏 | 系统全屏
### exitFullscreen: (type?: "window" | "system" | undefined) => void;
退出全屏
```type?: "window" | "system" | undefined``` 窗口全屏 | 系统全屏 | 自动
### requestPictureInPicture(): Promise<PictureInPictureWindow> | undefined;
进入画中画
### screenshot(): Promise<ImageData | void>
截图
### refresh(): void;
刷新,重新加载视频
### getPluginInstance<pluginLabel extends keyof PluginMap>(label: string | pluginLabel): PluginMap[pluginLabel] | undefined;
获取插件实例
***
> 以下API用于自定义插件
### KwaiPlayer.register(plugin: typeof PluginModule, method: RegisterMethod = 'append');
注册插件
使用场景:
+ 替换现有包中的组件,例如更换UI,使用其他播控UI插件
+ 自定义插件,更多查看自定义插件说明
参数:
plugin: 插件
method: 添加位置,放在最前或者最后,prepend/append,插件注册的顺序会影响到钩子调用的顺序
更多查看插件自定义组件部分内容
### KwaiPlayer.deregister(plugin: typeof PluginModule | string);
注销插件
更多查看插件自定义组件说明
### createSubContainer(layer = KwaiPlayerLayer.DEFAULT): HTMLDivElement
创建一个子容器,用于在播放器中添加DOM
参数:
layer 添加层级
```ts
enum KwaiPlayerLayer {
VIDEO = 'video', // 视频内容层,例如视频画面,水印,全景视频渲染画面
VIDEO_INTERACTIVE = 'videoInteractive', // 视频交互层,如弹幕
DEFAULT = 'default', // 播控层,如播放组件,视频信息面板
}
```
## 原生js组件事件
**以下事件同HTMLVideoElement**
| 属性 | 定义 | 备注 |
| -------------- | :----------------------------- | ---- |
| abort | 资源未完全加载时触发,非错误 | |
| canplay | 可播时 | |
| canplaythrough | 可播时,估计已加载足够数据 | |
| durationchange | 视频总时长变更 | |
| emptied | 媒体源设置为空时 | |
| ended | 播放结束 | |
| error | 发生错误 | |
| loadeddata | 当前播放位置视频帧加载完成 | |
| loadedmetadata | metadata加载完成 | |
| loadstart | 开始加载 | |
| pause | 进入暂停状态 puased转为true时 | |
| play | 进入播放状态 puased转为false时 | |
| playing | 播放准备开始时 | |
| progress | 加载资源 | |
| ratechange | 播放速度变更 | |
| resize | 视频源尺寸变更 | |
| seeked | seek完成 | |
| seeking | seek开始 | |
| stalled | 尝试获取数据但是为取到时触发 | |
| suspend | 加载数据被挂起 | |
| timeupdate | 播放时间变更 | |
| volumechange | 音量变更 | |
| waiting | 缺少数据导致播放暂停 | |
**与HTMLVideoElement有差异的事件**
> 以下事件与多清晰度相关
### manifestparsed
+ 定义:manifest解析成功事件
+ 数据:
```js
{
levels: {
width: 640, // 宽,可选
height: 360, // 高,可选
qualityType: "360"
qualityLabel: "标清"
}[], // 可用流列表
currentLevel: 3, // 当前流index,
audioTracks?: {
lang: 'en', // 语言
qualityLabel: '',
qualityType: '',
}[], // 可用音频轨
audioTrack?: 0, // 当前音频轨index
}
```
### levelswitching
+ 定义:开始进行码率切换
+ 数据:
```js
{
bitrate: 460560, // 码率
smooth: true, // 是否平滑切换
auto: false, // 是否自动
level: 1, // level下标
id: 1, // 切换操作id
}
```
### levelswitched
+ 定义:码率切换成功事件
+ 数据:
```js
{
bitrate: 460560, // 码率
smooth: true, // 是否平滑切换
auto: false, // 是否自动
level: 1, // level下标
id: 1, // 切换操作id
}
```
### levelswitchplaying
+ 定义:码率切换开始播放,切换至自动码率时无此事件
+ 数据:
```js
{
bitrate: 460560, // 码率
smooth: true, // 是否平滑切换
auto: false, // 是否自动
level: 1, // level下标
id: 1, // 切换操作id
}
```
### levelswitchfailed
+ 定义:切换清晰度失败
### audiotrackswitching
+ 定义:音频轨开始切换
+ 数据:
```js
{
level: 0, // 音频轨id
smooth: false, // 是否平滑切换
auto: false, // 是否自动切换
id: 1 // 切换操作id
}
```
### audiotrackswitched
+ 定义:音频轨切换完成
+ 数据:
```js
{
level: 0, // 音频轨id
smooth: false, // 是否平滑切换
auto: false, // 是否自动切换
id: 1 // 切换操作id
}
```
## React组件与原生js组件差异
API相同
### React事件对应表
| React组件事件 | 对应事件 |
| --------------------- | :------------------ |
| onAbout | abort |
| onCanplay | canplay |
| onCanplayThrough | canplaythrough |
| onDurationChange | durationchange |
| onEmptied | emptied |
| onEnded | ended |
| onError | error |
| onLoadedData | loadeddata |
| onLoadedMetadata | loadedmetadata |
| onLoadStart | loadstart |
| onPause | pause |
| onPlay | play |
| onPlaying | playing |
| onProgress | progress |
| onRateChange | ratechange |
| onResize | resize |
| onSeeked | seeked |
| onSeeking | seeking |
| onStalled | stalled |
| onSuspend | suspend |
| onTimeUpdate | timeupdate |
| onVolumeChange | volumechange |
| onWaiting | waiting |
| onManifestParsed | manifestparsed |
| onLevelSwitching | levelswitching |
| onLevelSwitched | levelswitched |
| onLevelSwitchPlaying | levelswitchplaying |
| onLevelSwitchFailed | levelswitchfailed |
| onAudioTrackSwitching | audiotrackswitching |
| onAudioTrackSwitched | audiotrackswitched |
## Vue组件与原生js组件差异
事件相同
**以下props同HTMLVideoElement**
+ crossOrigin //是否设置跨域
+ preload //是否预加载
+ defaultPlaybackRate //设置默认播放倍速
+ playbackRate //修改播放倍速
+ autoplay //是否设置视频播自动播放
+ loop //是否在视频播放结束的时候,自动返回视频开始的地方,继续播放
+ controls //是否在视频底部使用默认面板 包括控制音量,跨帧,暂停/播放等
+ volume //设置音量
+ muted //设置音量是否静音
+ defaultMuted //设置音量是否默认静音
+ poster //视频播放之前,作为海报展示的图片
+ disablePictureInPicture //是否禁用画中画选项
+ playsinline //指明视频将内联(inline)播放,即在元素的播放区域内
+ src //播放URL或者manifest内容
**Vue组件属性对照表**
| Vue组件 API | 原生js组件属性 |
| ------------------------------------------------------- | :------------------------------------------------ |
| getError | error |
| getNetworkState | networkState |
| getBuffered | buffered |
| getReadyState | readyState |
| getSeeking | seeking |
| getDuration | duration |
| getPaused | paused |
| getSeekable | seekable |
| getEnded | ended |
| getVideoWidth | videoWidth |
| getVideoHeight | videoHeight |
| getSrc / setSrc | src |
| getCrossOrigin / setCrossOrigin | crossOrigin |
| getPreload / setPreload | preload |
| getCurrentTime / setCurrentTime | currentTime |
| getDefaultPlaybackRate / setDefaultPlaybackRate | defaultPlaybackRate |
| getPlaybackRate / setPlaybackRate | playbackRate |
| getAutoplay / setAutoplay | autoplay |
| getLoop / setLoop | loop |
| getControls / setControls | controls |
| getVolume / setVolume | volume |
| getMuted / setMuted | muted |
| getDefaultMuted / setDefaultMuted | defaultMuted |
| getPoster / setPoster | poster |
| getDisablePictureInPicture / setDisablePictureInPicture | disablePictureInPicture |
| getPlaysinline / setPlaysinline | playsinline + webkit-playsinline + x5-playsinline |
### 在页面中引入
+ 引入js
```html
<script src="https://cdn.jsdelivr.net/npm/@kwai-video-team/kwai-player-web/full/kwai-player-web-full.js"></script>
```
+ 提供挂载元素
```html
<body>
<div id="player"></div>
</body>
```
+ 实例化
```html
<script>
player = new KwaiPlayer.default('#player', {
src: 'http://xxxx.mp4',
autoplay: true,
});
</script>
```
可以根据需要引入不同包
```html
<script src="https://cdn.jsdelivr.net/npm/@kwai-video-team/kwai-player-web/full/kwai-player-web-full.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@kwai-video-team/kwai-player-web/vue2/kwai-player-web-vue2.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@kwai-video-team/kwai-player-web/vue3/kwai-player-web-vue3.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@kwai-video-team/kwai-player-web/react/kwai-player-web-react.js"></script>
```
# 错误码
播放组件错误说明
| code | 定义 | |
| :-------- | :------------------------------------------------------ | :------------- |
| 10xx | 流加载错误 | 网络错误 |
| 1000 | 流加载错误且无http status code,加载资源的跨域头不正确 | 网络错误 |
| 1001 | 流加载错误400 | 网络错误 |
| 1002 | 流加载错误401 | 网络错误 |
| 1003 | 流加载错误403 | 网络错误 |
| 1004 | 流加载错误404 | 网络错误 |
| 1005 | 流加载错误4xx | 网络错误 |
| 1006 | 流加载错误5xx | 网络错误 |
| 1007 | 流加载错误,连接超时 | 网络错误 |
| 1008 | 流加载错误,数据超时 | 网络错误 |
| 1009 | 流加载出错,传输过程中失败 | 网络错误 |
| 11xx | hlsManifestLoadError HLS manifest加载错误 | 网络错误 |
| 12xx | hlsLevelLoadError HLS level加载错误 | 网络错误 |
| 13xx | hls音频track playlist加载失败 | 网络错误 |
| 14xx | hls key加载失败 网络错误 | 网络错误 |
| 15xx | drm license加载失败 | 网络错误 |
| 16xx | 解码库加载失败 | 网络错误 |
| 100 | canNotSeek无法seek | |
| 101 | video触发错误 且未取到MediaError.code | |
| 102 | 不支持的协议 | |
| 103 | 传入配置错误 | |
| 106 | seek至指定帧失败 | |
| 107 | 传入Src为空 | |
| 111 | video触发错误 对应MediaError.code 1 | 参考MediaError |
| 112 | video触发错误 对应MediaError.code 2 | 参考MediaError |
| 113 | video触发错误 对应MediaError.code 3 | 参考MediaError |
| 114 | video触发错误 对应MediaError.code 4 | 参考MediaError |
| 200 | mediaSourceError 初始化MSE错误,MediaSource未定义时触发 | |
| 201 | addSourceBufferError MSE增加SourceBuffer失败 | |
| 202 | sourceBufferError MSE的SourceBuffer触发错误 | |
| 203 | endOfStreamError MSE结束流错误 | |
| 204 | appendBufferError MSE填充buffer错误 | |
| 205 | SourceBuffer changeType 错误 | |
| 301 | 解封装错误 | |
| 302 | 重新封装错误 | |
| 303 | remuxAllocError 重新封装alloc mdat存储错误 | |
| 304 | remux worker报错 | |
| 305 | 未找到解封装器 | |
| 400 | manifestParsingError manifest解析错误 | |
| 401 | levelSwitchError HLS level切换错误 | |
| 500~506 | 加密视频解密错误 | |
| 600 | wasm解码库加载失败 | |
| 601 | wasm解码库启动失败 | |
| 602 | wasm解码库渲染失败 | |
| 603 | wasm解码时WebGL发生错误 | |
| 604 | wasm解码不支持 | |
| 1011~1019 | webRTC直播错误 | |
错误码111~114 参考[MediaError code说明](https://developer.mozilla.org/en-US/docs/Web/API/MediaError/code),