Playing in iOS/Safari with user interaction not working after server request
See original GitHub issueHi, first of all, thanks for your react-player component. It has helped our team to build different players in our projects but we are running into a big problem that for you may find to be easy to fix but we didn’t find any solution yet:
Current Behavior
We have two projects: https://www.cadena100.es/ and https://www.cope.es/directos/net1
Both of them use ReactPlayer as their’s player core (FilePlayer) but we are unable to trigger a video/audio playing after making a server request for the video data. This request is triggered by a user interaction. This problem only happens in iOS and Safari.
We have the error:
NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
This is related to the autoplay policies but we don’t want to autoplay them, we just need to play it after a user’s interaction on the page that will change the ReactPlayer props after we have the video/audio src that comes from server.
Expected Behavior
I would expect this to just play normally since the click for playing was done in a user interaction on the page.
Example:
import React, { useState } from 'react';
import ReactPlayer from 'react-player';
const TEST_VIDEO_SRC = 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4';
const getMedia = () => new Promise((resolve) => {
setTimeout(() => {
resolve(TEST_VIDEO_SRC);
}, 2000);
});
const Example = () => {
const [url, setUrl] = useState(null);
return (
<section>
<div onClick={() => getMedia().then(setUrl)}>
Play Video
</div>
<ReactPlayer
url={url}
playsinline
playing={!!url}
onError={error => console.log(error)}
/>
</section>
);
};
export default Example;
If I remove the promise and I just execute setUrl it works normally. Do you know what are we doing wrong?
Thanks in advance.
PD: Maybe related: https://github.com/videojs/video.js/issues/4765 https://github.com/videojs/video.js/pull/5822
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (2 by maintainers)
This is too much of an assumption to make on behalf of the user. We don’t know that devs/users will be happy with the media playing anyway if the browser is not allowing it to play. They might be happy to wait for direct user interaction. It also creates a weird dissonance between props and reality (something is playing muted even though
muted
prop isfalse
).You can probably implement this yourself already: store
muted: false
in state, then useronError
to listen for the error, andsetState({ muted: true })
if it happens. You may also have to switchplaying
fromfalse
totrue
, or callgetInternalPlayer().play()
to forceplay()
to be called.Edit: Sorry, I assumed you were suggesting
ReactPlayer
do this. If you just meant that you are going to implement this in your app, then awesome 👍Yep, we will implement a solution like that, thanks for your help.