Skip to content

Commit

Permalink
Revert "Full overhawl of video & audio playback to make it more compl…
Browse files Browse the repository at this point in the history
…ete (rrweb-io#1432)"

This reverts commit 123a81e.
  • Loading branch information
billyvg committed Apr 26, 2024
1 parent e26708f commit c6bc3c7
Show file tree
Hide file tree
Showing 28 changed files with 59 additions and 1,886 deletions.
5 changes: 0 additions & 5 deletions .changeset/cool-grapes-hug.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/dirty-rules-dress.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/mighty-ads-worry.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/silver-pots-sit.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/smart-geckos-cover.md

This file was deleted.

2 changes: 0 additions & 2 deletions packages/rrdom/src/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ function diffAfterUpdatingChildren(
oldMediaElement.currentTime = newMediaRRElement.currentTime;
if (newMediaRRElement.playbackRate !== undefined)
oldMediaElement.playbackRate = newMediaRRElement.playbackRate;
if (newMediaRRElement.loop !== undefined)
oldMediaElement.loop = newMediaRRElement.loop;
break;
}
case 'CANVAS': {
Expand Down
1 change: 0 additions & 1 deletion packages/rrdom/src/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,6 @@ export function BaseRRMediaElementImpl<
public paused?: boolean;
public muted?: boolean;
public playbackRate?: number;
public loop?: boolean;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
attachShadow(_init: ShadowRootInit): IRRElement {
throw new Error(
Expand Down
2 changes: 0 additions & 2 deletions packages/rrdom/test/diff.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,13 @@ describe('diff algorithm for rrdom', () => {
rrMedia.muted = true;
rrMedia.paused = false;
rrMedia.playbackRate = 0.5;
rrMedia.loop = false;

diff(element, rrMedia, replayer);
expect(element.volume).toEqual(0.5);
expect(element.currentTime).toEqual(100);
expect(element.muted).toEqual(true);
expect(element.paused).toEqual(false);
expect(element.playbackRate).toEqual(0.5);
expect(element.loop).toEqual(false);

rrMedia.paused = true;
diff(element, rrMedia, replayer);
Expand Down
1 change: 0 additions & 1 deletion packages/rrdom/test/document.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,6 @@ describe('Basic RRDocument implementation', () => {
expect(node.paused).toBeUndefined();
expect(node.muted).toBeUndefined();
expect(node.playbackRate).toBeUndefined();
expect(node.loop).toBeUndefined();
expect(node.play).toBeDefined();
expect(node.pause).toBeDefined();
expect(node.toString()).toEqual('VIDEO ');
Expand Down
11 changes: 0 additions & 11 deletions packages/rrweb-snapshot/src/rebuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,17 +348,6 @@ 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;
}
}

Expand Down
10 changes: 2 additions & 8 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
KeepIframeSrcFn,
ICanvas,
serializedElementNodeWithId,
type mediaAttributes,
} from './types';
import {
Mirror,
Expand Down Expand Up @@ -762,15 +761,10 @@ function serializeElementNode(
}
// media elements
if (tagName === 'audio' || tagName === 'video') {
const mediaAttributes = attributes as mediaAttributes;
mediaAttributes.rr_mediaState = (n as HTMLMediaElement).paused
attributes.rr_mediaState = (n as HTMLMediaElement).paused
? 'paused'
: 'played';
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;
attributes.rr_mediaCurrentTime = (n as HTMLMediaElement).currentTime;
}
// Scroll
if (!newlyAddedElement) {
Expand Down
21 changes: 0 additions & 21 deletions packages/rrweb-snapshot/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,27 +82,6 @@ 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;
Expand Down
3 changes: 1 addition & 2 deletions packages/rrweb/src/record/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ function initMediaInteractionObserver({
) {
return;
}
const { currentTime, volume, muted, playbackRate, loop } =
const { currentTime, volume, muted, playbackRate } =
target as HTMLMediaElement;
mediaInteractionCb({
type,
Expand All @@ -1051,7 +1051,6 @@ function initMediaInteractionObserver({
volume,
muted,
playbackRate,
loop,
});
}),
sampling.media || 500,
Expand Down
75 changes: 31 additions & 44 deletions packages/rrweb/src/replay/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
ReplayerEvents,
Handler,
Emitter,
MediaInteractions,
metaEvent,
mutationData,
scrollData,
Expand Down Expand Up @@ -80,7 +81,6 @@ import getInjectStyleRules from './styles/inject-style';
import './styles/style.css';
import canvasMutation from './canvas';
import { deserializeArg } from './canvas/deserialize-args';
import { MediaManager } from './media';

const SKIP_TIME_INTERVAL = 5 * 1000;

Expand Down Expand Up @@ -142,9 +142,6 @@ export class Replayer {
// Used to track StyleSheetObjects adopted on multiple document hosts.
private styleMirror: StyleSheetMirror = new StyleSheetMirror();

// Used to track video & audio elements, and keep them in sync with general playback.
private mediaManager: MediaManager;

private firstFullSnapshot: eventWithTime | true | null = null;

private newDocumentQueue: addedNodeMutation[] = [];
Expand Down Expand Up @@ -327,7 +324,6 @@ export class Replayer {
this.firstFullSnapshot = null;
this.mirror.reset();
this.styleMirror.reset();
this.mediaManager.reset();
});

const timer = new Timer([], {
Expand Down Expand Up @@ -370,13 +366,6 @@ export class Replayer {
speed: state,
});
});
this.mediaManager = new MediaManager({
warn: this.warn.bind(this),
service: this.service,
speedService: this.speedService,
emitter: this.emitter,
getCurrentTime: this.getCurrentTime.bind(this),
});

// rebuild first full snapshot as the poster of the player
// maybe we can cache it for performance optimization
Expand Down Expand Up @@ -475,16 +464,10 @@ export class Replayer {
};
}

/**
* Get the actual time offset the player is at now compared to the first event.
*/
public getCurrentTime(): number {
return this.timer.timeOffset + this.getTimeOffset();
}

/**
* Get the time offset the player is at now compared to the first event, but without regard for the timer.
*/
public getTimeOffset(): number {
const { baselineTime, events } = this.service.state.context;
return baselineTime - events[0].timestamp;
Expand Down Expand Up @@ -544,9 +527,6 @@ export class Replayer {
*/
public destroy() {
this.pause();
this.mirror.reset();
this.styleMirror.reset();
this.mediaManager.reset();
this.config.root.removeChild(this.wrapper);
this.emitter.emit(ReplayerEvents.Destroy);
}
Expand Down Expand Up @@ -687,10 +667,9 @@ export class Replayer {
// Timer (requestAnimationFrame) can be faster than setTimeout(..., 1)
this.firstFullSnapshot = true;
}
this.mediaManager.reset();
this.styleMirror.reset();
this.rebuildFullSnapshot(event, isSync);
this.iframe.contentWindow?.scrollTo(event.data.initialOffset);
this.styleMirror.reset();
};
break;
case EventType.IncrementalSnapshot:
Expand Down Expand Up @@ -799,14 +778,6 @@ export class Replayer {
const collected: AppendedIframe[] = [];
const afterAppend = (builtNode: Node, id: number) => {
this.collectIframeAndAttachDocument(collected, builtNode);
if (this.mediaManager.isSupportedMediaElement(builtNode)) {
const { events } = this.service.state.context;
this.mediaManager.addMediaElements(
builtNode,
event.timestamp - events[0].timestamp,
this.mirror,
);
}
for (const plugin of this.config.plugins || []) {
if (plugin.onBuild)
plugin.onBuild(builtNode, {
Expand Down Expand Up @@ -1290,14 +1261,35 @@ export class Replayer {
return this.debugNodeNotFound(d, d.id);
}
const mediaEl = target as HTMLMediaElement | RRMediaElement;
const { events } = this.service.state.context;

this.mediaManager.mediaMutation({
target: mediaEl,
timeOffset: e.timestamp - events[0].timestamp,
mutation: d,
});

try {
if (d.currentTime !== undefined) {
mediaEl.currentTime = d.currentTime;
}
if (d.volume !== undefined) {
mediaEl.volume = d.volume;
}
if (d.muted !== undefined) {
mediaEl.muted = d.muted;
}
if (d.type === MediaInteractions.Pause) {
mediaEl.pause();
}
if (d.type === MediaInteractions.Play) {
// remove listener for 'canplay' event because play() is async and returns a promise
// i.e. media will evntualy start to play when data is loaded
// 'canplay' event fires even when currentTime attribute changes which may lead to
// unexpeted behavior
void mediaEl.play();
}
if (d.type === MediaInteractions.RateChange) {
mediaEl.playbackRate = d.playbackRate;
}
} catch (error) {
this.warn(
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions
`Failed to replay media interactions: ${error.message || error}`,
);
}
break;
}
case IncrementalSource.StyleSheetRule:
Expand Down Expand Up @@ -1374,11 +1366,6 @@ export class Replayer {
}
}

/**
* Apply the mutation to the virtual dom or the real dom.
* @param d - The mutation data.
* @param isSync - Whether the mutation should be applied synchronously (while fast-forwarding).
*/
private applyMutation(d: mutationData, isSync: boolean) {
// Only apply virtual dom optimization if the fast-forward process has node mutation. Because the cost of creating a virtual dom tree and executing the diff algorithm is usually higher than directly applying other kind of events.
if (this.config.useVirtualDom && !this.usingVirtualDom && isSync) {
Expand Down
Loading

0 comments on commit c6bc3c7

Please sign in to comment.