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

Add enum for media errors

This commit is contained in:
Bill Thornton 2024-03-08 17:41:02 -05:00
parent 94c5b586db
commit 081d408b18
5 changed files with 52 additions and 26 deletions

View file

@ -1,6 +1,7 @@
import appSettings from '../scripts/settings/appSettings' ; import appSettings from '../scripts/settings/appSettings' ;
import browser from '../scripts/browser'; import browser from '../scripts/browser';
import Events from '../utils/events.ts'; import Events from '../utils/events.ts';
import { MediaError } from 'types/mediaError';
export function getSavedVolume() { export function getSavedVolume() {
return appSettings.get('volume') || 1; return appSettings.get('volume') || 1;
@ -87,7 +88,7 @@ export function handleHlsJsMediaError(instance, reject) {
if (reject) { if (reject) {
reject(); reject();
} else { } else {
onErrorInternal(instance, 'mediadecodeerror'); onErrorInternal(instance, MediaError.MEDIA_DECODE_ERROR);
} }
} }
} }
@ -269,10 +270,10 @@ export function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, r
hls.destroy(); hls.destroy();
if (reject) { if (reject) {
reject('servererror'); reject(MediaError.SERVER_ERROR);
reject = null; reject = null;
} else { } else {
onErrorInternal(instance, 'servererror'); onErrorInternal(instance, MediaError.SERVER_ERROR);
} }
return; return;
@ -291,10 +292,10 @@ export function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, r
hls.destroy(); hls.destroy();
if (reject) { if (reject) {
reject('network'); reject(MediaError.NETWORK_ERROR);
reject = null; reject = null;
} else { } else {
onErrorInternal(instance, 'network'); onErrorInternal(instance, MediaError.NETWORK_ERROR);
} }
} else { } else {
console.debug('fatal network error encountered, try to recover'); console.debug('fatal network error encountered, try to recover');
@ -318,7 +319,7 @@ export function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, r
reject(); reject();
reject = null; reject = null;
} else { } else {
onErrorInternal(instance, 'mediadecodeerror'); onErrorInternal(instance, MediaError.MEDIA_DECODE_ERROR);
} }
break; break;
} }

View file

