Yet another workaround for autoplay issues
This commit is contained in:
parent
90cbb8b597
commit
39cf33b194
@ -64,7 +64,14 @@ export default class KurentoAudioBridge extends BaseAudioBridge {
|
||||
audioTag.pause();
|
||||
audioTag.srcObject = stream;
|
||||
audioTag.muted = false;
|
||||
audioTag.play();
|
||||
audioTag.play().catch((e) => {
|
||||
const tagFailedEvent = new CustomEvent('mediaTagPlayFailed', { detail: { mediaTag: audioTag } });
|
||||
window.dispatchEvent(tagFailedEvent);
|
||||
logger.warn({
|
||||
logCode: 'sfuaudiobridge_play_error',
|
||||
extraInfo: { error: e },
|
||||
}, 'Could not play audio tag, emit mediaTagPlayFailed event');
|
||||
});
|
||||
}
|
||||
resolve(this.callback({ status: this.baseCallStates.started }));
|
||||
};
|
||||
|
@ -21,6 +21,56 @@ export default class Media extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.refContainer = React.createRef();
|
||||
|
||||
this.failedTags = [];
|
||||
this.listeningToTagPlayFailed = false;
|
||||
this.monitorMediaTagPlayFailures();
|
||||
}
|
||||
|
||||
monitorMediaTagPlayFailures() {
|
||||
const handleFailTagEvent = (e) => {
|
||||
e.stopPropagation();
|
||||
this.failedTags.push(e.detail.mediaTag);
|
||||
|
||||
if (!this.listeningToTagPlayFailed) {
|
||||
this.listeningToTagPlayFailed = true;
|
||||
// Monitor user action events so we can play and flush all the failed tags
|
||||
// in the queue when the user performs one of them
|
||||
window.addEventListener('click', flushFailedTags);
|
||||
window.addEventListener('auxclick', flushFailedTags);
|
||||
window.addEventListener('keydown', flushFailedTags);
|
||||
window.addEventListener('touchstart', flushFailedTags);
|
||||
}
|
||||
}
|
||||
|
||||
const flushFailedTags = () => {
|
||||
window.removeEventListener('click', flushFailedTags);
|
||||
window.removeEventListener('auxclick', flushFailedTags);
|
||||
window.removeEventListener('keydown', flushFailedTags);
|
||||
window.removeEventListener('touchstart', flushFailedTags);
|
||||
|
||||
while (this.failedTags.length) {
|
||||
const mediaTag = this.failedTags.shift();
|
||||
if (mediaTag) {
|
||||
mediaTag.play().catch(e => {
|
||||
// Ignore the error for now.
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.listeningToTagPlayFailed = false;
|
||||
}
|
||||
|
||||
// Monitor tag play failure events, probably due to autoplay. The callback
|
||||
// puts the failed tags in a queue which will be flushed on a user action
|
||||
// by the listeners created @handleFailTagEvent. Once the queue is flushed, all
|
||||
// user action listeners are removed since the autoplay restriction should be over.
|
||||
// Every media tag in the app should have a then/catch handler and emit
|
||||
// this event accordingly so we can try to circumvent autoplay without putting
|
||||
// a UI block/prompt.
|
||||
// If a tag fail to play again for some odd reason, the listeners will be
|
||||
// reattached (see this.listeningToTagPlayFailed) and flushFailedTags runs again
|
||||
window.addEventListener("mediaTagPlayFailed", handleFailTagEvent);
|
||||
}
|
||||
|
||||
componentWillUpdate() {
|
||||
|
@ -58,16 +58,14 @@ class VideoListItem extends Component {
|
||||
componentDidUpdate() {
|
||||
const playElement = (elem) => {
|
||||
if (elem.paused) {
|
||||
const p = elem.play();
|
||||
if (p && (typeof Promise !== 'undefined') && (p instanceof Promise)) {
|
||||
// Catch exception when playing video
|
||||
p.catch((e) => {
|
||||
logger.warn({
|
||||
logCode: 'videolistitem_component_play_error',
|
||||
extraInfo: { error: e },
|
||||
}, 'Could not play video');
|
||||
});
|
||||
}
|
||||
elem.play().catch((error) => {
|
||||
const tagFailedEvent = new CustomEvent('mediaTagPlayFailed', { detail: { mediaTag: elem } });
|
||||
window.dispatchEvent(tagFailedEvent);
|
||||
logger.warn({
|
||||
logCode: 'videolistitem_component_play_error',
|
||||
extraInfo: { error },
|
||||
}, 'Could not play video tag, emit mediaTagPlayFailed event');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -325,11 +325,20 @@ function WebRtcPeer(mode, options, callback) {
|
||||
const MAX_RETRIES = 5;
|
||||
let attempt = 0;
|
||||
const playVideo = () => {
|
||||
if (!played && attempt < MAX_RETRIES) {
|
||||
remoteVideo.play().catch(e => {
|
||||
attempt++;
|
||||
playVideo(remoteVideo);
|
||||
}).then(() => { remoteVideo.muted = false; played = true; attempt = 0;});
|
||||
if (!played) {
|
||||
if (attempt < MAX_RETRIES) {
|
||||
remoteVideo.play()
|
||||
.then(() => { remoteVideo.muted = false; played = true; attempt = 0;})
|
||||
.catch(e => {
|
||||
attempt++;
|
||||
setTimeout(() => {
|
||||
playVideo(remoteVideo);
|
||||
}, 500);
|
||||
});
|
||||
} else {
|
||||
const tagFailedEvent = new CustomEvent('mediaTagPlayFailed', { detail: { mediaTag: remoteVideo } });
|
||||
window.dispatchEvent(tagFailedEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user