Add plyr again as fallback
This commit is contained in:
Generated
+10
-10
@@ -13,7 +13,7 @@
|
||||
"chart.js": "^4.5.0",
|
||||
"dashjs": "^5.0.0",
|
||||
"hammerjs": "^2.0.8",
|
||||
"plyr": "^3.7.8",
|
||||
"plyr": "^3.8.4",
|
||||
"tw-elements": "^1.1.0",
|
||||
"vidstack": "^1.12.13"
|
||||
},
|
||||
@@ -3132,6 +3132,15 @@
|
||||
"postcss": "^8.0.9"
|
||||
}
|
||||
},
|
||||
"node_modules/tw-elements/node_modules/yaml": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz",
|
||||
"integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz",
|
||||
@@ -3349,15 +3358,6 @@
|
||||
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
||||
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz",
|
||||
"integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
"chart.js": "^4.5.0",
|
||||
"dashjs": "^5.0.0",
|
||||
"hammerjs": "^2.0.8",
|
||||
"plyr": "^3.7.8",
|
||||
"plyr": "^3.8.4",
|
||||
"tw-elements": "^1.1.0",
|
||||
"vidstack": "^1.12.13"
|
||||
}
|
||||
|
||||
@@ -645,6 +645,82 @@
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* ---- Player Switcher Toggle ---- */
|
||||
.player-switcher {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: rgba(10, 10, 10, 0.65);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 9999px;
|
||||
padding: 6px 4px 6px 14px;
|
||||
transition: all 0.3s ease;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.aspect-\[16\/9\]:hover .player-switcher,
|
||||
.player-switcher--visible {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.player-switcher__label {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.player-switcher__btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 6px 14px;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 9999px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-family: 'Figtree', sans-serif;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.player-switcher__btn:hover {
|
||||
background: rgba(198, 30, 84, 0.2);
|
||||
border-color: rgba(198, 30, 84, 0.4);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.player-switcher__btn i {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.player-switcher__btn--active {
|
||||
background: rgba(198, 30, 84, 0.25);
|
||||
border-color: rgba(198, 30, 84, 0.5);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.player-switcher__dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #c61e54;
|
||||
box-shadow: 0 0 6px rgba(198, 30, 84, 0.6);
|
||||
}
|
||||
|
||||
/* ---- Fullscreen (remove rounded borders) ---- */
|
||||
.hstream-player:fullscreen,
|
||||
.hstream-player:-webkit-full-screen {
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
// Plyr Fallback Player
|
||||
import Plyr from 'plyr';
|
||||
import 'plyr/dist/plyr.css';
|
||||
|
||||
import * as dashjs from 'dashjs';
|
||||
import SubtitlesOctopus from '@jellyfin/libass-wasm';
|
||||
|
||||
import { initMobileWidescreen } from './player-mobile';
|
||||
import { mobileDoubleClick } from './player-mobile';
|
||||
import { playNextPlaylistVideo } from './playlist';
|
||||
import { addVideoTracks } from './player-data';
|
||||
import { addSubtitleTracks } from './player-data';
|
||||
import { serverSelectMenuItem, serverSelectSubmenu, serverSelectMenuClickToggle } from './player-server-select';
|
||||
import { isIOS } from './detect-ios';
|
||||
import { startEngagementTracking, stopEngagementTracking } from './player/player-engagement';
|
||||
import { renderHeatmap } from './player/player-heatmap';
|
||||
|
||||
var player = null;
|
||||
var av1Supported = (!!document.createElement('video').canPlayType('video/webm; codecs="av01.0.05M.08, opus"'));
|
||||
var dashSupported = dashjs.supportsMediaSource();
|
||||
var apiResponse = {};
|
||||
var volume = 0.5;
|
||||
var muted = false;
|
||||
var captions = true;
|
||||
var lastTime = 0.0;
|
||||
var streamServer = '';
|
||||
var streamServers = [];
|
||||
var streamServerIndex = 0;
|
||||
var streamServerCount = 0;
|
||||
var ambientMode = true;
|
||||
var serverFallback = false;
|
||||
var saveInterval;
|
||||
var watchTracked = false;
|
||||
var subtitleInstance = null;
|
||||
|
||||
function trackWatchTime() {
|
||||
if (watchTracked) return;
|
||||
var video = document.getElementsByTagName('video')[0];
|
||||
if (video && video.currentTime >= 10) {
|
||||
watchTracked = true;
|
||||
var episodeId = document.getElementById('e_id').value;
|
||||
window.axios.post('/watched/track', {
|
||||
episode_id: episodeId
|
||||
}).then(function () {
|
||||
console.log('Watch tracked for episode ' + episodeId);
|
||||
}).catch(function (error) {
|
||||
console.error('Failed to track watch: ' + error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var controls = [
|
||||
'play-large',
|
||||
'play',
|
||||
'progress',
|
||||
'current-time',
|
||||
'duration',
|
||||
'mute',
|
||||
'volume',
|
||||
'captions',
|
||||
'settings',
|
||||
'fullscreen',
|
||||
];
|
||||
|
||||
if (localStorage.hstreamVolume) {
|
||||
volume = parseFloat(localStorage.getItem('hstreamVolume')).toFixed(2);
|
||||
console.log('Loaded Audio Volume from Local Storage: ' + volume);
|
||||
}
|
||||
|
||||
if (localStorage.hstreamCaptions) {
|
||||
captions = (localStorage.getItem('hstreamCaptions') == 'true');
|
||||
console.log('Loaded Captions Status from Local Storage: ' + captions);
|
||||
}
|
||||
|
||||
if (localStorage.hstreamMuted) {
|
||||
muted = (localStorage.getItem('hstreamMuted') == 'true');
|
||||
console.log('Loaded Muted Status from Local Storage: ' + muted);
|
||||
}
|
||||
|
||||
if (localStorage.hstreamServerFallback) {
|
||||
serverFallback = (localStorage.getItem('hstreamServerFallback') == 'true');
|
||||
console.log('Loaded Server Fallback Status from Local Storage: ' + serverFallback);
|
||||
}
|
||||
|
||||
if (!av1Supported) {
|
||||
document.getElementById('av1-unsupported').classList.remove('hidden');
|
||||
}
|
||||
|
||||
function initDash(data, player) {
|
||||
const video = document.querySelector('video');
|
||||
|
||||
data.forEach(function (el) {
|
||||
if (el.mode === 'mpd' && el.size === player.config.quality.selected) {
|
||||
const dash = dashjs.MediaPlayer().create();
|
||||
dash.initialize(video, el.src, true);
|
||||
window.player = player;
|
||||
window.dash = dash;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setCanvasDimension(canvas, video) {
|
||||
canvas.height = video.offsetHeight;
|
||||
canvas.width = video.offsetWidth;
|
||||
}
|
||||
|
||||
function paintStaticVideo(ctx, video) {
|
||||
if (localStorage.theme == 'light') {
|
||||
return;
|
||||
}
|
||||
if (!ambientMode) {
|
||||
return;
|
||||
}
|
||||
ctx.drawImage(video, 0, 0, video.offsetWidth, video.offsetHeight);
|
||||
}
|
||||
|
||||
function toggleAmbientMode() {
|
||||
let canvas = document.getElementById('ambientVideo'), ctx = canvas.getContext('2d'), video = document.getElementsByTagName('video')[0];
|
||||
if (ambientMode) {
|
||||
ambientMode = false;
|
||||
localStorage.ambientMode = 'false';
|
||||
setCanvasDimension(canvas, video);
|
||||
document.getElementById('ambient-mode-toggle').innerHTML = '<span>Ambient Mode<span class="plyr__menu__value">Off</span></span>';
|
||||
} else {
|
||||
ambientMode = true;
|
||||
localStorage.ambientMode = 'true';
|
||||
setCanvasDimension(canvas, video);
|
||||
paintStaticVideo(ctx, video);
|
||||
document.getElementById('ambient-mode-toggle').innerHTML = '<span>Ambient Mode<span class="plyr__menu__value">On</span></span>';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleAsiaServer() {
|
||||
if (serverFallback) {
|
||||
serverFallback = false;
|
||||
localStorage.hstreamServerFallback = 'false';
|
||||
document.getElementById('server-fallback-toggle').innerHTML = '<span>Fallback Server<span class="plyr__menu__value">Off</span></span>';
|
||||
streamServers = apiResponse.stream_domains;
|
||||
} else {
|
||||
serverFallback = true;
|
||||
localStorage.hstreamServerFallback = 'true';
|
||||
document.getElementById('server-fallback-toggle').innerHTML = '<span>Fallback Server<span class="plyr__menu__value">On</span></span>';
|
||||
streamServers = apiResponse.asia_stream_domains;
|
||||
}
|
||||
|
||||
streamServerCount = streamServers.length;
|
||||
streamServerIndex = Math.floor(Math.random() * streamServerCount);
|
||||
streamServer = streamServers[streamServerIndex];
|
||||
console.log('Selected Server: ' + streamServer);
|
||||
|
||||
if (player) {
|
||||
clearInterval(saveInterval);
|
||||
stopEngagementTracking();
|
||||
player.destroy();
|
||||
}
|
||||
initPlayer();
|
||||
}
|
||||
|
||||
function initSubtitles(lang) {
|
||||
if (isIOS()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (subtitleInstance != null && subtitleInstance instanceof SubtitlesOctopus) {
|
||||
subtitleInstance.dispose();
|
||||
}
|
||||
|
||||
let newSubUrl = streamServer + '/' + apiResponse.stream_url + '/';
|
||||
|
||||
if (lang != 'en') {
|
||||
newSubUrl += 'autotrans/' + lang + '.ass';
|
||||
} else {
|
||||
newSubUrl += 'eng.ass';
|
||||
}
|
||||
|
||||
let subFont = '/fonts/Figtree-ExtraBold.woff2';
|
||||
if (lang == 'hi') {
|
||||
subFont = '/fonts/Hind-SemiBold.ttf';
|
||||
}
|
||||
|
||||
var options = {
|
||||
video: document.getElementsByTagName('video')[0],
|
||||
subUrl: newSubUrl,
|
||||
workerUrl: '/build/js/subtitles-octopus-worker.js',
|
||||
legacyWorkerUrl: '/build/js/subtitles-octopus-worker-legacy.js',
|
||||
fonts: [subFont],
|
||||
renderMode: 'wasm-blend',
|
||||
};
|
||||
|
||||
subtitleInstance = new SubtitlesOctopus(options);
|
||||
}
|
||||
|
||||
function initPlayer() {
|
||||
player = new Plyr('#player', {
|
||||
controls,
|
||||
quality: {
|
||||
default: 720,
|
||||
options: [2161, 2160, 1081, 1080, 720]
|
||||
},
|
||||
i18n: {
|
||||
qualityLabel: {
|
||||
2161: '2160p48',
|
||||
2160: '2160p',
|
||||
1081: '1080p48',
|
||||
1080: '1080p',
|
||||
720: '720p'
|
||||
},
|
||||
qualityBadge: {
|
||||
2161: 'UHD@48',
|
||||
1081: 'FHD@48',
|
||||
1080: 'FHD',
|
||||
},
|
||||
},
|
||||
fullscreen: { enabled: true, fallback: true, iosNative: true }
|
||||
});
|
||||
|
||||
var data = addVideoTracks(streamServer, apiResponse, av1Supported, dashSupported);
|
||||
|
||||
player.source = {
|
||||
type: 'video',
|
||||
title: apiResponse.title,
|
||||
poster: apiResponse.poster,
|
||||
previewThumbnails: {
|
||||
enabled: true,
|
||||
src: streamServer + '/' + apiResponse.stream_url + '/thumbs.vtt',
|
||||
},
|
||||
sources: data,
|
||||
tracks: addSubtitleTracks(streamServer, apiResponse)
|
||||
};
|
||||
|
||||
player.volume = volume;
|
||||
player.muted = muted;
|
||||
player.captions.language = 'en';
|
||||
player.captions.active = captions;
|
||||
|
||||
if (dashSupported && !apiResponse.legacy) {
|
||||
player.on('qualitychange', () => {
|
||||
initDash(data, player);
|
||||
});
|
||||
|
||||
initDash(data, player);
|
||||
}
|
||||
|
||||
let canvas = document.getElementById('ambientVideo'), ctx = canvas.getContext('2d'), video = document.getElementsByTagName('video')[0];
|
||||
setCanvasDimension(canvas, video);
|
||||
paintStaticVideo(ctx, video);
|
||||
|
||||
var allItems = document.getElementsByClassName('plyr__control--forward');
|
||||
var lastItem = allItems[allItems.length - 1];
|
||||
lastItem.insertAdjacentHTML('afterend', '<button id="ambient-mode-toggle" type="button" class="plyr__control" role="menuitem" aria-haspopup="true"><span>Ambient Mode<span class="plyr__menu__value">On</span></span></button>');
|
||||
document.getElementById('ambient-mode-toggle').addEventListener('click', toggleAmbientMode);
|
||||
|
||||
if (localStorage.ambientMode == 'false') {
|
||||
toggleAmbientMode();
|
||||
}
|
||||
|
||||
lastItem = allItems[allItems.length - 1];
|
||||
let value = 'Off';
|
||||
if (serverFallback) { value = 'On'; }
|
||||
lastItem.insertAdjacentHTML('afterend', '<button id="server-fallback-toggle" type="button" class="plyr__control" role="menuitem" aria-haspopup="true"><span>Fallback Server<span class="plyr__menu__value">' + value + '</span></span></button>');
|
||||
document.getElementById('server-fallback-toggle').addEventListener('click', toggleAsiaServer);
|
||||
|
||||
var clickedPlay = false;
|
||||
|
||||
player.on('play', () => {
|
||||
if (!clickedPlay) {
|
||||
player.stop();
|
||||
console.log('Stopped video, because user didn\'t click play.');
|
||||
}
|
||||
|
||||
const episodeId = document.getElementById('e_id').value;
|
||||
startEngagementTracking(episodeId);
|
||||
|
||||
setCanvasDimension(canvas, video);
|
||||
console.log('Play => Function Loop()');
|
||||
var $this = video;
|
||||
(function loop() {
|
||||
if (!player.paused && !player.ended && localStorage.theme == 'dark' && ambientMode) {
|
||||
ctx.drawImage($this, 0, 0, $this.offsetWidth, $this.offsetHeight);
|
||||
setTimeout(loop, 24000 / 1001);
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
player.on('seeked', () => {
|
||||
paintStaticVideo(ctx, video);
|
||||
if (player.currentTime > 0) {
|
||||
lastTime = player.currentTime;
|
||||
}
|
||||
console.log('Seeked => paintStaticVideo() at ' + player.currentTime);
|
||||
});
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
setCanvasDimension(canvas, video);
|
||||
if (player.paused) {
|
||||
paintStaticVideo(ctx, video);
|
||||
}
|
||||
});
|
||||
|
||||
player.on('captionsenabled', () => {
|
||||
document.getElementsByClassName('libassjs-canvas-parent')[0].style.visibility = 'visible';
|
||||
localStorage.setItem('hstreamCaptions', 'true');
|
||||
console.log('Set Captions Status to Local Storage: true');
|
||||
});
|
||||
|
||||
player.on('captionsdisabled', () => {
|
||||
document.getElementsByClassName('libassjs-canvas-parent')[0].style.visibility = 'hidden';
|
||||
localStorage.setItem('hstreamCaptions', 'false');
|
||||
console.log('Set Captions Status to Local Storage: false');
|
||||
});
|
||||
|
||||
player.on('volumechange', () => {
|
||||
console.log('Saving Audio Volume to Local Storage: ' + player.volume);
|
||||
localStorage.setItem('hstreamVolume', player.volume.toString());
|
||||
console.log('Saving Audio Muted to Local Storage: ' + player.muted.toString());
|
||||
localStorage.setItem('hstreamMuted', player.muted.toString());
|
||||
});
|
||||
|
||||
player.on('ended', () => {
|
||||
playNextPlaylistVideo();
|
||||
});
|
||||
|
||||
player.on('timeupdate', () => {
|
||||
trackWatchTime();
|
||||
});
|
||||
|
||||
player.on('languagechange', (event) => {
|
||||
let lang = event.detail.plyr.captions.language;
|
||||
|
||||
console.log('Subtitle Event ' + lang);
|
||||
initSubtitles(lang);
|
||||
});
|
||||
|
||||
function playerPlayTemp() {
|
||||
clickedPlay = true;
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-plyr="play"]').forEach(play =>
|
||||
play.addEventListener('click', playerPlayTemp)
|
||||
);
|
||||
|
||||
document.getElementsByClassName('plyr--video')[0].addEventListener('click', playerPlayTemp);
|
||||
|
||||
initMobileWidescreen();
|
||||
|
||||
setTimeout(function () {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const time = parseInt(params.get('t'));
|
||||
if (!isNaN(time)) {
|
||||
player.currentTime = time;
|
||||
console.log('Skipping to ' + time);
|
||||
}
|
||||
if (lastTime > 0) {
|
||||
player.currentTime = lastTime;
|
||||
console.log('Skipping to ' + lastTime);
|
||||
}
|
||||
}, 500);
|
||||
|
||||
player.on('ready', () => {
|
||||
mobileDoubleClick(player);
|
||||
|
||||
const video = document.querySelector('video');
|
||||
const episodeId = document.getElementById('e_id').value;
|
||||
if (video && video.duration) {
|
||||
renderHeatmap(episodeId, video.duration);
|
||||
} else if (video) {
|
||||
video.addEventListener('loadedmetadata', function onMeta() {
|
||||
video.removeEventListener('loadedmetadata', onMeta);
|
||||
renderHeatmap(episodeId, video.duration);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var settingElements = document.getElementsByClassName('plyr__control--forward');
|
||||
if (settingElements.length == 3) {
|
||||
settingElements[2].insertAdjacentHTML('afterend', serverSelectMenuItem(streamServerIndex));
|
||||
|
||||
var settingNodes = document.getElementsByClassName('plyr__menu__container')[0].childNodes[0].childNodes;
|
||||
if (settingNodes.length == 4) {
|
||||
document.getElementsByClassName('plyr__menu__container')[0].childNodes[0].childNodes[3].insertAdjacentHTML('afterend', serverSelectSubmenu(streamServerIndex, streamServerCount));
|
||||
}
|
||||
|
||||
document.getElementById('server-select').addEventListener('click', serverSelectMenuClickToggle);
|
||||
document.getElementById('server-select-list-back-btn').addEventListener('click', serverSelectMenuClickToggle);
|
||||
let serverSelects = document.getElementsByClassName('change_server');
|
||||
for (let i = 0; i < serverSelects.length; i++) {
|
||||
serverSelects[i].addEventListener('click', function () {
|
||||
streamServerIndex = Number(this.value);
|
||||
streamServer = streamServers[streamServerIndex];
|
||||
console.log('Selected Server: ' + streamServer);
|
||||
|
||||
if (player) {
|
||||
clearInterval(saveInterval);
|
||||
stopEngagementTracking();
|
||||
player.destroy();
|
||||
}
|
||||
initPlayer();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
saveInterval = setInterval(function () {
|
||||
lastTime = player.currentTime;
|
||||
console.log('Last Player Position: ' + lastTime);
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
export function initPlyrPlayer(episodeId) {
|
||||
window.axios.post('/player/api', {
|
||||
episode_id: episodeId
|
||||
}).then(function (response) {
|
||||
if (response.status == 200) {
|
||||
apiResponse = response.data;
|
||||
streamServers = apiResponse.stream_domains;
|
||||
|
||||
if (serverFallback) {
|
||||
streamServers = apiResponse.asia_stream_domains;
|
||||
}
|
||||
|
||||
streamServerCount = streamServers.length;
|
||||
streamServerIndex = Math.floor(Math.random() * streamServerCount);
|
||||
streamServer = streamServers[streamServerIndex];
|
||||
console.log('Selected Server: ' + streamServer + ' with Index: ' + streamServerIndex);
|
||||
|
||||
initPlayer();
|
||||
}
|
||||
}).catch(function (error) {
|
||||
var alert = document.getElementById('player-alert');
|
||||
if (alert) {
|
||||
alert.innerText = 'The player encountered a problem: ' + error;
|
||||
alert.classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
return player;
|
||||
}
|
||||
+15
-4
@@ -268,9 +268,19 @@ async function initVidstackPlayer() {
|
||||
});
|
||||
}
|
||||
|
||||
window.axios.post('/player/api', {
|
||||
window.setPlayerPreference = function(pref) {
|
||||
localStorage.setItem('hstreamPlayerPreference', pref);
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
const playerPreference = localStorage.getItem('hstreamPlayerPreference') || 'hstream';
|
||||
|
||||
if (playerPreference === 'plyr' && !isIOS()) {
|
||||
import('./player-plyr.js').then(m => m.initPlyrPlayer(document.getElementById('e_id').value));
|
||||
} else {
|
||||
window.axios.post('/player/api', {
|
||||
episode_id: document.getElementById('e_id').value
|
||||
}).then(function (response) {
|
||||
}).then(function (response) {
|
||||
if (response.status === 200) {
|
||||
apiResponse = response.data;
|
||||
streamServers = apiResponse.stream_domains || [];
|
||||
@@ -296,10 +306,11 @@ window.axios.post('/player/api', {
|
||||
initVidstackPlayer();
|
||||
}
|
||||
}
|
||||
}).catch(function (error) {
|
||||
}).catch(function (error) {
|
||||
var alert = document.getElementById('player-alert');
|
||||
if (alert) {
|
||||
alert.innerText = 'The player encountered a problem: ' + error;
|
||||
alert.classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,6 +8,28 @@
|
||||
@endif
|
||||
<canvas id="ambientVideo" class="decoy"></canvas>
|
||||
<div class="relative w-full aspect-[16/9]">
|
||||
<div class="player-switcher" id="player-switcher">
|
||||
<span class="player-switcher__label">Player</span>
|
||||
<button type="button" class="player-switcher__btn" id="plyr-toggle-btn"
|
||||
onclick="window.setPlayerPreference('plyr')" title="Switch to Plyr player">
|
||||
<span class="player-switcher__dot"></span> Plyr
|
||||
</button>
|
||||
<button type="button" class="player-switcher__btn player-switcher__btn--active" id="hstream-toggle-btn"
|
||||
onclick="window.setPlayerPreference('hstream')" title="Switch to HStream player">
|
||||
<span class="player-switcher__dot"></span> HStream
|
||||
</button>
|
||||
</div>
|
||||
<video id="player" playsinline crossorigin class="absolute inset-0 w-full h-full"></video>
|
||||
</div>
|
||||
<script>
|
||||
(function() {
|
||||
var pref = localStorage.getItem('hstreamPlayerPreference') || 'hstream';
|
||||
var hstreamBtn = document.getElementById('hstream-toggle-btn');
|
||||
var plyrBtn = document.getElementById('plyr-toggle-btn');
|
||||
if (pref === 'plyr') {
|
||||
hstreamBtn.classList.remove('player-switcher__btn--active');
|
||||
plyrBtn.classList.add('player-switcher__btn--active');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,7 @@ export default defineConfig({
|
||||
'resources/js/modals-playlist.js',
|
||||
'resources/js/theme.js',
|
||||
'resources/js/player.js',
|
||||
'resources/js/player-plyr.js',
|
||||
'resources/js/playlist.js',
|
||||
'resources/js/upload.js',
|
||||
'resources/js/user-blacklist.js',
|
||||
|
||||
Reference in New Issue
Block a user