On iOS 15.1, certain interruptions (like incoming calls or backgrounding the browser) can cause VideoTracks to go black or the page to freeze. You can implement a shim that listens for pause and play events on the video element to intelligently re-attach the track.
// Keeps track of video elements and their event listeners
const videoElements = {};
// Listen to onPlay and onPause events and intelligently re-attach the video element
function shimVideoElement(track, el) {
let wasInterrupted = false;
const onPause = () => {
wasInterrupted = true;
};
const onPlay = () => {
if (wasInterrupted) {
track.detach(el);
track.attach(el);
wasInterrupted = false;
}
};
el.addEventListener('pause', onPause);
el.addEventListener('play', onPlay);
// Track this element so we can remove the listeners
videoElements[el] = { onPause, onPlay };
}
// Apply the workaround after attaching the video element.
videoTrack.attach(videoElement);
shimVideoElement(videoTrack, videoElement);
// Remove the listeners before detaching the video element.
const { onPause, onPlay } = videoElements[videoElement];
videoElement.removeEventListener('pause', onPause);
videoElement.removeEventListener('play', onPlay);