Skip to content

Instantly share code, notes, and snippets.

@wplit
Created April 15, 2025 00:07
Show Gist options
  • Save wplit/29c373d24f081b96ad31ce943cf4e441 to your computer and use it in GitHub Desktop.
Save wplit/29c373d24f081b96ad31ce943cf4e441 to your computer and use it in GitHub Desktop.
fix vidstack PIP issue
// Fix for PIP button issue with multiple players
function fixPIPMediaSessionIssue() {
// Keep track of which player is currently in PIP mode
let pipPlayer = null;
// Store original mediaSession handlers
const originalHandlers = {};
// Function to capture and store the original mediaSession handlers
function captureOriginalHandlers() {
if (typeof navigator !== 'undefined' && 'mediaSession' in navigator) {
// Store original handlers if they exist
['play', 'pause', 'seekbackward', 'seekforward'].forEach(action => {
if (navigator.mediaSession.setActionHandler) {
originalHandlers[action] = navigator.mediaSession.actionHandler?.[action];
}
});
}
}
// Function to override mediaSession handlers to target the PIP player
function overrideMediaSessionHandlers() {
if (typeof navigator !== 'undefined' && 'mediaSession' in navigator && pipPlayer) {
// Override play handler
navigator.mediaSession.setActionHandler('play', () => {
if (pipPlayer && pipPlayer.paused) {
pipPlayer.play();
} else if (originalHandlers.play) {
originalHandlers.play();
}
});
// Override pause handler
navigator.mediaSession.setActionHandler('pause', () => {
if (pipPlayer && !pipPlayer.paused) {
pipPlayer.pause();
} else if (originalHandlers.pause) {
originalHandlers.pause();
}
});
// Override seekbackward handler
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
if (pipPlayer) {
const skipTime = details.seekOffset || 10;
pipPlayer.currentTime = Math.max(pipPlayer.currentTime - skipTime, 0);
} else if (originalHandlers.seekbackward) {
originalHandlers.seekbackward(details);
}
});
// Override seekforward handler
navigator.mediaSession.setActionHandler('seekforward', (details) => {
if (pipPlayer) {
const skipTime = details.seekOffset || 10;
pipPlayer.currentTime = Math.min(pipPlayer.currentTime + skipTime, pipPlayer.duration || 0);
} else if (originalHandlers.seekforward) {
originalHandlers.seekforward(details);
}
});
}
}
// Function to restore original mediaSession handlers
function restoreOriginalHandlers() {
if (typeof navigator !== 'undefined' && 'mediaSession' in navigator) {
Object.keys(originalHandlers).forEach(action => {
if (navigator.mediaSession.setActionHandler) {
navigator.mediaSession.setActionHandler(action, originalHandlers[action]);
}
});
}
}
// Monitor for PIP changes
document.addEventListener('enterpictureinpicture', (event) => {
// Find the Vidstack player that contains this video element
const videoElement = event.target;
const playerElement = videoElement.closest('media-player');
if (playerElement) {
// Capture handlers when first entering PIP
if (!pipPlayer) {
captureOriginalHandlers();
}
pipPlayer = playerElement;
overrideMediaSessionHandlers();
}
}, true);
document.addEventListener('leavepictureinpicture', () => {
pipPlayer = null;
restoreOriginalHandlers();
}, true);
}
// Initialize the PIP fix
fixPIPMediaSessionIssue();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment