Full overhawl of video & audio playback to make it more complete (#1432)

* Add support for capturing media attributes in rrweb-snapshot

* Add loop to mediaInteractionParam

* Add support for loop in RRMediaElement

* Add support for recording loop attribute on media elements

* Update video playback and fix bugs

* Update cross-origin iframe media attributes and player state
This commit is contained in:
Justin Halsall
2026-04-01 12:00:00 +08:00
committed by GitHub
parent c61c906e31
commit f6543be763
28 changed files with 1886 additions and 59 deletions

View File

@@ -342,6 +342,17 @@ function buildNode(
break;
default:
}
} else if (
name === 'rr_mediaPlaybackRate' &&
typeof value === 'number'
) {
(node as HTMLMediaElement).playbackRate = value;
} else if (name === 'rr_mediaMuted' && typeof value === 'boolean') {
(node as HTMLMediaElement).muted = value;
} else if (name === 'rr_mediaLoop' && typeof value === 'boolean') {
(node as HTMLMediaElement).loop = value;
} else if (name === 'rr_mediaVolume' && typeof value === 'number') {
(node as HTMLMediaElement).volume = value;
}
}

View File

@@ -12,6 +12,7 @@ import {
ICanvas,
elementNode,
serializedElementNodeWithId,
type mediaAttributes,
} from './types';
import {
Mirror,
@@ -761,10 +762,15 @@ function serializeElementNode(
}
// media elements
if (tagName === 'audio' || tagName === 'video') {
attributes.rr_mediaState = (n as HTMLMediaElement).paused
const mediaAttributes = attributes as mediaAttributes;
mediaAttributes.rr_mediaState = (n as HTMLMediaElement).paused
? 'paused'
: 'played';
attributes.rr_mediaCurrentTime = (n as HTMLMediaElement).currentTime;
mediaAttributes.rr_mediaCurrentTime = (n as HTMLMediaElement).currentTime;
mediaAttributes.rr_mediaPlaybackRate = (n as HTMLMediaElement).playbackRate;
mediaAttributes.rr_mediaMuted = (n as HTMLMediaElement).muted;
mediaAttributes.rr_mediaLoop = (n as HTMLMediaElement).loop;
mediaAttributes.rr_mediaVolume = (n as HTMLMediaElement).volume;
}
// Scroll
if (!newlyAddedElement) {

View File

@@ -82,6 +82,27 @@ export type tagMap = {
[key: string]: string;
};
export type mediaAttributes = {
rr_mediaState: 'played' | 'paused';
rr_mediaCurrentTime: number;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaPlaybackRate?: number;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaMuted?: boolean;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaLoop?: boolean;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaVolume?: number;
};
// @deprecated
export interface INode extends Node {
__sn: serializedNodeWithId;