Skip to content

Instantly share code, notes, and snippets.

@casebeer
Created February 19, 2026 23:56
Show Gist options
  • Select an option

  • Save casebeer/c9f7e3764b93b62a4a0a936a7e31b8ad to your computer and use it in GitHub Desktop.

Select an option

Save casebeer/c9f7e3764b93b62a4a0a936a7e31b8ad to your computer and use it in GitHub Desktop.
Reset an HTML5 <video> element so it can be reused. Avoids race condition with setMediaKeys.
/*
* Unload any previous media and keys from <video> element
**/
const resetVideoElt = async (videoElt) => {
const videoEltEmptied= new Promise((resolve) => { videoElt.addEventListener('emptied', (e) => {
//console.log(e);
resolve();
}, { once: true }) });
videoElt.pause();
videoElt.src = '';
videoElt.removeAttribute('src');
await videoEltEmptied;
videoElt.load();
console.log('Video unloaded.');
await new Promise((resolve) => setTimeout(resolve, 10));
// Try to clear media keys until we succeed. Attempting to clear media keys while encrypted
// video is playing or a setMediaKeys() call is already in progress results in error:
// Failed to execute 'setMediaKeys' on 'HTMLMediaElement': Another request is in progress.
await (async () => {
let backoff = 10;
while (true) {
try {
await videoElt.setMediaKeys(null);
console.log('Cleared media keys.');
return;
} catch (e) {
console.log('Race condition clearing media keys, will retry.');
await new Promise((resolve) => setTimeout(resolve, backoff));
backoff *= 2;
}
}
})();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment