From 2dac41e5e5b9f63e13fbfe8bcc4ae705ed2dbb96 Mon Sep 17 00:00:00 2001 From: infinite-persistence <64950861+infinite-persistence@users.noreply.github.com> Date: Wed, 19 May 2021 23:56:54 +0800 Subject: [PATCH] Mute video when autoplay is blocked by browser policy (#6087) ## Issue When opening a video directly in Chrome Incognito, the video should autoplay (since that's the default Lbry setting), but it doesn't due to browser policy https://developers.google.com/web/updates/2017/09/autoplay-policy-changes ## Changes - We don't want to forcefully mute the video when `autoplay=true`; we just want to do it when the browser policy is applied. - Fortunately, there is already an existing code-block for us to check that. ## Test cases - [x] "Autoplay=Off" should not be affected. - [x] After manually unmuting, the next autoplayed video should not be muted (this is "user interacted" opening, so the policy allows autoplay) - [x] If manually muting, the next autoplayed video should retain user's last setting. ## Known issues - I've seen `error` occasionally being undefined in the `catch` block. In those cases, the solution doesn't work. We could remove `if (player.autoplay() && !player.muted())` and simply just try muting it, but for now it's better to ensure `NotAllowedError` is due to unmuted first before applying the fix. - This doesn't work for Firefox as there is an explicit "Allow Autoplay" button in the address bar that user needs to click themselves. Applies to all sites. --- ui/component/viewers/videoViewer/internal/videojs.jsx | 1 + ui/component/viewers/videoViewer/view.jsx | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/ui/component/viewers/videoViewer/internal/videojs.jsx b/ui/component/viewers/videoViewer/internal/videojs.jsx index be0a6bcbf..2f1ed5373 100644 --- a/ui/component/viewers/videoViewer/internal/videojs.jsx +++ b/ui/component/viewers/videoViewer/internal/videojs.jsx @@ -38,6 +38,7 @@ export type Player = { controlBar: { addChild: (string, any) => void, }, + autoplay: (any) => boolean, }; type Props = { diff --git a/ui/component/viewers/videoViewer/view.jsx b/ui/component/viewers/videoViewer/view.jsx index 13a6f7378..4afa0502c 100644 --- a/ui/component/viewers/videoViewer/view.jsx +++ b/ui/component/viewers/videoViewer/view.jsx @@ -221,6 +221,12 @@ function VideoViewer(props: Props) { ); Promise.race([playPromise, timeoutPromise]).catch((error) => { + if (typeof error === 'object' && error.name && error.name === 'NotAllowedError') { + if (player.autoplay() && !player.muted()) { + player.muted(true); + } + } + if (PLAY_TIMEOUT_ERROR) { const retryPlayPromise = player.play(); Promise.race([retryPlayPromise, timeoutPromise]).catch((error) => {