diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js
index 70be9c45f1..09eb2a6095 100644
--- a/src/components/htmlMediaHelper.js
+++ b/src/components/htmlMediaHelper.js
@@ -88,7 +88,7 @@ export function handleHlsJsMediaError(instance, reject) {
if (reject) {
reject();
} else {
- onErrorInternal(instance, MediaError.MEDIA_DECODE_ERROR);
+ onErrorInternal(instance, MediaError.FATAL_HLS_ERROR);
}
}
}
@@ -99,11 +99,7 @@ export function onErrorInternal(instance, type) {
instance.destroyCustomTrack(instance._mediaElement);
}
- Events.trigger(instance, 'error', [
- {
- type: type
- }
- ]);
+ Events.trigger(instance, 'error', [{ type }]);
}
export function isValidDuration(duration) {
@@ -319,7 +315,7 @@ export function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, r
reject();
reject = null;
} else {
- onErrorInternal(instance, MediaError.MEDIA_DECODE_ERROR);
+ onErrorInternal(instance, MediaError.FATAL_HLS_ERROR);
}
break;
}
diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js
index 32108e77d5..cfdfcbdb52 100644
--- a/src/components/playback/playbackmanager.js
+++ b/src/components/playback/playbackmanager.js
@@ -1,3 +1,4 @@
+import { PlaybackErrorCode } from '@jellyfin/sdk/lib/generated-client/models/playback-error-code.js';
import merge from 'lodash-es/merge';
import Screenfull from 'screenfull';
@@ -591,9 +592,18 @@ function supportsDirectPlay(apiClient, item, mediaSource) {
return Promise.resolve(false);
}
+/**
+ * @param {PlaybackManager} instance
+ * @param {import('@jellyfin/sdk/lib/generated-client/index.js').PlaybackInfoResponse} result
+ * @returns {boolean}
+ */
function validatePlaybackInfoResult(instance, result) {
if (result.ErrorCode) {
- showPlaybackInfoErrorMessage(instance, 'PlaybackError' + result.ErrorCode);
+ // NOTE: To avoid needing to retranslate the "NoCompatibleStream" message,
+ // we need to keep the key in the same format.
+ const errMessage = result.ErrorCode === PlaybackErrorCode.NoCompatibleStream ?
+ 'PlaybackErrorNoCompatibleStream' : `PlaybackError.${result.ErrorCode}`;
+ showPlaybackInfoErrorMessage(instance, errMessage);
return false;
}
@@ -1723,7 +1733,7 @@ class PlaybackManager {
streamInfo.resetSubtitleOffset = false;
if (!streamInfo.url) {
- showPlaybackInfoErrorMessage(self, 'PlaybackErrorNoCompatibleStream');
+ showPlaybackInfoErrorMessage(self, `PlaybackError.${MediaError.NO_MEDIA_ERROR}`);
return;
}
@@ -1771,7 +1781,7 @@ class PlaybackManager {
playerData.isChangingStream = false;
onPlaybackError.call(player, e, {
- type: MediaError.MEDIA_DECODE_ERROR,
+ type: MediaError.PLAYER_ERROR,
streamInfo: streamInfo
});
});
@@ -2182,7 +2192,7 @@ class PlaybackManager {
// If it's still null then there's nothing to play
if (!firstItem) {
- showPlaybackInfoErrorMessage(self, 'PlaybackErrorNoCompatibleStream');
+ showPlaybackInfoErrorMessage(self, `PlaybackError.${MediaError.NO_MEDIA_ERROR}`);
return Promise.reject();
}
@@ -2554,7 +2564,7 @@ class PlaybackManager {
onPlaybackStarted(player, playOptions, streamInfo, mediaSource);
setTimeout(function () {
onPlaybackError.call(player, err, {
- type: MediaError.MEDIA_DECODE_ERROR,
+ type: MediaError.PLAYER_ERROR,
streamInfo
});
}, 100);
@@ -2788,7 +2798,7 @@ class PlaybackManager {
return mediaSource;
}
} else {
- showPlaybackInfoErrorMessage(self, 'PlaybackErrorNoCompatibleStream');
+ showPlaybackInfoErrorMessage(self, `PlaybackError.${MediaError.NO_MEDIA_ERROR}`);
return Promise.reject();
}
});
diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js
index 6185ecdafe..6f78cb80c1 100644
--- a/src/plugins/htmlVideoPlayer/plugin.js
+++ b/src/plugins/htmlVideoPlayer/plugin.js
@@ -1022,8 +1022,7 @@ export class HtmlVideoPlayer {
// 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)
if (!mediaSource || mediaSource.RunTimeTicks) {
- // FIXME: This shouldn't really be a decode error...
- onErrorInternal(this, MediaError.MEDIA_DECODE_ERROR);
+ onErrorInternal(this, MediaError.NO_MEDIA_ERROR);
}
}
}
@@ -1279,7 +1278,7 @@ export class HtmlVideoPlayer {
// HACK: Give JavascriptSubtitlesOctopus time to dispose itself
setTimeout(() => {
// FIXME: Probably not a decode error...
- onErrorInternal(this, MediaError.MEDIA_DECODE_ERROR);
+ onErrorInternal(this, MediaError.ASS_RENDER_ERROR);
}, 0);
},
timeOffset: (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000,
diff --git a/src/strings/en-us.json b/src/strings/en-us.json
index 13363d303f..e0318abe6d 100644
--- a/src/strings/en-us.json
+++ b/src/strings/en-us.json
@@ -1228,6 +1228,16 @@
"Play": "Play",
"PlayAllFromHere": "Play all from here",
"PlaybackData": "Playback Info",
+ "PlaybackError.ASS_RENDER_ERROR": "",
+ "PlaybackError.FATAL_HLS_ERROR": "",
+ "PlaybackError.MEDIA_DECODE_ERROR": "",
+ "PlaybackError.MEDIA_NOT_SUPPORTED": "",
+ "PlaybackError.NETWORK_ERROR": "",
+ "PlaybackError.NO_MEDIA_ERROR": "",
+ "PlaybackError.PLAYER_ERROR": "",
+ "PlaybackError.SERVER_ERROR": "",
+ "PlaybackError.NotAllowed": "",
+ "PlaybackError.RateLimitExceeded": "",
"PlaybackErrorNoCompatibleStream": "This client isn't compatible with the media and the server isn't sending a compatible media format.",
"PlaybackErrorPlaceHolder": "This is a placeholder for physical media that Jellyfin cannot play. Please insert the disc to play.",
"PlaybackRate": "Playback Speed",
diff --git a/src/types/mediaError.ts b/src/types/mediaError.ts
index 8124d38f13..d12d74f17f 100644
--- a/src/types/mediaError.ts
+++ b/src/types/mediaError.ts
@@ -2,8 +2,12 @@
* 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'
+ ASS_RENDER_ERROR = 'ASS_RENDER_ERROR',
+ FATAL_HLS_ERROR = 'FATAL_HLS_ERROR',
+ MEDIA_DECODE_ERROR = 'MEDIA_DECODE_ERROR',
+ MEDIA_NOT_SUPPORTED = 'MEDIA_NOT_SUPPORTED',
+ NETWORK_ERROR = 'NETWORK_ERROR',
+ NO_MEDIA_ERROR = 'NO_MEDIA_ERROR',
+ PLAYER_ERROR = 'PLAYER_ERROR',
+ SERVER_ERROR = 'SERVER_ERROR'
}