141 lines
6.9 KiB
JavaScript
141 lines
6.9 KiB
JavaScript
|
|
import videojs from "video.js";
|
|||
|
|
import TachVideoMenuButton from "./components/tach-video-menu-button";
|
|||
|
|
import TachVideoMenuItem from "./components/tach-video-menu-item";
|
|||
|
|
import audioTrackSelector from "./selectors/audio-track-selector";
|
|||
|
|
import playbackRateSelector from "./selectors/playback-rate-selector";
|
|||
|
|
import qualityRateSelector from "./selectors/quality-rate-selector";
|
|||
|
|
import textTracksSelector from "./selectors/text-track-selector";
|
|||
|
|
import "./settings.css";
|
|||
|
|
const BasePlugin = videojs.getPlugin("plugin");
|
|||
|
|
// Значения опций по умолчанию
|
|||
|
|
const defaults = {};
|
|||
|
|
class SettingsButton extends BasePlugin {
|
|||
|
|
constructor(player, options) {
|
|||
|
|
super(player);
|
|||
|
|
this.mainMenu = [];
|
|||
|
|
this.options = videojs.obj.merge(defaults, options);
|
|||
|
|
this.player.ready(() => this.initialize());
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Инициализация плагина: создание кнопки настроек и привязка событий
|
|||
|
|
*/
|
|||
|
|
initialize() {
|
|||
|
|
this.createSettingsButton();
|
|||
|
|
this.bindPlayerEvents();
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Привязка событий плеера (например, для обновления меню)
|
|||
|
|
*/
|
|||
|
|
bindPlayerEvents() {
|
|||
|
|
// При необходимости можно привязать событие, например:
|
|||
|
|
// this.settingsButton.on("click", this.setMenu.bind(this, undefined, false, true));
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Создание кнопки настроек и определение пунктов меню.
|
|||
|
|
* Здесь создаются фабрики для формирования кнопок и устанавливается начальное меню.
|
|||
|
|
*/
|
|||
|
|
createSettingsButton() {
|
|||
|
|
const player = this.player;
|
|||
|
|
// Создаем кнопку настроек с помощью компонента TachVideoMenuButton
|
|||
|
|
this.settingsButton = new TachVideoMenuButton(player, "Settings", "Settings");
|
|||
|
|
this.buttonInstance = player.controlBar.addChild(this.settingsButton, {
|
|||
|
|
componentClass: "settingsButton",
|
|||
|
|
});
|
|||
|
|
this.buttonInstance.addClass("vjs-settings-button");
|
|||
|
|
// Определяем кнопку "Назад" для возврата в главное меню
|
|||
|
|
this.backButton = {
|
|||
|
|
label: "Назад",
|
|||
|
|
value: this.mainMenu,
|
|||
|
|
selectable: false,
|
|||
|
|
selected: false,
|
|||
|
|
onClick: () => this.setMenu(undefined, true, true),
|
|||
|
|
className: "settings-back",
|
|||
|
|
};
|
|||
|
|
// Создаем фабрики для дополнительных настроек
|
|||
|
|
const { menuItem: audioMenuItem, menuItems: audioMenuItems } = audioTrackSelector(player);
|
|||
|
|
this.audioTracksButton = () => ({
|
|||
|
|
...audioMenuItem(),
|
|||
|
|
onClick: () => this.setMenu(audioMenuItems(), false, true),
|
|||
|
|
});
|
|||
|
|
const { menuItem: textMenuItem, menuItems: textMenuItems } = textTracksSelector(player);
|
|||
|
|
this.textTracksButton = () => ({
|
|||
|
|
...textMenuItem(),
|
|||
|
|
onClick: () => this.setMenu(textMenuItems(), false, true),
|
|||
|
|
});
|
|||
|
|
const { menuItem: playbackMenuItem, menuItems: playbackMenuItems } = playbackRateSelector(player);
|
|||
|
|
this.playbackRateButton = () => ({
|
|||
|
|
...playbackMenuItem(),
|
|||
|
|
onClick: () => this.setMenu(playbackMenuItems(), false, true),
|
|||
|
|
});
|
|||
|
|
// В createSettingsButton замени этот участок:
|
|||
|
|
const qualitySelector = qualityRateSelector(player);
|
|||
|
|
this.qualityRateButton = () => ({
|
|||
|
|
...qualitySelector.menuItem(), // пересоздание при каждом открытии меню
|
|||
|
|
onClick: () => this.setMenu(qualitySelector.menuItems(), false, true),
|
|||
|
|
});
|
|||
|
|
// Подписка на автообновление, когда hls переключает уровень
|
|||
|
|
qualitySelector.setMenuUpdateCallback(() => {
|
|||
|
|
this.setMenu(undefined, true); // Обновить главное меню без перезахода
|
|||
|
|
});
|
|||
|
|
// Инициализируем меню с кнопками по умолчанию без показа
|
|||
|
|
this.setMenu(undefined, true, false);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Обёртка для создания экземпляра пункта меню.
|
|||
|
|
*
|
|||
|
|
* @param item - объект настроек пункта меню
|
|||
|
|
* @returns экземпляр TachVideoMenuItem
|
|||
|
|
*/
|
|||
|
|
getMenuItem(item) {
|
|||
|
|
return new TachVideoMenuItem(this.player, item, this.settingsButton, this);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* Устанавливает (обновляет) пункты меню плагина.
|
|||
|
|
*
|
|||
|
|
* @param items - массив пунктов меню (если не передан, используются кнопки по умолчанию)
|
|||
|
|
* @param skipBackButton - если true, не добавлять кнопку "Назад"
|
|||
|
|
* @param forceShow - если true, принудительно показать меню после обновления
|
|||
|
|
*/
|
|||
|
|
async setMenu(items = [], skipBackButton = false, forceShow = false) {
|
|||
|
|
const menuButtons = [];
|
|||
|
|
if (!skipBackButton) {
|
|||
|
|
menuButtons.push(this.backButton);
|
|||
|
|
}
|
|||
|
|
if (items?.length === 0) {
|
|||
|
|
// Если не переданы конкретные пункты меню – используем кнопки по умолчанию
|
|||
|
|
const defaultButtons = [
|
|||
|
|
this.playbackRateButton,
|
|||
|
|
this.qualityRateButton,
|
|||
|
|
this.textTracksButton,
|
|||
|
|
this.audioTracksButton,
|
|||
|
|
];
|
|||
|
|
defaultButtons.forEach(createButton => {
|
|||
|
|
const btn = createButton();
|
|||
|
|
if (btn.enabled) {
|
|||
|
|
menuButtons.push(btn);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
menuButtons.push(...items);
|
|||
|
|
}
|
|||
|
|
// Формируем список пунктов меню: вместо пересоздания меню, назначаем функцию,
|
|||
|
|
// возвращающую актуальный список пунктов, и вызываем метод обновления.
|
|||
|
|
this.settingsButton.createItems = () => menuButtons.map(item => this.getMenuItem(item));
|
|||
|
|
await this.settingsButton.update();
|
|||
|
|
// Если требуется принудительно показать меню, эмулируем клик по кнопке меню
|
|||
|
|
if (forceShow) {
|
|||
|
|
const menuElement = this.buttonInstance.el().querySelector(".vjs-menu");
|
|||
|
|
const menuButton = this.buttonInstance
|
|||
|
|
.el()
|
|||
|
|
.querySelector(".vjs-menu-button");
|
|||
|
|
if (menuElement && menuButton) {
|
|||
|
|
menuButton.click();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// Регистрируем плагин в Video.js
|
|||
|
|
videojs.registerPlugin("settingsMenu", SettingsButton);
|
|||
|
|
export default SettingsButton;
|
|||
|
|
//# sourceMappingURL=index.js.map
|