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:
parent
94c5b586db
commit
081d408b18
5 changed files with 52 additions and 26 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
9
src/types/mediaError.ts
Normal 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'
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue