Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(replay): Fix video flickering on Safari #82769

Merged
merged 7 commits into from
Jan 3, 2025
Merged

Conversation

c298lee
Copy link
Member

@c298lee c298lee commented Dec 31, 2024

To prevent flickering in Safari, we set the z-index of the clip depending on its index. We hide all videos except the next video and the video before that. This "fixes" the gap in the video by showing the previous video when the gap is happening.

Example replay: https://brustolin.sentry.io/replays/c817d3d7daac4440a2788fd0cbf521b0

Before:
Playthough with gaps

Screen.Recording.2025-01-02.at.5.57.26.PM.mov

Clicking to gap
image

After:
Playthrough is smooth

Screen.Recording.2025-01-02.at.5.58.46.PM.mov

No empty video at same timestamp
image

Fixes #82771

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Dec 31, 2024
Copy link

codecov bot commented Jan 2, 2025

Bundle Report

Changes will increase total bundle size by 5.49kB (0.02%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
app-webpack-bundle-array-push 32.18MB 5.49kB (0.02%) ⬆️

@c298lee c298lee marked this pull request as ready for review January 2, 2025 22:47
@c298lee c298lee requested a review from a team as a code owner January 2, 2025 22:47
@@ -3,6 +3,7 @@ import {css, type Theme} from '@emotion/react';
// Base styles, to make the Replayer instance work
export const baseReplayerCss = css`
.replayer-wrapper {
z-index: 1000000;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replays should be max 60 minutes and each clip is ~5 seconds so the z-index of the clips should never reach this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a comment about why/how the z-index is needed?

// resets the soon-to-be previous video to the beginning if it's ended so it starts from the beginning on restart
if (this._currentVideo.ended) {
this.setVideoTime(this._currentVideo, 0);
for (const video of this._videos) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about destructuring to get named vars:

Suggested change
for (const video of this._videos) {
for (const [index, videoElem] of this._videos) {

and then video[0] would be index and video[1] would be videoElem now

@c298lee c298lee merged commit 9ce7ff2 into master Jan 3, 2025
42 checks passed
@c298lee c298lee deleted the cl/safari-flicker branch January 3, 2025 21:40
Copy link
Member

@billyvg billyvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work as expected if we are in say segment 1 and we seek to near the end of the replay (e.g. segment 20), will it show end of video 0 or 19?

@@ -3,6 +3,7 @@ import {css, type Theme} from '@emotion/react';
// Base styles, to make the Replayer instance work
export const baseReplayerCss = css`
.replayer-wrapper {
z-index: 1000000;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a comment about why/how the z-index is needed?

// resets the soon-to-be previous video to the beginning if it's ended so it starts from the beginning on restart
if (this._currentVideo.ended) {
this.setVideoTime(this._currentVideo, 0);
for (const [index, videoElem] of this._videos) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to loop through all videos? Shouldn't there only be 2 videos that are relevant: the next video to show and the current/soon-to-be-previous video?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We loop through them all since you can click on a timestamp much earlier or later in the video. It's harder to keep track of which videos need to be hidden in that case, especially if someone decided to click around different timestamps of the video. For instance, if someone's on video 5 and clicking on a timestamp that would show video 10, then we would need to hide video 4 and 5 and show video 9 and 10.
I decided to just loop through them all since adding that logic might be confusing, and when testing it with looping through everything, it didn't seem to add any visible lag or weirdness.

@c298lee
Copy link
Member Author

c298lee commented Jan 6, 2025

Does this work as expected if we are in say segment 1 and we seek to near the end of the replay (e.g. segment 20), will it show end of video 0 or 19?

It works as expected! It shows the end of video 19 in that scenario

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Mobile Replay]: Player flickering on Safari
3 participants