feat(AudioTrack): retries for play()
This commit is contained in:
parent
689bb3f226
commit
574994607c
|
@ -696,6 +696,36 @@ export function createStartSilentEvent() {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event which indicates that HTMLAudioElement.play has failed.
|
||||
*
|
||||
* @param {sting} elementID - The ID of the HTMLAudioElement.
|
||||
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
|
||||
*/
|
||||
export function createAudioPlayErrorEvent(elementID) {
|
||||
return {
|
||||
action: 'audio.play.error',
|
||||
attributes: {
|
||||
elementID
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event which indicates that HTMLAudioElement.play has succeded after a prior failure.
|
||||
*
|
||||
* @param {sting} elementID - The ID of the HTMLAudioElement.
|
||||
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
|
||||
*/
|
||||
export function createAudioPlaySuccessEvent(elementID) {
|
||||
return {
|
||||
action: 'audio.play.success',
|
||||
attributes: {
|
||||
elementID
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event which indicates the "start muted" configuration.
|
||||
*
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { createAudioPlayErrorEvent, createAudioPlaySuccessEvent, sendAnalytics } from '../../../../analytics';
|
||||
import logger from '../../logger';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link AudioTrack}.
|
||||
*/
|
||||
|
@ -50,6 +53,11 @@ export default class AudioTrack extends Component<Props> {
|
|||
*/
|
||||
_ref: ?HTMLAudioElement;
|
||||
|
||||
/**
|
||||
* The current timeout ID for play() retries.
|
||||
*/
|
||||
_playTimeout: ?TimeoutID;
|
||||
|
||||
/**
|
||||
* Default values for {@code AudioTrack} component's properties.
|
||||
*
|
||||
|
@ -72,6 +80,7 @@ export default class AudioTrack extends Component<Props> {
|
|||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
this._setRef = this._setRef.bind(this);
|
||||
this._play = this._play.bind(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,14 +94,7 @@ export default class AudioTrack extends Component<Props> {
|
|||
this._attachTrack(this.props.audioTrack);
|
||||
|
||||
if (this._ref) {
|
||||
const { autoPlay, muted, volume } = this.props;
|
||||
|
||||
if (autoPlay) {
|
||||
// Ensure the audio gets play() called on it. This may be necessary in the
|
||||
// case where the local video container was moved and re-attached, in which
|
||||
// case the audio may not autoplay.
|
||||
this._ref.play();
|
||||
}
|
||||
const { muted, volume } = this.props;
|
||||
|
||||
if (typeof volume === 'number') {
|
||||
this._ref.volume = volume;
|
||||
|
@ -181,6 +183,7 @@ export default class AudioTrack extends Component<Props> {
|
|||
}
|
||||
|
||||
track.jitsiTrack.attach(this._ref);
|
||||
this._play();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,10 +196,58 @@ export default class AudioTrack extends Component<Props> {
|
|||
*/
|
||||
_detachTrack(track) {
|
||||
if (this._ref && track && track.jitsiTrack) {
|
||||
clearTimeout(this._playTimeout);
|
||||
this._playTimeout = undefined;
|
||||
track.jitsiTrack.detach(this._ref);
|
||||
}
|
||||
}
|
||||
|
||||
_play: ?number => void;
|
||||
|
||||
/**
|
||||
* Plays the uderlying HTMLAudioElement.
|
||||
*
|
||||
* @param {number} retries - The number of previously failed retries.
|
||||
* @returns {void}
|
||||
*/
|
||||
_play(retries = 0) {
|
||||
if (!this._ref) {
|
||||
// nothing to play.
|
||||
|
||||
return;
|
||||
}
|
||||
const { autoPlay, id } = this.props;
|
||||
|
||||
if (autoPlay) {
|
||||
// Ensure the audio gets play() called on it. This may be necessary in the
|
||||
// case where the local video container was moved and re-attached, in which
|
||||
// case the audio may not autoplay.
|
||||
this._ref.play()
|
||||
.then(() => {
|
||||
if (retries !== 0) {
|
||||
// success after some failures
|
||||
this._playTimeout = undefined;
|
||||
sendAnalytics(createAudioPlaySuccessEvent(id));
|
||||
logger.info(`Successfully played audio track! retries: ${retries}`);
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
logger.error(`Failed to play audio track! retry: ${retries} ; Error: ${e}`);
|
||||
|
||||
if (retries < 3) {
|
||||
this._playTimeout = setTimeout(() => this._play(retries + 1), 1000);
|
||||
|
||||
if (retries === 0) {
|
||||
// send only 1 error event.
|
||||
sendAnalytics(createAudioPlayErrorEvent(id));
|
||||
}
|
||||
} else {
|
||||
this._playTimeout = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_setRef: (?HTMLAudioElement) => void;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue