Skip to content

Commit 1c80e51

Browse files
committed
Guards against missing VideoJS plugins/elements
Adds checks to ensure VideoJS plugins and control elements exist before attempting to initialize or modify them. This prevents errors when certain plugins or elements are not available or have not yet been initialized, improving robustness. Also includes logic to dispose and remove a previously initialized player to resolve conflicts during initialization.
1 parent 11865e7 commit 1c80e51

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

ui/component/viewers/videoViewer/internal/plugins/videojs-mobile-ui/plugin.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,19 @@ const onPlayerReady = (player, options) => {
6666

6767
const controlBar = player.getChild('ControlBar');
6868

69-
// Insert before the ControlBar:
69+
// Guard: ControlBar must exist and be in the player's children
70+
if (!controlBar) {
71+
videojs.log.warn('mobileUi: ControlBar not found, skipping mobile UI setup');
72+
return;
73+
}
74+
7075
const controlBarIdx = player.children_.indexOf(controlBar);
76+
if (controlBarIdx === -1) {
77+
videojs.log.warn('mobileUi: ControlBar not in player children, skipping mobile UI setup');
78+
return;
79+
}
80+
81+
// Insert before the ControlBar:
7182
player.addChild('touchOverlay', options.touchControls, controlBarIdx);
7283

7384
// Make the TouchOverlay the new parent of the ControlBar.

ui/component/viewers/videoViewer/internal/videojs.jsx

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -327,24 +327,30 @@ export default React.memo<Props>(function VideoJs(props: Props) {
327327

328328
player.appState = {};
329329

330-
player.reloadSourceOnError({ errorInterval: 10 });
331-
332-
player.mobileUi({
333-
fullscreen: {
334-
enterOnRotate: false,
335-
},
336-
touchControls: {
337-
seekSeconds: 10,
338-
},
339-
});
340-
341-
player.i18n();
342-
player.settingsMenu();
343-
player.timeMarkerPlugin();
344-
player.hlsQualitySelector({ displayCurrentQuality: true });
330+
if (typeof player.reloadSourceOnError === 'function') {
331+
player.reloadSourceOnError({ errorInterval: 10 });
332+
}
333+
334+
if (typeof player.mobileUi === 'function') {
335+
player.mobileUi({
336+
fullscreen: {
337+
enterOnRotate: false,
338+
},
339+
touchControls: {
340+
seekSeconds: 10,
341+
},
342+
});
343+
}
344+
345+
if (typeof player.i18n === 'function') player.i18n();
346+
if (typeof player.settingsMenu === 'function') player.settingsMenu();
347+
if (typeof player.timeMarkerPlugin === 'function') player.timeMarkerPlugin();
348+
if (typeof player.hlsQualitySelector === 'function') {
349+
player.hlsQualitySelector({ displayCurrentQuality: true });
350+
}
345351

346352
// Add recsys plugin
347-
if (shareTelemetry) {
353+
if (shareTelemetry && typeof player.recsys === 'function') {
348354
player.recsys({
349355
videoId: claimId,
350356
userId: userId,
@@ -359,13 +365,15 @@ export default React.memo<Props>(function VideoJs(props: Props) {
359365

360366
Chromecast.initialize(player);
361367

362-
player.airPlay();
368+
if (typeof player.airPlay === 'function') player.airPlay();
363369

364-
player.watchdog({
365-
timeoutMs: 15000,
366-
livestreamsOnly: true,
367-
action: () => setReload(Date.now()),
368-
});
370+
if (typeof player.watchdog === 'function') {
371+
player.watchdog({
372+
timeoutMs: 15000,
373+
livestreamsOnly: true,
374+
action: () => setReload(Date.now()),
375+
});
376+
}
369377
});
370378

371379
// fixes #3498 (https://github.com/lbryio/lbry-desktop/issues/3498)
@@ -403,6 +411,17 @@ export default React.memo<Props>(function VideoJs(props: Props) {
403411

404412
// initialize videojs if it hasn't been done yet
405413
if (!canUseOldPlayer) {
414+
// Dispose old player if it exists to prevent "already initialised" conflicts
415+
if (window.player && typeof window.player.dispose === 'function') {
416+
try {
417+
window.player.dispose();
418+
} catch (e) {
419+
console.warn('Failed to dispose old player:', e);
420+
}
421+
window.player = null;
422+
window.oldSavedDiv = null;
423+
}
424+
406425
const vjsElement = createVideoPlayerDOM(containerRef.current);
407426
vjsPlayer = initializeVideoPlayer(vjsElement);
408427
if (!vjsPlayer) {

0 commit comments

Comments
 (0)