@oplayer/dash
Version:
Dash plugin for oplayer
230 lines (229 loc) • 8.86 kB
JavaScript
/**
* name: @oplayer/dash
* version: v1.2.27-beta.2
* description: Dash plugin for oplayer
* author: shiyiya
* homepage: https://github.com/shiyiya/oplayer
*/
import { loadSDK } from "@oplayer/core";
const PLUGIN_NAME = "oplayer-plugin-dash";
const defaultMatcher = (_, source) => source.format === "dash" || source.format === "mpd" || (source.format === "auto" || typeof source.format === "undefined") && /.mpd(#|\?|$)/i.test(source.src);
class DashPlugin {
constructor(options) {
this.key = "dash";
this.name = PLUGIN_NAME;
this.version = "1.2.27-beta.2";
this.options = {
textControl: true,
audioControl: true,
qualityControl: true,
withBitrate: false,
qualitySwitch: "immediate",
matcher: defaultMatcher,
defaultQuality: () => -1,
defaultAudio: () => -1,
defaultSubtitle: () => -1
};
Object.assign(this.options, options);
}
apply(player) {
this.player = player;
return this;
}
async load(_ref, source) {
var _a;
let $video = _ref.$video;
const _this$options = this.options, matcher = _this$options.matcher, library = _this$options.library;
if (!matcher($video, source)) return false;
if (!DashPlugin.library) {
DashPlugin.library = globalThis.dashjs || (library ? await loadSDK(library, "dashjs") : (await import("dashjs")).default);
}
if (!DashPlugin.library.supportsMediaSource()) return false;
this.instance = DashPlugin.library.MediaPlayer().create();
const player = this.player, instance = this.instance;
const _this$options2 = this.options, drm = _this$options2.drm, config = _this$options2.config;
if (config) instance.updateSettings(config);
if (drm) instance.setProtectionData(drm);
instance.initialize($video, source.src, $video.autoplay);
instance.on(DashPlugin.library.MediaPlayer.events.ERROR, function(event) {
const err = event.event || event.error;
const message = event.event ? event.event.message || event.type : void 0;
player.emit("error", Object.assign({
pluginName: PLUGIN_NAME,
message
}, err));
});
if ((_a = player.context.ui) == null ? void 0 : _a.setting) {
if (instance.getBitrateInfoListFor) {
generateSetting(player, instance, this.options);
} else {
console.warn("https://github.com/shiyiya/oplayer/issues/155");
}
}
return this;
}
destroy() {
var _a;
if (this.instance) {
const player = this.player, instance = this.instance;
if ((_a = player.context.ui) == null ? void 0 : _a.setting) removeSetting(player);
instance.destroy();
}
}
}
function getSettingsByType(instance, type, withBitrate) {
var _a, _b, _c;
const bitrateInfoList = instance.getBitrateInfoListFor(type);
const isAuto = Boolean((_c = (_b = (_a = instance.getSettings().streaming) == null ? void 0 : _a.abr) == null ? void 0 : _b.autoSwitchBitrate) == null ? void 0 : _c.video);
const videoQuality = instance.getQualityFor("video");
if (bitrateInfoList.length > 1) {
return bitrateInfoList.toSorted((a, b) => b.bitrate - a.bitrate).map((it) => {
let name = it.height + "p";
if (withBitrate) {
const kb = it.bitrate / 1e3;
const useMb = kb > 1e3;
const number = useMb ? (kb / 1e3).toFixed(2) : Math.floor(kb);
name += " (" + number + (useMb ? "m" : "k") + "bps)";
}
return {
name,
default: isAuto ? false : videoQuality == it.qualityIndex,
value: it.qualityIndex
};
});
}
return [];
}
const generateSetting = (player, instance, options) => {
instance.on(DashPlugin.library.MediaPlayer.events.STREAM_INITIALIZED, function() {
var _a, _b;
if (options.qualityControl) {
const quality = instance.getBitrateInfoListFor("video");
if (quality.length < 2) return;
const defaultLevel = options.defaultQuality(quality);
if (defaultLevel != -1) instance.setQualityFor("video", defaultLevel);
settingUpdater({
name: "Quality",
icon: player.context.ui.icons.quality,
settings: () => {
var _a2, _b2, _c;
return [{
name: player.locales.get("Auto"),
default: Boolean((_c = (_b2 = (_a2 = instance.getSettings().streaming) == null ? void 0 : _a2.abr) == null ? void 0 : _b2.autoSwitchBitrate) == null ? void 0 : _c.video),
value: -1
}].concat(getSettingsByType(instance, "video", options.withBitrate));
},
onChange(_ref2) {
let value = _ref2.value;
instance.updateSettings({
streaming: {
abr: {
autoSwitchBitrate: {
video: value == -1
}
}
}
});
if (value != -1) {
instance.setQualityFor("video", value, options.qualitySwitch == "immediate");
}
}
});
instance.on(DashPlugin.library.MediaPlayer.events.QUALITY_CHANGE_RENDERED, function qualityMenuUpdater(data) {
var _a2, _b2, _c, _d, _e;
if (data.mediaType !== "video" || !((_c = (_b2 = (_a2 = instance.getSettings().streaming) == null ? void 0 : _a2.abr) == null ? void 0 : _b2.autoSwitchBitrate) == null ? void 0 : _c.video)) return;
const height = (_d = instance.getBitrateInfoListFor("video")[data.newQuality]) == null ? void 0 : _d.height;
const levelName = player.locales.get("Auto") + (height ? " (" + height + "p)" : "");
(_e = player.context.ui) == null ? void 0 : _e.setting.updateLabel(PLUGIN_NAME + "-Quality", levelName);
});
}
if (options.audioControl) {
const audioTracks = instance.getTracksFor("audio");
if (audioTracks.length < 2) return;
let defaultAudio = options.defaultAudio(audioTracks);
if (defaultAudio == -1) {
defaultAudio = (_a = audioTracks.find((_ref3) => {
let lang = _ref3.lang;
return lang === navigator.language || lang === navigator.language.split("-")[0];
})) == null ? void 0 : _a.id;
}
if (defaultAudio != -1 && defaultAudio != void 0) {
instance.setCurrentTrack(audioTracks.find((t) => t.id == defaultAudio));
}
const currentAudio = instance.getCurrentTrackFor("audio");
settingUpdater({
name: "Language",
icon: player.context.ui.icons.lang,
settings() {
return audioTracks.map((it) => ({
name: it.lang || "unknown",
default: (currentAudio == null ? void 0 : currentAudio.index) != null && currentAudio.index == it.index,
value: it
}));
},
onChange(_ref4) {
let value = _ref4.value;
instance.setCurrentTrack(value);
}
});
}
if (options.textControl) {
const textTracks = instance.getTracksFor("text");
if (textTracks.length < 1) return;
let defaultSubtitle = options.defaultSubtitle(textTracks);
if (defaultSubtitle == -1) {
defaultSubtitle = (_b = textTracks.find((_ref5) => {
let lang = _ref5.lang;
return lang === navigator.language || lang === navigator.language.split("-")[0];
})) == null ? void 0 : _b.id;
}
if (defaultSubtitle != -1 && defaultSubtitle != void 0) {
instance.enableText(true);
instance.setTextTrack(defaultSubtitle);
}
const currentTrack = instance.getCurrentTrackFor("text");
settingUpdater({
name: "Subtitle",
icon: player.context.ui.icons.subtitle,
settings() {
return [{
name: player.locales.get("Off"),
default: !instance.isTextEnabled(),
value: -1
}].concat(textTracks.map((it) => ({
name: it.lang || "unknown",
default: (currentTrack == null ? void 0 : currentTrack.index) != null && currentTrack.index == it.index,
value: it.index
})));
},
onChange(_ref6) {
let value = _ref6.value;
instance.enableText(value != -1);
if (value != -1) instance.setTextTrack(value);
}
});
}
});
function settingUpdater(arg) {
const settings = arg.settings();
const name = arg.name, icon = arg.icon, onChange = arg.onChange;
player.context.ui.setting.unregister(PLUGIN_NAME + "-" + name);
player.context.ui.setting.register({
name: player.locales.get(name),
icon,
onChange,
type: "selector",
key: PLUGIN_NAME + "-" + name,
children: settings
});
}
};
const removeSetting = (player) => {
["Quality", "Language", "Subtitle"].forEach((it) => player.context.ui.setting.unregister(PLUGIN_NAME + "-" + it));
};
function create(options) {
return new DashPlugin(options);
}
export {
create as default
};