From eebc08daa181e9995c66459efd2ff65d128984ea Mon Sep 17 00:00:00 2001 From: Jaya Allamsetty <54324652+jallamsetty1@users.noreply.github.com> Date: Mon, 27 Feb 2023 17:44:32 -0500 Subject: [PATCH] fix(AudioTrack): Reattach the track to the audio element on error. Audio playback for a remote participant doesn't happen when the browser fires an error event on the audio element that the audio track is attached to. '[modules/RTC/JitsiRemoteTrack.js] <._containerEventHandler>: error handler was called for a container with attached RemoteTrack' Log an error when that happens and try to re-attach the audio track and execute play on it as a potential fix. --- .../base/media/components/web/AudioTrack.js | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/react/features/base/media/components/web/AudioTrack.js b/react/features/base/media/components/web/AudioTrack.js index 5ac1d5c91..91ab4a2af 100644 --- a/react/features/base/media/components/web/AudioTrack.js +++ b/react/features/base/media/components/web/AudioTrack.js @@ -79,6 +79,7 @@ class AudioTrack extends Component { super(props); // Bind event handlers so they are only bound once for every instance. + this._errorHandler = this._errorHandler.bind(this); this._setRef = this._setRef.bind(this); this._play = this._play.bind(this); } @@ -103,6 +104,8 @@ class AudioTrack extends Component { if (typeof _muted === 'boolean') { this._ref.muted = _muted; } + + this._ref.addEventListener('error', this._errorHandler); } } @@ -115,6 +118,7 @@ class AudioTrack extends Component { */ componentWillUnmount() { this._detachTrack(this.props.audioTrack); + this._ref.removeEventListener('error', this._errorHandler); } /** @@ -202,10 +206,25 @@ class AudioTrack extends Component { } } + _errorHandler: (?Error) => void; + + /** + * Reattaches the audio track to the underlying HTMLAudioElement when an 'error' event is fired. + * + * @param {Error} error - The error event fired on the HTMLAudioElement. + * @returns {void} + */ + _errorHandler(error) { + logger.error(`Error ${error?.message} called on audio track ${this.props.audioTrack?.jitsiTrack}. ` + + 'Attempting to reattach the audio track to the element and execute play on it'); + this._detachTrack(this.props.audioTrack); + this._attachTrack(this.props.audioTrack); + } + _play: ?number => void; /** - * Plays the uderlying HTMLAudioElement. + * Plays the underlying HTMLAudioElement. * * @param {number} retries - The number of previously failed retries. * @returns {void}