diff --git a/assets/css/sabr_player.css b/assets/css/sabr_player.css
index 07af1191d..bedec6b66 100644
--- a/assets/css/sabr_player.css
+++ b/assets/css/sabr_player.css
@@ -176,17 +176,7 @@
background-color: rgba(35, 35, 35, 0.9) !important;
}
-/* Spinner */
-.shaka-spinner-container {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
-}
-
-.shaka-spinner {
- border-color: rgba(0, 182, 240, 1) transparent transparent transparent !important;
-}
+/* Shaka 5 spinner uses full-container flex centering; do not override container position. */
/* Captions/subtitles - match video.js */
.shaka-text-container {
diff --git a/assets/js/sabr_player.js b/assets/js/sabr_player.js
index 67420dbcc..76eff37e6 100644
--- a/assets/js/sabr_player.js
+++ b/assets/js/sabr_player.js
@@ -459,26 +459,33 @@ var SABRPlayer = (function () {
playbackWebPoTokenContentBinding = videoId;
try {
- if (!innertube) {
- innertube = await initInnertube();
- if (!innertube) throw new Error('Failed to initialize Innertube');
- }
- if (!clientConfig) {
- await fetchOnesieConfig();
- }
-
- // Mint a content-bound PoToken before getInfo so streaming_data includes
- // the server_abr_streaming_url and so the SABR requests authenticate.
- try { await mintContentWebPO(); } catch (e) { console.warn('[SABRPlayer] poToken mint failed, continuing', e); }
- var poToken = playbackWebPoToken || coldStartToken || '';
-
+ // Start Shaka player init (DOM + polyfills) in parallel with network init.
+ var shakaPromise;
if (!player) {
- await initializeShakaPlayer(containerElement, options.listen);
+ shakaPromise = initializeShakaPlayer(containerElement, options.listen);
} else {
player.configure('abr', DEFAULT_ABR_CONFIG);
player.configure('manifest.disableVideo', !!options.listen);
+ shakaPromise = Promise.resolve();
}
+ // Network init chain: Innertube → Onesie config → PoToken.
+ var netPromise = (async function () {
+ if (!innertube) {
+ innertube = await initInnertube();
+ if (!innertube) throw new Error('Failed to initialize Innertube');
+ }
+ if (!clientConfig) {
+ await fetchOnesieConfig();
+ }
+ // Mint a content-bound PoToken before getInfo so streaming_data includes
+ // the server_abr_streaming_url and so the SABR requests authenticate.
+ try { await mintContentWebPO(); } catch (e) { console.warn('[SABRPlayer] poToken mint failed, continuing', e); }
+ })();
+
+ await Promise.all([shakaPromise, netPromise]);
+ var poToken = playbackWebPoToken || coldStartToken || '';
+
setupRequestFilters();
var videoInfo = await innertube.getInfo(videoId, { po_token: poToken || undefined });
diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr
index bed7c1d7b..abd2b46e3 100644
--- a/src/invidious/views/components/player.ecr
+++ b/src/invidious/views/components/player.ecr
@@ -111,20 +111,22 @@
<% if use_sabr %>
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
<% else %>