-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Changes from all commits
f173b56
ab38768
82151ab
11f1eb6
77e6cde
f1a16b9
a8722dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,7 +43,6 @@ export class VideoReplayer { | |
private _attachments: VideoEvent[]; | ||
private _callbacks: Record<string, (args?: any) => unknown>; | ||
private _currentIndex: number | undefined; | ||
private _currentVideo: HTMLVideoElement | undefined; | ||
private _startTimestamp: number; | ||
private _timer = new Timer(); | ||
private _trackList: [ts: number, index: number][]; | ||
|
@@ -196,6 +195,8 @@ export class VideoReplayer { | |
const el = document.createElement('video'); | ||
const sourceEl = document.createElement('source'); | ||
el.style.display = 'none'; | ||
el.style.zIndex = index.toString(); | ||
el.style.position = 'absolute'; | ||
sourceEl.setAttribute('type', 'video/mp4'); | ||
sourceEl.setAttribute('src', `${this._videoApiPrefix}${segmentData.id}/`); | ||
el.setAttribute('muted', ''); | ||
|
@@ -397,29 +398,35 @@ export class VideoReplayer { | |
|
||
/** | ||
* Shows the video -- it is assumed that it is preloaded. Also | ||
* hides the previous video, there should not be a reason we show | ||
* a video and not hide the previous video, otherwise there will | ||
* hides all other videos, otherwise there will | ||
* be multiple video elements stacked on top of each other. | ||
*/ | ||
protected showVideo(nextVideo: HTMLVideoElement | undefined): void { | ||
if (!nextVideo) { | ||
return; | ||
} | ||
|
||
// This is the soon-to-be previous video that needs to be hidden | ||
if (this._currentVideo) { | ||
this._currentVideo.style.display = 'none'; | ||
// 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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
// On safari, some clips have a ~1 second gap in the beginning so we also need to show the previous video to hide this gap | ||
if (index === (this._currentIndex || 0) - 1) { | ||
if (videoElem.duration) { | ||
// we need to set the previous video to the end so that it's shown in case the next video has a gap at the beginning | ||
// setting it to the end of the video causes the 'ended' bug in Chrome so we set it to 1 ms before the video ends | ||
this.setVideoTime(videoElem, videoElem.duration * 1000 - 1); | ||
} | ||
videoElem.style.display = 'block'; | ||
} | ||
// hides all videos because videos have a different z-index depending on their index | ||
else { | ||
videoElem.style.display = 'none'; | ||
// resets the other videos to the beginning if it's ended so it starts from the beginning on restart | ||
if (videoElem.ended) { | ||
this.setVideoTime(videoElem, 0); | ||
} | ||
} | ||
} | ||
|
||
nextVideo.style.display = 'block'; | ||
|
||
// Update current video so that we can hide it when showing the | ||
// next video | ||
this._currentVideo = nextVideo; | ||
} | ||
|
||
protected async playVideo(video: HTMLVideoElement | undefined): Promise<void> { | ||
|
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?