diff --git a/.changeset/gorgeous-eels-rescue.md b/.changeset/gorgeous-eels-rescue.md new file mode 100644 index 0000000000..da921a4e06 --- /dev/null +++ b/.changeset/gorgeous-eels-rescue.md @@ -0,0 +1,5 @@ +--- +"rrweb": patch +--- + +Safer Media play/pause when target is not in fact a MediaElement diff --git a/packages/rrweb/src/record/observer.ts b/packages/rrweb/src/record/observer.ts index 8326d79651..c3415fc765 100644 --- a/packages/rrweb/src/record/observer.ts +++ b/packages/rrweb/src/record/observer.ts @@ -1027,6 +1027,7 @@ function initMediaInteractionObserver({ const target = getEventTarget(event); if ( !target || + !(target instanceof HTMLMediaElement) || isBlocked(target as Node, blockClass, blockSelector, true) ) { return; diff --git a/packages/rrweb/src/replay/media/index.ts b/packages/rrweb/src/replay/media/index.ts index ef577cafa0..075df87d7d 100644 --- a/packages/rrweb/src/replay/media/index.ts +++ b/packages/rrweb/src/replay/media/index.ts @@ -54,7 +54,14 @@ export class MediaManager { this.mediaMap.forEach((_mediaState, target) => { this.syncTargetWithState(target); if (options.pause) { - target.pause(); + try { + target.pause(); + } catch (error) { + this.warn( + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions + `Failed to sync media element: ${error.message || error}`, + ); + } } }); } @@ -104,7 +111,14 @@ export class MediaManager { target.currentTime = seekToTime; } else { - target.pause(); + try { + target.pause(); + } catch (error) { + this.warn( + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions + `Failed to pause during seek: ${error.message || error}`, + ); + } target.currentTime = mediaState.currentTimeAtLastInteraction; } }