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

[Web]: Mux video flickers when played on Safari #951

Closed
1 task done
ssandino opened this issue Nov 27, 2024 · 2 comments · Fixed by #944
Closed
1 task done

[Web]: Mux video flickers when played on Safari #951

ssandino opened this issue Nov 27, 2024 · 2 comments · Fixed by #944
Assignees
Labels
website Issues concerning Website

Comments

@ssandino
Copy link
Member

Describe the bug

In Safari, the poster image flickers briefly before the video starts playing, causing a "not so smooth" transition.
Image

Steps To Reproduce

No response

Expected Behavior

No response

Screenshots?

No response

Desktop Environment (please complete the following information)

- OS:
- Browser:
- Version:

Smartphone Type (please complete the following information)

- Device:
- OS:
- Browser:
- Version:

Additional context

No response

Code of Conduct

  • I've read the Code of Conduct and understand my responsibilities as a member of the Social Income community
@ssandino ssandino added the website Issues concerning Website label Nov 27, 2024
@ssandino
Copy link
Member Author

ssandino commented Nov 27, 2024

The flickering was really bothering me, so I played around with some fixes and found something that worked for me locally. Here’s what I ended up with—could you @mdumond try it out on your end and see if it resolves the issue for you too?


Changes:

1. Added a Dedicated Poster Layer
I added a div with an <img> for the poster. This ensures the poster remains visible until the video is fully ready to play.

const posterRef = useRef<HTMLDivElement>(null);
<div ref={posterRef} className="absolute inset-0 z-0">
    <img
        className="h-full w-full object-cover"
        src="https://image.mux.com/IPdwilTUVkKs2nK8zKZi5eKwbKhpCWxgsYNVxcANeFE/thumbnail.jpg?time=2"
        alt="Video Poster"
    />
</div>

2. Managed Poster Visibility Dynamically
The poster's visibility is controlled using the opacity property. It fades out when the video is ready (canplay event) and fades back in when the video is paused.

useEffect(() => {
    const video = videoElementRef.current;
    if (playing && video) {
        video.addEventListener('canplay', () => {
            if (posterRef.current) {
                posterRef.current.style.opacity = '0';
                posterRef.current.style.transition = 'opacity 0.5s ease';
            }
        });
        video.play();
    } else {
        video?.pause();
        if (posterRef.current) {
            posterRef.current.style.opacity = '1';
        }
    }
}, [playing]);

3. Some Layering for <MuxVideo>
Added z-10 to make sure the video plays above the poster layer.

<MuxVideo
    ref={videoElementRef}
    className="h-full w-full object-cover z-10"
    playbackId="IPdwilTUVkKs2nK8zKZi5eKwbKhpCWxgsYNVxcANeFE"
    startTime={2}
    loop
    muted={muted}
    autoPlay={playing}
    playsInline
    onCanPlay={() => setPlaying(true)}
>

This worked for me—curious to know if it resolves the issue on your end as well or if it causes new problems.

(one issue is now that when we press pause the poster image reappears, which is not optimal, but not really as bad as the white flickering)

@mdumond
Copy link
Contributor

mdumond commented Dec 3, 2024

I'm testing this, for me when I pause the video and start it again, the video stays behind the poster image.

If I revert locally

useEffect(() => {
    const video = videoElementRef.current;
    if (playing && video) {
        video.addEventListener('canplay', () => {
            if (posterRef.current) {
                posterRef.current.style.opacity = '0';
                posterRef.current.style.transition = 'opacity 0.5s ease';
            }
        });
        video.play();
    } else {
        video?.pause();
        if (posterRef.current) {
            posterRef.current.style.opacity = '1';
        }
    }
}, [playing]);

to

useEffect(() => {
    const video = videoElementRef.current;
    if (playing && video) {
        video.addEventListener('canplay', () => {
            if (posterRef.current) {
                posterRef.current.style.opacity = '0';
                posterRef.current.style.transition = 'opacity 0.5s ease';
            }
        });
        video.play();
    } else {
        videoElementRef.current?.pause();
    }
}, [playing]);

the pause behavior does not change, and the flickering at the start is not reverted

@mkue mkue linked a pull request Dec 3, 2024 that will close this issue
@mkue mkue closed this as completed in #944 Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
website Issues concerning Website
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants