# HLS 控制
[English](../en/plugin/hls-control.md)
为 Hls.js 播放器添加画质与音轨菜单。插件控制你放在 `art.hls` 上的 Hls.js 实例,不负责下载、创建或销毁 SDK。
本页描述当前重构分支。这里说明的自动刷新与生命周期修复尚未发布;未固定版本的 npm/CDN 安装仍使用已发布版本。
## 安装
```sh
yarn add artplayer hls.js artplayer-plugin-hls-control
```
```js
import Artplayer from 'artplayer';
import Hls from 'hls.js';
import artplayerPluginHlsControl from 'artplayer-plugin-hls-control';
```
通过 script 标签使用时,先加载 ArtPlayer、Hls.js 和插件的 `dist/artplayer-plugin-hls-control.js`。插件全局名称为 `artplayerPluginHlsControl`。应用中应固定依赖版本,并使用允许浏览器访问的视频地址。
## 完整示例
下面与[在线 HLS 示例](https://artplayer.org/?libs=https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.17/hls.min.js%0A./uncompiled/artplayer-plugin-hls-control/index.js&example=hls.control)使用同一份代码和站点容器。接入自己的应用时替换容器与视频地址。
▶ Run Code
```js
// npm i hls.js
// npm i artplayer-plugin-hls-control
// import Hls from 'hls.js';
// import artplayerPluginHlsControl from 'artplayer-plugin-hls-control';
const useHls = Hls.isSupported()
let hls
function destroyHls() {
const previous = hls
hls = undefined
if (previous)
previous.destroy()
}
const art = new Artplayer({
container: '.artplayer-app',
url: 'https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/index.m3u8',
setting: true,
plugins: useHls
? [
artplayerPluginHlsControl({
quality: {
// Show quality choices in the controls
control: true,
// Show quality choices in settings
setting: true,
// Get the quality name from level
getName: level => `${level.height}P`,
// I18n
title: 'Quality',
auto: 'Auto',
},
audio: {
// Show audios in control
control: true,
// Show audios in setting
setting: true,
// Get the audio name from track
getName: track => track.name || track.lang || 'Audio',
// I18n
title: 'Audio',
auto: 'Auto',
},
}),
]
: [],
customType: {
m3u8: function playM3u8(video, url, art) {
destroyHls()
if (useHls) {
hls = new Hls()
art.hls = hls
hls.loadSource(url)
hls.attachMedia(video)
}
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = url
}
else {
art.notice.show = 'Unsupported playback format: m3u8'
}
},
},
})
art.on('destroy', destroyHls)
```
仅在支持 Hls.js 时安装控制插件。若改用浏览器原生 HLS,示例直接设置 `video.src`,不安装必须依赖 `art.hls` 的插件;该插件不会为原生播放提供画质或音轨选择。单个播放器实例保持固定的 `useHls`,更换播放集成方式时重新创建播放器。
## 配置
`artplayerPluginHlsControl(option?)` 同步返回插件工厂。`quality` 与 `audio` 都可以使用以下字段:
| 字段 | 含义与默认行为 |
| --- | --- |
| `control` | 显示底部控制器;省略时不显示。 |
| `setting` | 显示设置项;省略时不显示,同时需要播放器的 `setting: true`。 |
| `title` | 菜单标题,画质默认 `Quality`,音轨默认 `Audio`。 |
| `auto` | 当前项未知时的文字,默认 `Auto`;画质还用于自动选项。音轨不会因此新增一个虚拟 Auto 轨道。 |
| `getName(item, index?)` | 根据原始 SDK 档位或轨道对象返回字符串。当前标签调用没有 `index`,列表调用带有索引。 |
省略画质回调时,标签取 `level.name` 或 `level.height + 'P'`;音轨依次取 `track.name`、`track.lang`、`track.language`。空标题和空 Auto 文字会使用默认值。媒体没有相关字段时,自定义回调应提供字符串回退。
回调按普通函数调用,`this` 不会绑定到播放器,不能把可选索引视为必传字段。相同标签会合并成一个选项;如果想区分同高度的多个档位,可在标签中加入码率。轨道列表变空时会移除对应菜单。
选择画质会写入 `hls.currentLevel`,Auto 对应 `-1`;当 `autoLevelEnabled` 为 true 时,当前标签反映自动模式。选择音轨会把 SDK 轨道 ID 写入 `hls.audioTrack`。菜单选择是同步操作,不代表新流已经完成缓冲或解码。
## 外部修改后的刷新
播放器 `ready`、`restart` 会刷新菜单;SDK 提供事件接口时,清单、档位、音轨与销毁事件也会刷新或清除菜单。选中项来自当前 SDK 状态。
把替换后的实例绑定到同一个 video 并赋给 `art.hls` 后,如需立即刷新,可以调用已有同步方法:
```js
art.plugins.artplayerPluginHlsControl.update();
```
`update()` 返回 `undefined`,不是 Promise;在没有已绑定 Hls.js 实例时调用可能抛错。没有对应事件接口的自定义适配器需要在状态变化后手动刷新。菜单名 `hls-quality` 和 `hls-audio` 由插件使用,其他菜单请使用不同名称。
## SDK 所有权与换源
换源继续使用播放器已有的 `switchUrl()` 或 `switchQuality()`,并处理返回的 Promise。示例在创建新 SDK 前销毁旧实例,再更新 `art.hls`,每个播放器只保留一个最终清理监听器,每个 SDK 实例只销毁一次。不要在每次加载时累积新的播放器 `destroy` 监听器,同时又自行销毁被替换的实例。
控制插件只释放自己的 SDK 订阅;替换或销毁播放器后,旧菜单回调不再修改 SDK。插件不会销毁 SDK、移除其他使用者的监听器或实现 Hls.js 错误恢复;应用仍负责处理 SDK 致命错误和播放策略。
## TypeScript
默认回调类型包含画质高度/名称和音轨 ID/名称/语言字段。可以通过泛型使用应用所需的 SDK 元数据类型;下面的示例只声明实际使用的字段,无需导入 Hls.js 声明:
```ts
import hlsControl from 'artplayer-plugin-hls-control';
interface Level { height: number; bitrate: number }
interface Track { id: number; name: string; lang?: string }
const plugin = hlsControl({
quality: {
control: true,
getName: level => level.height + 'p / ' + level.bitrate,
},
audio: {
setting: true,
getName: track => track.name || track.lang || 'Audio',
},
});
```
根入口导出 `Option`、`Config`、`QualityLevel`、`AudioTrack` 和 `Result` 类型,原根入口及 legacy 路径继续保留。声明不会假定每个 ArtPlayer 实例都有 Hls.js;请在应用的集成类型中描述 `art.hls`。
注册结果只有固定的 `name: 'artplayerPluginHlsControl'` 和 `update()`。工厂普通调用允许省略配置;最后一个声明重载保留必填参数,因此 `Parameters[0]` 仍为 `Option`,不包含 `undefined`。本包没有 `/runtime` 子路径,也没有工厂 `.default` 自引用。
## 验证范围
重构使用本地媒体和真实 worker 验证 Hls.js 1.5.17 / 1.7.2;这两个版本是验证点,不是新定义的支持范围。Firefox 的分组播放崩溃和另一项切组停滞仍在排查。Windows Playwright WebKit 缺少测试所需的 MSE 路径,不能代表 Safari/iOS 原生 HLS 已验收。采用尚未发布的重构前,应验证实际媒体与目标设备。