X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fassets%2Fplayer%2Fp2p-media-loader%2Fhls-plugin.ts;h=672a85d0b0525bfd1d54bf9ed0982d8ca81f6610;hb=87da0a30ab197985917d8457e8388adc46cec10f;hp=9e2ac1aa49b3f48d0df87571a6c5dbf3c9acf2dc;hpb=512decf37ee6d36d0f16bda0f9bec6bf37d132b3;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/assets/player/p2p-media-loader/hls-plugin.ts b/client/src/assets/player/p2p-media-loader/hls-plugin.ts index 9e2ac1aa4..672a85d0b 100644 --- a/client/src/assets/player/p2p-media-loader/hls-plugin.ts +++ b/client/src/assets/player/p2p-media-loader/hls-plugin.ts @@ -13,7 +13,7 @@ type Metadata = { levels: Hlsjs.Level[] } -type CustomAudioTrack = AudioTrack & { name?: string, lang?: string } +type CustomAudioTrack = Hlsjs.HlsAudioTrack & { name?: string, lang?: string } const registerSourceHandler = function (vjs: typeof videojs) { if (!Hlsjs.isSupported()) { @@ -102,9 +102,8 @@ class Html5Hlsjs { private dvrDuration: number = null private edgeMargin: number = null - private handlers: { [ id in 'play' | 'addtrack' | 'playing' | 'textTracksChange' | 'audioTracksChange' ]: EventListener } = { + private handlers: { [ id in 'play' | 'playing' | 'textTracksChange' | 'audioTracksChange' ]: EventListener } = { play: null, - addtrack: null, playing: null, textTracksChange: null, audioTracksChange: null @@ -124,8 +123,11 @@ class Html5Hlsjs { this.videoElement.addEventListener('error', event => { let errorTxt: string - const mediaError = (event.currentTarget as HTMLVideoElement).error + const mediaError = ((event.currentTarget || event.target) as HTMLVideoElement).error + if (!mediaError) return + + console.log(mediaError) switch (mediaError.code) { case mediaError.MEDIA_ERR_ABORTED: errorTxt = 'You aborted the video playback' @@ -174,14 +176,11 @@ class Html5Hlsjs { // See comment for `initialize` method. dispose () { this.videoElement.removeEventListener('play', this.handlers.play) - this.videoElement.textTracks.removeEventListener('addtrack', this.handlers.addtrack) this.videoElement.removeEventListener('playing', this.handlers.playing) this.player.textTracks().removeEventListener('change', this.handlers.textTracksChange) this.uiTextTrackHandled = false - this.player.audioTracks().removeEventListener('change', this.handlers.audioTracksChange) - this.hls.destroy() } @@ -228,12 +227,34 @@ class Html5Hlsjs { if (this.errorCounts[ Hlsjs.ErrorTypes.MEDIA_ERROR ] > 2) { console.info('bubbling media error up to VIDEOJS') + this.hls.destroy() this.tech.error = () => error this.tech.trigger('error') return } } + private _handleNetworkError (error: any) { + if (this.errorCounts[ Hlsjs.ErrorTypes.NETWORK_ERROR] <= 5) { + console.info('trying to recover network error') + + // Wait 1 second and retry + setTimeout(() => this.hls.startLoad(), 1000) + + // Reset error count on success + this.hls.once(Hlsjs.Events.FRAG_LOADED, () => { + this.errorCounts[ Hlsjs.ErrorTypes.NETWORK_ERROR] = 0 + }) + + return + } + + console.info('bubbling network error up to VIDEOJS') + this.hls.destroy() + this.tech.error = () => error + this.tech.trigger('error') + } + private _onError (_event: any, data: Hlsjs.errorData) { const error: { message: string, code?: number } = { message: `HLS.js error: ${data.type} - fatal: ${data.fatal} - ${data.details}` @@ -244,30 +265,19 @@ class Html5Hlsjs { if (this.errorCounts[ data.type ]) this.errorCounts[ data.type ] += 1 else this.errorCounts[ data.type ] = 1 - // Implement simple error handling based on hls.js documentation - // https://github.com/dailymotion/hls.js/blob/master/API.md#fifth-step-error-handling - if (data.fatal) { - switch (data.type) { - case Hlsjs.ErrorTypes.NETWORK_ERROR: - console.info('bubbling network error up to VIDEOJS') - error.code = 2 - this.tech.error = () => error as any - this.tech.trigger('error') - break - - case Hlsjs.ErrorTypes.MEDIA_ERROR: - error.code = 3 - this._handleMediaError(error) - break - - default: - // cannot recover - this.hls.destroy() - console.info('bubbling error up to VIDEOJS') - this.tech.error = () => error as any - this.tech.trigger('error') - break - } + if (!data.fatal) return + + if (data.type === Hlsjs.ErrorTypes.NETWORK_ERROR) { + error.code = 2 + this._handleNetworkError(error) + } else if (data.type === Hlsjs.ErrorTypes.MEDIA_ERROR && data.details !== 'manifestIncompatibleCodecsError') { + error.code = 3 + this._handleMediaError(error) + } else { + this.hls.destroy() + console.info('bubbling error up to VIDEOJS') + this.tech.error = () => error as any + this.tech.trigger('error') } } @@ -610,9 +620,6 @@ class Html5Hlsjs { this.hls.attachMedia(this.videoElement) - this.handlers.addtrack = this._updateTextTrackList.bind(this) - this.videoElement.textTracks.addEventListener('addtrack', this.handlers.addtrack) - this.hls.loadSource(this.source.src) }