Files
ArtPlayer/packages/artplayer-plugin-dash-control/src/index.js
T
Mr.Hope cb69e4ad66 feat(artplayer-plugin-dash-control)!: support dash.js v5
- replace removed v4 APIs with their v5 equivalents:
  getRepresentationsByType / getCurrentRepresentationForType /
  setRepresentationForTypeByIndex
- bump dash.js CDN references from 4.5.2 to 5.2.1 (modern/umd build)
- rebuild dist, docs/compiled and docs/uncompiled artifacts
- regenerate vitepress docs
2026-09-10 15:58:17 +08:00

179 lines
4.7 KiB
JavaScript

import $audio from './audio.svg?raw'
import $quality from './quality.svg?raw'
function uniqBy(array, property) {
const seen = new Map()
return array.filter((item) => {
const key = item[property]
if (key === undefined) {
return true
}
return !seen.has(key) && seen.set(key, 1)
})
}
export default function artplayerPluginDashControl(option = {}) {
return (art) => {
const { $video } = art.template
const { errorHandle } = art.constructor.utils
function updateQuality(dash) {
const qualities = dash.getRepresentationsByType('video')
if (!qualities || !qualities.length)
return
const config = option.quality || {}
const auto = config.auto || 'Auto'
const title = config.title || 'Quality'
const getName = config.getName || (level => `${level.height}p`)
const currentRepresentation = dash.getCurrentRepresentationForType('video')
const currentId = currentRepresentation && currentRepresentation.id
const currentAuto = dash.getSettings().streaming.abr.autoSwitchBitrate.video
const defaultHtml = !currentAuto && currentRepresentation ? getName(currentRepresentation) : auto
const selector = uniqBy(
qualities.map((item, index) => {
return {
html: getName(item),
value: index,
default: !currentAuto && !!currentId && item.id === currentId,
}
}),
'html',
).sort((a, b) => b.value - a.value)
selector.push({
html: auto,
value: 'auto',
default: currentAuto,
})
const onSelect = (item) => {
if (item.value === 'auto') {
dash.updateSettings({
streaming: {
abr: {
autoSwitchBitrate: {
video: true,
},
},
},
})
}
else {
dash.updateSettings({
streaming: {
abr: {
autoSwitchBitrate: {
video: false,
},
},
},
})
dash.setRepresentationForTypeByIndex('video', item.value)
}
art.notice.show = `${title}: ${item.html}`
if (config.control)
art.controls.check(item)
if (config.setting)
art.setting.check(item)
return item.html
}
if (config.control) {
art.controls.update({
name: 'dash-quality',
position: 'right',
html: defaultHtml,
style: { padding: '0 10px' },
selector,
onSelect,
})
}
if (config.setting) {
art.setting.update({
name: 'dash-quality',
tooltip: defaultHtml,
html: title,
icon: $quality,
width: 200,
selector,
onSelect,
})
}
}
function updateAudio(dash) {
const audioTracks = dash.getTracksFor('audio')
if (!audioTracks || !audioTracks.length)
return
const config = option.audio || {}
const auto = config.auto || 'Auto'
const title = config.title || 'Audio'
const getName = config.getName || (track => track.lang || track.id)
const currentTrack = dash.getCurrentTrackFor('audio') || audioTracks[0]
const defaultHtml = currentTrack ? getName(currentTrack) : auto
const selector = uniqBy(
audioTracks.map((item) => {
return {
html: getName(item),
value: item,
default: currentTrack === item,
}
}),
'html',
)
const onSelect = (item) => {
dash.setCurrentTrack(item.value)
art.notice.show = `${title}: ${item.html}`
if (config.control)
art.controls.check(item)
if (config.setting)
art.setting.check(item)
return item.html
}
if (config.control) {
art.controls.update({
name: 'dash-audio',
position: 'right',
html: defaultHtml,
style: { padding: '0 10px' },
selector,
onSelect,
})
}
if (config.setting) {
art.setting.update({
name: 'dash-audio',
tooltip: defaultHtml,
html: title,
icon: $audio,
width: 200,
selector,
onSelect,
})
}
}
function update() {
errorHandle(art.dash.getVideoElement() === $video, 'Cannot find instance of DASH from "art.dash"')
updateQuality(art.dash)
updateAudio(art.dash)
}
art.on('ready', update)
art.on('restart', update)
return {
name: 'artplayerPluginDashControl',
update,
}
}
}