To prevent the webpage from playing sound without permission, most web browsers restrict the autoplay function: Autoplay with sound is blocked unless the user has interacted with the webpage.
This restriction policy is intended to improve the user experience, because autoplay with sound may be against the users' deliberate intention.
When it comes to the Agora Web SDK, audio playback is affected by this policy so long as the stream object in Stream.play
contains an unmuted audio track.
The policy may cause playback issues. This document describes how to get around this restriction for the following scenarios:
The Stream.play("ID")
method reports an error in the callback function when the playback fails due to the autoplay block. We can resume the playback in the failure callback. As the visit number increases, the browser will add the webpage to its autoplay whitelist.
When detecting an autoplay block, instruct the user to click on the webpage to resume the playback:
stream.play("agora_remote"+ stream.getId(), function(err){
if (err && err.status !== "aborted"){
// The playback fails. Guide the user to resume the playback by clicking.
document.querySelector("#agora_remote"+ stream.getId()).onclick=function(){
stream.resume().then(
function (result) {
console.log('Resume succeeds: ' + result);
}).catch(
function (reason) {
console.log('Resume fails: ' + reason);
});
}
}
});
Usually the autoplay policy does not affect the local streams (because we do not play the sound of the local streams), so you only need to deal with the remote streams.
If you prefer dealing with the autoplay block in advance, choose one of the following methods:
Stream.play("ID", { muted: true })
, because autoplay without sound is allowed.If your app requires autoplay without any user interaction, we recommend the first method.
If your app allows user interaction before playing the stream, for example a user needs to click a button to view the host, we recommend the second method.
Play the stream without sound first, and unmute it when the user interacts with the webpage.
Register a global event listener at the beginning of your code:
document.body.addEventListener("touchstart") // Listen for the touch action
Or
document.body.addEventListener("mousedown") // Listen for the click action.
Get the Stream
objects for playback by createStream
or by subscribing to the remote users, and play these objects without sound immediately. Save these objects in an internal list object playingStreamList
in the meantime.
Stream.stop()
Stream.play("ID", { muted: true })
In the event listener registered in step 1, play the Stream
objects in playingStreamList
with sound.
Stream.play("ID", { muted: false })
If the user has interacted with the webpage before playing the stream, autoplay with sound is allowed.This method can work around almost all the autoplay block for the browsers on your PC, but does not apply to iOS Safari or WebView. See the following section for our suggested workaround for iOS Safari and WebView.
iOS Safari or WebView has a stricter autoplay policy. It only allows playback with sound that is triggered by user interaction, and does not remove the autoplay block after a user interaction.
If your app works on iOS Safari or WebView, we recommend handling autoplay in the following way:
Play the streams without sound first: Stream.play("ID", { muted: true })
.
Bind the user interaction event (click or touch) to the HTMLElement
container, which is specified by each Stream.play
method call.
Display a mute icon on the playback interface showing that the stream is muted, and instruct the user to click on (or touch) the interface.
When the user clicks on (or touches) the interface, play the stream with sound again in the event callback and toggle the mute icon.
Stream.stop()
Stream.play("ID", { muted: true })