Skip to content

Commit 0f59d47

Browse files
fix(replays): sync replay timer with shown duration
1 parent f8e8949 commit 0f59d47

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

static/app/components/replays/replayContext.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ function ProviderNonMemo({
495495
setVideoBuffering(buffering);
496496
},
497497
clipWindow,
498+
duration: durationMs,
498499
});
499500
// `.current` is marked as readonly, but it's safe to set the value from
500501
// inside a `useEffect` hook.
@@ -521,6 +522,7 @@ function ProviderNonMemo({
521522
startTimestampMs,
522523
startTimeOffsetMs,
523524
clipWindow,
525+
durationMs,
524526
]
525527
);
526528

static/app/components/replays/videoReplayer.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface OffsetOptions {
1414
}
1515

1616
interface VideoReplayerOptions {
17+
duration: number;
1718
onBuffer: (isBuffering: boolean) => void;
1819
onFinished: () => void;
1920
onLoaded: (event: any) => void;
@@ -56,6 +57,7 @@ export class VideoReplayer {
5657
private _videos: Map<any, HTMLVideoElement>;
5758
private _videoApiPrefix: string;
5859
private _clipDuration: number | undefined;
60+
private _duration: number;
5961
public config: VideoReplayerConfig = {
6062
skipInactive: false,
6163
speed: 1.0,
@@ -73,6 +75,7 @@ export class VideoReplayer {
7375
onFinished,
7476
onLoaded,
7577
clipWindow,
78+
duration,
7679
}: VideoReplayerOptions
7780
) {
7881
this._attachments = attachments;
@@ -86,6 +89,7 @@ export class VideoReplayer {
8689
};
8790
this._videos = new Map<any, HTMLVideoElement>();
8891
this._clipDuration = undefined;
92+
this._duration = duration;
8993

9094
this.wrapper = document.createElement('div');
9195
if (root) {
@@ -297,7 +301,12 @@ export class VideoReplayer {
297301

298302
// No more segments
299303
if (nextIndex >= this._attachments.length) {
300-
this.stopReplay();
304+
// If we're at the end of a segment, but there's a gap
305+
// at the end, force the replay to play until the end duration
306+
// rather than stopping right away.
307+
this._timer.addNotificationAtTime(this._duration, () => {
308+
this.stopReplay();
309+
});
301310
return;
302311
}
303312

@@ -598,8 +607,13 @@ export class VideoReplayer {
598607
const loadedSegmentIndex = await this.loadSegmentAtTime(videoOffsetMs);
599608

600609
if (loadedSegmentIndex === undefined) {
601-
// TODO: this shouldn't happen, loadSegment should load the previous
602-
// segment until it's time to start the next segment
610+
// If we end up here, we seeked into a gap
611+
// at the end of the replay.
612+
// This tells the timer to stop at the specified duration
613+
// and prevents the timer from running infinitely.
614+
this._timer.addNotificationAtTime(this._duration, () => {
615+
this.stopReplay();
616+
});
603617
return Promise.resolve();
604618
}
605619

0 commit comments

Comments
 (0)