Possible error in playFirstVideo()

kindco

Member
Hello,

Currently, main part of playFirstVideo() method is following:

JavaScript:
if (src) {
    video.src = src;
    video.play().then(function () {
        display.appendChild(video);
        resolve();
    })["catch"](function () {
        //WCS-2375. fixed autoplay in ios safari
        logger.info(LOG_PREFIX, "Autoplay detected! Trying to play a video with a muted sound...");
        video.muted = true;
        video.play().then(function () {
            display.appendChild(video);
            resolve();
        }); //WCS-2375. low power mode suspends video play

        video.onsuspend = function (event) {
            reject();
        };
    });
    return;
}
It works well unless we go into the "catch" block. Here the problem is that video.onsuspend is always called before video plays, i.e. promise is rejected without any chance to be resolved. If we comment reject(); out, everything works well.

We tested this using different OS and browsers, including main target (Mac Safari), with the same result.
 

Max

Administrator
Staff member
Good day.
The playFirstVideo() function is intended to use in Safari browser only. In this browser, onsuspend event is raised only if preloader file cannot be played.
All the other browsers (Chrome and Chromium based, Firefox) do not need to use the trick to autoplay stream.
So we recommend to use this function in Safari only, as is shown in Player example:
Code:
        if (Flashphoner.getMediaProviders()[0] === "WSPlayer") {
            Flashphoner.playFirstSound();
        } else if (Browser.isSafariWebRTC() || Flashphoner.getMediaProviders()[0] === "MSE") {
            Flashphoner.playFirstVideo(remoteVideo, false, PRELOADER_URL).then(function() {
                start();
            }).catch(function () {
                onStopped();
            });
            return;
        }
        start();
 

kindco

Member
Hello @Max ,

We tested this in Safari as well and got the same result.

Maybe the problem is in our specific use case. We are building a React app where live stream is restored automatically if it wasn't properly finished by the host. In this case (when the stream is restored automatically on page load) we are falling into "catch" block with error
DOMException: play() failed because the user didn't interact with the document first.
And is this case onsuspend is called before second play attempt is performed. But if we remove reject() from its handler, all works well: second play() plays the video and the promise resolves.

Everything works also if we set video.muted = true initially, before first play() attempt. In this case we never go into the catch block.

But in general, it seems that the whole "catch" block is still a bit incorrect. It must give as a chance to play muted video one more time, but onsuspend is called before the second play().
 

Max

Administrator
Staff member
Understand.
We raised the ticket WCS-2972 to fix it. But this requires additional testing in Low Power Mode on iOS devices, suspend rejection is for this case.
Also, the problem is not reproduced in Player example tweaked for automatic play restoration (see attach). Please provide us Player example code modification to reproduce the issue for testing purposes using this form (just add the code archive)
 

Attachments

kindco

Member
Hello @Max ,
We are sorry, it seems our problems were because of old OSX version. We updated it recently and now on newest OSX version (10.15.7) everything works well. We will try to find old OSX and test again, just to be sure, but it seems there are no errors here. Sorry again.
 
Top