1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge branch 'master' into enable-airplay-audioplayer

This commit is contained in:
stamatovg 2023-07-20 18:10:13 +03:00 committed by GitHub
commit e0d4aa6c77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
227 changed files with 5818 additions and 2022 deletions

View file

@ -384,7 +384,7 @@ export class BookPlayer {
}
canPlayItem(item) {
return item.Path && item.Path.endsWith('epub');
return item.Path?.endsWith('epub');
}
}

View file

@ -2,7 +2,7 @@ import appSettings from '../../scripts/settings/appSettings';
import * as userSettings from '../../scripts/settings/userSettings';
import { playbackManager } from '../../components/playback/playbackmanager';
import globalize from '../../scripts/globalize';
import castSenderApiLoader from './castSenderApi';
import CastSenderApi from './castSenderApi';
import ServerConnections from '../../components/ServerConnections';
import alert from '../../components/alert';
import { PluginType } from '../../types/plugin.ts';
@ -103,7 +103,7 @@ class CastPlayer {
return;
}
if (!chrome.cast || !chrome.cast.isAvailable) {
if (!chrome.cast?.isAvailable) {
setTimeout(this.initializeCastPlayer.bind(this), 1000);
return;
}
@ -322,14 +322,14 @@ class CastPlayer {
const session = player.session;
if (session && session.receiver && session.receiver.friendlyName) {
if (session?.receiver?.friendlyName) {
receiverName = session.receiver.friendlyName;
}
let apiClient;
if (message.options && message.options.ServerId) {
if (message.options?.ServerId) {
apiClient = ServerConnections.getApiClient(message.options.ServerId);
} else if (message.options && message.options.items && message.options.items.length) {
} else if (message.options?.items?.length) {
apiClient = ServerConnections.getApiClient(message.options.items[0].ServerId);
} else {
apiClient = ServerConnections.currentApiClient();
@ -350,7 +350,7 @@ class CastPlayer {
message.maxBitrate = bitrateSetting;
}
if (message.options && message.options.items) {
if (message.options?.items) {
message.subtitleAppearance = userSettings.getSubtitleAppearanceSettings();
message.subtitleBurnIn = appSettings.get('subtitleburnin') || '';
}
@ -451,10 +451,10 @@ function onVolumeDownKeyDown() {
}
function normalizeImages(state) {
if (state && state.NowPlayingItem) {
if (state?.NowPlayingItem) {
const item = state.NowPlayingItem;
if ((!item.ImageTags || !item.ImageTags.Primary) && item.PrimaryImageTag) {
if ((!item.ImageTags?.Primary) && item.PrimaryImageTag) {
item.ImageTags = item.ImageTags || {};
item.ImageTags.Primary = item.PrimaryImageTag;
}
@ -576,7 +576,7 @@ class ChromecastPlayer {
this.isLocalPlayer = false;
this.lastPlayerData = {};
new castSenderApiLoader().load().then(initializeChromecast.bind(this));
new CastSenderApi().load().then(initializeChromecast.bind(this));
}
tryPair() {
@ -599,7 +599,7 @@ class ChromecastPlayer {
getTargets() {
const targets = [];
if (this._castPlayer && this._castPlayer.hasReceivers) {
if (this._castPlayer?.hasReceivers) {
targets.push(this.getCurrentTargetInfo());
}
@ -612,7 +612,7 @@ class ChromecastPlayer {
const castPlayer = this._castPlayer;
if (castPlayer.session && castPlayer.session.receiver && castPlayer.session.receiver.friendlyName) {
if (castPlayer.session?.receiver?.friendlyName) {
appName = castPlayer.session.receiver.friendlyName;
}

View file

@ -417,7 +417,7 @@ class HtmlAudioPlayer {
const mediaElement = this._mediaElement;
if (mediaElement) {
const seekable = mediaElement.seekable;
if (seekable && seekable.length) {
if (seekable?.length) {
let start = seekable.start(0);
let end = seekable.end(0);

View file

@ -1,3 +1,5 @@
import DOMPurify from 'dompurify';
import browser from '../../scripts/browser';
import { appHost } from '../../components/apphost';
import loading from '../../components/loading/loading';
@ -434,6 +436,7 @@ export class HtmlVideoPlayer {
const includeCorsCredentials = await getIncludeCorsCredentials();
const hls = new Hls({
startPosition: options.playerStartPositionTicks / 10000000,
manifestLoadingTimeOut: 20000,
maxBufferLength: maxBufferLength,
xhrSetup(xhr) {
@ -1008,7 +1011,7 @@ export class HtmlVideoPlayer {
}
if (elem.videoWidth === 0 && elem.videoHeight === 0) {
const mediaSource = (this._currentPlayOptions || {}).mediaSource;
const mediaSource = this._currentPlayOptions?.mediaSource;
// Only trigger this if there is media info
// Avoid triggering in situations where it might not actually have a video stream (audio only live tv channel)
@ -1269,13 +1272,13 @@ export class HtmlVideoPlayer {
availableFonts: { 'liberation sans': `${appRouter.baseUrl()}/default.woff2` },
// Disabled eslint compat, but is safe as corejs3 polyfills URL
// eslint-disable-next-line compat/compat
workerUrl: new URL('jassub/dist/jassub-worker.js', import.meta.url),
workerUrl: new URL('jassub/dist/jassub-worker.js', import.meta.url).href,
// eslint-disable-next-line compat/compat
wasmUrl: new URL('jassub/dist/jassub-worker.wasm', import.meta.url),
wasmUrl: new URL('jassub/dist/jassub-worker.wasm', import.meta.url).href,
// eslint-disable-next-line compat/compat
legacyWasmUrl: new URL('jassub/dist/jassub-worker.wasm.js', import.meta.url),
legacyWasmUrl: new URL('jassub/dist/jassub-worker.wasm.js', import.meta.url).href,
// eslint-disable-next-line compat/compat
modernWasmUrl : new URL('jassub/dist/jassub-worker-modern.wasm', import.meta.url),
modernWasmUrl : new URL('jassub/dist/jassub-worker-modern.wasm', import.meta.url).href,
timeOffset: (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000,
// new jassub options; override all, even defaults
blendMode: 'js',
@ -1488,8 +1491,8 @@ export class HtmlVideoPlayer {
// add some cues to show the text
// in safari, the cues need to be added before setting the track mode to showing
for (const trackEvent of data.TrackEvents) {
const trackCueObject = window.VTTCue || window.TextTrackCue;
const cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false));
const TrackCue = window.VTTCue || window.TextTrackCue;
const cue = new TrackCue(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false));
if (cue.line === 'auto') {
cue.line = cueLine;
@ -1534,8 +1537,9 @@ export class HtmlVideoPlayer {
}
}
if (selectedTrackEvent && selectedTrackEvent.Text) {
subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text, true);
if (selectedTrackEvent?.Text) {
subtitleTextElement.innerHTML = DOMPurify.sanitize(
normalizeTrackEventText(selectedTrackEvent.Text, true));
subtitleTextElement.classList.remove('hide');
} else {
subtitleTextElement.classList.add('hide');
@ -1809,7 +1813,7 @@ export class HtmlVideoPlayer {
Windows.UI.ViewManagement.ApplicationView.getForCurrentView().tryEnterViewModeAsync(Windows.UI.ViewManagement.ApplicationViewMode.default);
}
} else {
if (video && video.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === 'function') {
if (video?.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === 'function') {
video.webkitSetPresentationMode(isEnabled ? 'picture-in-picture' : 'inline');
}
}
@ -1888,7 +1892,7 @@ export class HtmlVideoPlayer {
const mediaElement = this.#mediaElement;
if (mediaElement) {
const seekable = mediaElement.seekable;
if (seekable && seekable.length) {
if (seekable?.length) {
let start = seekable.start(0);
let end = seekable.end(0);

View file

@ -25,7 +25,7 @@ export default function () {
const elem = document.querySelector('.logoScreenSaverImage');
if (elem && elem.animate) {
if (elem?.animate) {
const random = randomInt(0, animations.length - 1);
animations[random](elem, 1);

View file

@ -312,7 +312,7 @@ export class PdfPlayer {
}
canPlayItem(item) {
return item.Path && item.Path.endsWith('pdf');
return item.Path?.endsWith('pdf');
}
}

View file

@ -157,7 +157,7 @@ function subscribeToPlayerUpdates(instance) {
}
function normalizeImages(state, apiClient) {
if (state && state.NowPlayingItem) {
if (state?.NowPlayingItem) {
const item = state.NowPlayingItem;
if (!item.ImageTags || !item.ImageTags.Primary && item.PrimaryImageTag) {

View file

@ -246,7 +246,7 @@ class Manager {
/**
* Handles a playback command from the server.
* @param {Object} cmd The playback command.
* @param {Object|null} cmd The playback command.
*/
processCommand(cmd) {
if (cmd === null) return;
@ -294,7 +294,7 @@ class Manager {
/**
* Handles a group state change.
* @param {Object} update The group state update.
* @param {Object|null} update The group state update.
*/
processStateChange(update) {
if (update === null || update.State === null || update.Reason === null) return;