@ -1,3 +1,6 @@
import merge from 'lodash-es/merge';
import Screenfull from 'screenfull';
import Events from '../../utils/events.ts'; import Events from '../../utils/events.ts';
import datetime from '../../scripts/datetime'; import datetime from '../../scripts/datetime';
import appSettings from '../../scripts/settings/appSettings'; import appSettings from '../../scripts/settings/appSettings';
@ -8,14 +11,14 @@ import * as userSettings from '../../scripts/settings/userSettings';
import globalize from '../../scripts/globalize'; import globalize from '../../scripts/globalize';
import loading from '../loading/loading'; import loading from '../loading/loading';
import { appHost } from '../apphost'; import { appHost } from '../apphost';
import Screenfull from 'screenfull';
import ServerConnections from '../ServerConnections'; import ServerConnections from '../ServerConnections';
import alert from '../alert'; import alert from '../alert';
import { PluginType } from '../../types/plugin.ts'; import { PluginType } from '../../types/plugin.ts';
import { includesAny } from '../../utils/container.ts'; import { includesAny } from '../../utils/container.ts';
import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts'; import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts';
import { getItemBackdropImageUrl } from '../../utils/jellyfin-apiclient/backdropImage'; import { getItemBackdropImageUrl } from '../../utils/jellyfin-apiclient/backdropImage';
import merge from 'lodash-es/merge';
import { MediaError } from 'types/mediaError';
const UNLIMITED_ITEMS = -1; const UNLIMITED_ITEMS = -1;
@ -1768,7 +1771,7 @@ class PlaybackManager {
playerData.isChangingStream = false; playerData.isChangingStream = false;
onPlaybackError.call(player, e, { onPlaybackError.call(player, e, {
type: 'mediadecodeerror', type: MediaError.MEDIA_DECODE_ERROR,
streamInfo: streamInfo streamInfo: streamInfo
}); });
}); });
@ -2551,8 +2554,8 @@ class PlaybackManager {
onPlaybackStarted(player, playOptions, streamInfo, mediaSource); onPlaybackStarted(player, playOptions, streamInfo, mediaSource);
setTimeout(function () { setTimeout(function () {
onPlaybackError.call(player, err, { onPlaybackError.call(player, err, {
type: 'mediadecodeerror', type: MediaError.MEDIA_DECODE_ERROR,
streamInfo: streamInfo streamInfo
}); });
}, 100); }, 100);
}); });
@ -3194,22 +3197,32 @@ class PlaybackManager {
} }
} }
/**
* @param {object} streamInfo
* @param {MediaError} errorType
* @param {boolean} currentlyPreventsVideoStreamCopy
* @param {boolean} currentlyPreventsAudioStreamCopy
* @returns {boolean} Returns true if the stream should be retried by transcoding.
*/
function enablePlaybackRetryWithTranscoding(streamInfo, errorType, currentlyPreventsVideoStreamCopy, currentlyPreventsAudioStreamCopy) { function enablePlaybackRetryWithTranscoding(streamInfo, errorType, currentlyPreventsVideoStreamCopy, currentlyPreventsAudioStreamCopy) {
// mediadecodeerror, medianotsupported, network, servererror
return streamInfo.mediaSource.SupportsTranscoding return streamInfo.mediaSource.SupportsTranscoding
&& (!currentlyPreventsVideoStreamCopy || !currentlyPreventsAudioStreamCopy); && (!currentlyPreventsVideoStreamCopy || !currentlyPreventsAudioStreamCopy);
} }
/**
* Playback error handler.
* @param {Error} e
* @param {object} error
* @param {object} error.streamInfo
* @param {MediaError} error.type
*/
function onPlaybackError(e, error) { function onPlaybackError(e, error) {
const player = this; const player = this;
error = error || {}; error = error || {};
// network
// mediadecodeerror
// medianotsupported
const errorType = error.type; const errorType = error.type;
console.debug('playbackmanager playback error type: ' + (errorType || '')); console.warn('[playbackmanager] onPlaybackError:', error);
const streamInfo = error.streamInfo || getPlayerData(player).streamInfo; const streamInfo = error.streamInfo || getPlayerData(player).streamInfo;
@ -3235,8 +3248,7 @@ class PlaybackManager {
Events.trigger(self, 'playbackerror', [errorType]); Events.trigger(self, 'playbackerror', [errorType]);
const displayErrorCode = 'NoCompatibleStream'; onPlaybackStopped.call(player, e, `.${errorType}`);
onPlaybackStopped.call(player, e, displayErrorCode);
} }
function onPlaybackStopped(e, displayErrorCode) { function onPlaybackStopped(e, displayErrorCode) {

View file

@ -5,6 +5,7 @@ import profileBuilder from '../../scripts/browserDeviceProfile';
import { getIncludeCorsCredentials } from '../../scripts/settings/webSettings'; import { getIncludeCorsCredentials } from '../../scripts/settings/webSettings';
import { PluginType } from '../../types/plugin.ts'; import { PluginType } from '../../types/plugin.ts';
import Events from '../../utils/events.ts'; import Events from '../../utils/events.ts';
import { MediaError } from 'types/mediaError';
function getDefaultProfile() { function getDefaultProfile() {
return profileBuilder({}); return profileBuilder({});
@ -343,7 +344,7 @@ class HtmlAudioPlayer {
return; return;
case 2: case 2:
// MEDIA_ERR_NETWORK // MEDIA_ERR_NETWORK
type = 'network'; type = MediaError.NETWORK_ERROR;
break; break;
case 3: case 3:
// MEDIA_ERR_DECODE // MEDIA_ERR_DECODE
@ -351,12 +352,12 @@ class HtmlAudioPlayer {
htmlMediaHelper.handleHlsJsMediaError(self); htmlMediaHelper.handleHlsJsMediaError(self);
return; return;
} else { } else {
type = 'mediadecodeerror'; type = MediaError.MEDIA_DECODE_ERROR;
} }
break; break;
case 4: case 4:
// MEDIA_ERR_SRC_NOT_SUPPORTED // MEDIA_ERR_SRC_NOT_SUPPORTED
type = 'medianotsupported'; type = MediaError.MEDIA_NOT_SUPPORTED;
break; break;
default: default:
// seeing cases where Edge is firing error events with no error code // seeing cases where Edge is firing error events with no error code

View file

@ -37,6 +37,7 @@ import Events from '../../utils/events.ts';
import { includesAny } from '../../utils/container.ts'; import { includesAny } from '../../utils/container.ts';
import { isHls } from '../../utils/mediaSource.ts'; import { isHls } from '../../utils/mediaSource.ts';
import debounce from 'lodash-es/debounce'; import debounce from 'lodash-es/debounce';
import { MediaError } from 'types/mediaError';
/** /**
* Returns resolved URL. * Returns resolved URL.
@ -1021,7 +1022,8 @@ export class HtmlVideoPlayer {
// Only trigger this if there is media info // 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) // Avoid triggering in situations where it might not actually have a video stream (audio only live tv channel)
if (!mediaSource || mediaSource.RunTimeTicks) { if (!mediaSource || mediaSource.RunTimeTicks) {
onErrorInternal(this, 'mediadecodeerror'); // FIXME: This shouldn't really be a decode error...
onErrorInternal(this, MediaError.MEDIA_DECODE_ERROR);
} }
} }
} }
@ -1073,7 +1075,7 @@ export class HtmlVideoPlayer {
return; return;
case 2: case 2:
// MEDIA_ERR_NETWORK // MEDIA_ERR_NETWORK
type = 'network'; type = MediaError.NETWORK_ERROR;
break; break;
case 3: case 3:
// MEDIA_ERR_DECODE // MEDIA_ERR_DECODE
@ -1081,12 +1083,12 @@ export class HtmlVideoPlayer {
handleHlsJsMediaError(this); handleHlsJsMediaError(this);
return; return;
} else { } else {
type = 'mediadecodeerror'; type = MediaError.MEDIA_DECODE_ERROR;
} }
break; break;
case 4: case 4:
// MEDIA_ERR_SRC_NOT_SUPPORTED // MEDIA_ERR_SRC_NOT_SUPPORTED
type = 'medianotsupported'; type = MediaError.MEDIA_NOT_SUPPORTED;
break; break;
default: default:
// seeing cases where Edge is firing error events with no error code // seeing cases where Edge is firing error events with no error code
@ -1276,7 +1278,8 @@ export class HtmlVideoPlayer {
// HACK: Give JavascriptSubtitlesOctopus time to dispose itself // HACK: Give JavascriptSubtitlesOctopus time to dispose itself
setTimeout(() => { setTimeout(() => {
onErrorInternal(htmlVideoPlayer, 'mediadecodeerror'); // FIXME: Probably not a decode error...
onErrorInternal(this, MediaError.MEDIA_DECODE_ERROR);
}, 0); }, 0);
}, },
timeOffset: (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000, timeOffset: (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000,

9
src/types/mediaError.ts Normal file
View file

@ -0,0 +1,9 @@
/**
* Error types used for reporting media playback errors.
*/
export enum MediaError {
MEDIA_DECODE_ERROR = 'mediadecodeerror',
MEDIA_NOT_SUPPORTED = 'medianotsupported',
NETWORK_ERROR = 'network',
SERVER_ERROR = 'servererror'
}