impl #796 observe media volume change (#798)

This commit is contained in:
yz-yu
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 151debad4a
commit 9890b8db7c
5 changed files with 36 additions and 12 deletions

View File

@@ -31,9 +31,11 @@ rrweb.record({
// do not record mouse movement // do not record mouse movement
mousemove: false mousemove: false
// do not record mouse interaction // do not record mouse interaction
mouseInteraction: false, mouseInteraction: false
// set the interval of scrolling event // set the interval of scrolling event
scroll: 150 // do not emit twice in 150ms scroll: 150 // do not emit twice in 150ms
// set the interval of media interaction event
media: 800
// set the timing of record input // set the timing of record input
input: 'last' // When input mulitple characters, only record the final input input: 'last' // When input mulitple characters, only record the final input
} }

View File

@@ -34,6 +34,8 @@ rrweb.record({
mouseInteraction: false, mouseInteraction: false,
// 设置滚动事件的触发频率 // 设置滚动事件的触发频率
scroll: 150 // 每 150ms 最多触发一次 scroll: 150 // 每 150ms 最多触发一次
// set the interval of media interaction event
media: 800
// 设置输入事件的录制时机 // 设置输入事件的录制时机
input: 'last' // 连续输入时,只录制最终值 input: 'last' // 连续输入时,只录制最终值
} }

View File

@@ -684,22 +684,28 @@ function initMediaInteractionObserver(
mediaInteractionCb: mediaInteractionCallback, mediaInteractionCb: mediaInteractionCallback,
blockClass: blockClass, blockClass: blockClass,
mirror: Mirror, mirror: Mirror,
sampling: SamplingStrategy,
): listenerHandler { ): listenerHandler {
const handler = (type: MediaInteractions) => (event: Event) => { const handler = (type: MediaInteractions) =>
const target = getEventTarget(event); throttle((event: Event) => {
if (!target || isBlocked(target as Node, blockClass)) { const target = getEventTarget(event);
return; if (!target || isBlocked(target as Node, blockClass)) {
} return;
mediaInteractionCb({ }
type, const { currentTime, volume, muted } = target as HTMLMediaElement;
id: mirror.getId(target as INode), mediaInteractionCb({
currentTime: (target as HTMLMediaElement).currentTime, type,
}); id: mirror.getId(target as INode),
}; currentTime,
volume,
muted,
});
}, sampling.media || 500);
const handlers = [ const handlers = [
on('play', handler(MediaInteractions.Play)), on('play', handler(MediaInteractions.Play)),
on('pause', handler(MediaInteractions.Pause)), on('pause', handler(MediaInteractions.Pause)),
on('seeked', handler(MediaInteractions.Seeked)), on('seeked', handler(MediaInteractions.Seeked)),
on('volumechange', handler(MediaInteractions.VolumeChange)),
]; ];
return () => { return () => {
handlers.forEach((h) => h()); handlers.forEach((h) => h());
@@ -987,6 +993,7 @@ export function initObservers(
o.mediaInteractionCb, o.mediaInteractionCb,
o.blockClass, o.blockClass,
o.mirror, o.mirror,
o.sampling,
); );
const styleSheetObserver = initStyleSheetObserver( const styleSheetObserver = initStyleSheetObserver(

View File

@@ -1019,6 +1019,12 @@ export class Replayer {
if (d.currentTime) { if (d.currentTime) {
mediaEl.currentTime = d.currentTime; mediaEl.currentTime = d.currentTime;
} }
if (d.volume) {
mediaEl.volume = d.volume;
}
if (d.muted) {
mediaEl.muted = d.muted;
}
if (d.type === MediaInteractions.Pause) { if (d.type === MediaInteractions.Pause) {
mediaEl.pause(); mediaEl.pause();
} }

View File

@@ -192,6 +192,10 @@ export type SamplingStrategy = Partial<{
* number is the throttle threshold of recording scroll * number is the throttle threshold of recording scroll
*/ */
scroll: number; scroll: number;
/**
* number is the throttle threshold of recording media interactions
*/
media: number;
/** /**
* 'all' will record all the input events * 'all' will record all the input events
* 'last' will only record the last input value while input a sequence of chars * 'last' will only record the last input value while input a sequence of chars
@@ -472,12 +476,15 @@ export const enum MediaInteractions {
Play, Play,
Pause, Pause,
Seeked, Seeked,
VolumeChange,
} }
export type mediaInteractionParam = { export type mediaInteractionParam = {
type: MediaInteractions; type: MediaInteractions;
id: number; id: number;
currentTime?: number; currentTime?: number;
volume?: number;
muted?: boolean;
}; };
export type mediaInteractionCallback = (p: mediaInteractionParam) => void; export type mediaInteractionCallback = (p: mediaInteractionParam) => void;