UNPKG

npaw-plugin-adapters

Version:
530 lines (438 loc) 14.8 kB
export default class TritonAdapter { checkExistsPlayer() { return typeof this.player !== 'undefined'; } getVersion() { return '7.0.1-triton-jsclass'; } getPlayhead() { if (this.mediaElement && this.mediaElement.currentTime !== undefined) { return this.mediaElement.currentTime; } return 0; } getDroppedFrames() { return null; } getDuration() { if (this.mediaElement && this.mediaElement.duration !== undefined) { const duration = this.mediaElement.duration; if (!isNaN(duration) && duration !== Infinity) { return duration; } } return null; } getBitrate() { const audioNode = this.player?.MediaElement?.audioNode; if (audioNode && typeof audioNode.webkitAudioDecodedByteCount !== 'undefined') { const currentBytes = audioNode.webkitAudioDecodedByteCount; if (this._lastWebkitAudioBytes !== undefined && currentBytes > this._lastWebkitAudioBytes) { const deltaBytes = currentBytes - this._lastWebkitAudioBytes; const pingTime = this.getPlugin()?.fastDataTransform?.response?.pingTime || 5; const bitrate = Math.round((deltaBytes / pingTime) * 8); this._lastWebkitAudioBytes = currentBytes; return bitrate > 0 ? bitrate : null; } this._lastWebkitAudioBytes = currentBytes; } return null; } getThroughput() { return null; } getRendition() { return null; } getIsLive() { return this.isLive || false; } getResource() { if (this.mediaElement) { return this.mediaElement.currentSrc || this.mediaElement.src; } return undefined; } getPlayrate() { if (this.mediaElement && this.mediaElement.playbackRate !== undefined) { return this.mediaElement.playbackRate; } return 1; } getPlayerName() { return 'Triton Web Player'; } getPlayerVersion() { return '2.9'; } getTitle() { return this._currentTrackTitle || null; } getTitle2() { return this._currentArtist || null; } getLatency() { return null; } _bufferBeginListener() { if (this.flags.isJoined && !this.flags.isPaused) { if (this.isLive || !this.isSeeking) { this._adapterIsBuffering = true; this.fireBufferBegin({}, false, '_bufferBeginListener'); } } } _bufferEndListener() { if (this.flags.isBuffering || this._adapterIsBuffering) { this._adapterIsBuffering = false; this.fireBufferEnd({}, '_bufferEndListener'); } } _joinListener() { if (!this.flags.isJoined) { this.fireJoin({}, '_joinListener'); } } _resumeListener() { if (this.flags.isPaused) { this.fireResume({}, '_resumeListener'); } } _stopListener() { if (this._suppressNextSdkStop) { this._suppressNextSdkStop = false; return; } this.fireStop({}, '_stopListener'); } _pauseListener() { this.firePause({}, '_pauseListener'); } _errorListener(ev) { if (this._hasErrorFired) { return; } const code = ev.data?.code || ev.code || 'UNKNOWN_ERROR'; const msg = ev.data?.message || ev.message || 'Playback error occurred'; this._hasErrorFired = true; this.fireFatalError(code, msg, undefined, undefined, '_errorListener'); this.fireStop({}, '_errorListener'); } _isNewContent(params) { if (!this._currentPlayParams) return true; if (params.station || params.mount) { const newId = params.station || params.mount; const oldId = this._currentPlayParams.station || this._currentPlayParams.mount; return newId !== oldId; } if (params.file) { return params.file !== this._currentPlayParams.file; } return true; } _cleanupMediaElement() { if (this.mediaElement) { if (this._seekingHandler) { this.mediaElement.removeEventListener('seeking', this._seekingHandler); } if (this._playingHandler) { this.mediaElement.removeEventListener('playing', this._playingHandler); } if (this._html5ErrorHandler) { this.mediaElement.removeEventListener('error', this._html5ErrorHandler); } if (this._html5WaitingHandler) { this.mediaElement.removeEventListener('waiting', this._html5WaitingHandler); } if (this._html5CanPlayHandler) { this.mediaElement.removeEventListener('canplay', this._html5CanPlayHandler); } if (this._html5PlayingHandler) { this.mediaElement.removeEventListener('playing', this._html5PlayingHandler); } this.mediaElement = null; } } _tryGetMediaElement() { if (this.mediaElement) return; try { const node = this.player?.MediaPlayer?.mediaElement || this.player?.MediaElement?.audioNode; if (node && node.tagName) { this._attachMediaElement(node); return; } } catch (_) { /* ignore */ } try { const container = document.getElementById('td_container'); if (container) { const audio = container.querySelector('audio'); if (audio) { this._attachMediaElement(audio); } } } catch (_) { /* ignore */ } } _attachMediaElement(element) { if (this.mediaElement) return; this.mediaElement = element; if (this.isLive === undefined) { if (this.mediaElement.duration === Infinity) { this.isLive = true; } else if (!isNaN(this.mediaElement.duration)) { this.isLive = false; } } if (this.isLive === false) { this.mediaElement.addEventListener('seeking', this._seekingHandler); this.mediaElement.addEventListener('playing', this._playingHandler); } this.mediaElement.addEventListener('error', this._html5ErrorHandler); this.mediaElement.addEventListener('waiting', this._html5WaitingHandler); this.mediaElement.addEventListener('canplay', this._html5CanPlayHandler); this.mediaElement.addEventListener('playing', this._html5PlayingHandler); } registerListeners() { this.isSeeking = false; this.flags = this.flags || {}; this._adapterIsBuffering = false; this._lastStreamStatus = null; this._hasErrorFired = false; this._lastWebkitAudioBytes = undefined; this._currentPlayParams = null; this._suppressNextSdkStop = false; this._currentTrackTitle = null; this._currentArtist = null; this._currentAlbum = null; this._originalPlay = this.player.play.bind(this.player); this.player.play = (params) => { if (params) { const isNewContent = this._isNewContent(params); if ((this.flags.isStarted || this._npawVideo?.isInitiated) && isNewContent) { this._suppressNextSdkStop = true; this._cleanupMediaElement(); this.fireStop({}, 'playWrapper-contentChange'); this._originalStop(); } if (!this.flags.isStarted) { this._hasErrorFired = false; if (params.station || params.mount) { this.isLive = true; } else if (params.file) { this.isLive = false; } this._currentPlayParams = { ...params }; this.fireInit({}, 'playWrapper'); this.fireStart({}, 'playWrapper'); } } return this._originalPlay(params); }; this._originalStop = this.player.stop.bind(this.player); this.player.stop = () => { if (this.flags.isStarted || this._npawVideo?.isInitiated) { this._suppressNextSdkStop = true; this._cleanupMediaElement(); this.fireStop({}, 'stopWrapper'); } return this._originalStop(); }; this._seekingHandler = () => { if (this.flags.isStarted && !this.isSeeking && !this.isLive) { this.isSeeking = true; this.fireSeekBegin({}, false, 'html5SeekingEvent'); } }; this._playingHandler = () => { if (this.isSeeking) { this.isSeeking = false; this.fireSeekEnd({}, 'html5PlayingEvent'); } }; this._html5ErrorHandler = () => { const error = this.mediaElement?.error; const networkState = this.mediaElement?.networkState; if (this._hasErrorFired) { return; } let shouldFireError = false; let errorCode = ''; let errorMsg = ''; if (error) { const errorMessages = { 1: 'MEDIA_ERR_ABORTED - Playback aborted by user', 2: 'MEDIA_ERR_NETWORK - Network error while loading media', 3: 'MEDIA_ERR_DECODE - Media decoding error', 4: 'MEDIA_ERR_SRC_NOT_SUPPORTED - Media source not supported or not found' }; if (error.code === 2 || error.code === 4) { shouldFireError = true; errorCode = `HTML5_ERROR_${error.code}`; errorMsg = error.message || errorMessages[error.code]; } } else if (networkState === 3) { shouldFireError = true; errorCode = 'NETWORK_NO_SOURCE'; errorMsg = 'Media source not accessible'; } if (shouldFireError) { this._hasErrorFired = true; this.fireFatalError(errorCode, errorMsg, undefined, undefined, 'html5ErrorEvent'); this.fireStop({}, 'html5ErrorEvent'); } }; this._html5WaitingHandler = () => { if (!this.isSeeking) { this._bufferBeginListener(); } }; this._html5CanPlayHandler = () => { this._bufferEndListener(); }; this._html5PlayingHandler = () => { this._bufferEndListener(); }; this._playbackStatusHandler = (ev) => { if (ev.data) { this.flags = this.flags || {}; if (ev.data.mediaElement && !this.mediaElement && ev.data.status !== 'Stopped' && ev.data.status !== 'Ended') { this._attachMediaElement(ev.data.mediaElement); } switch (ev.data.status) { case 'Buffering': case 'Loading': this._bufferBeginListener(); break; case 'Playing': this._joinListener(); this._resumeListener(); this._bufferEndListener(); break; case 'Paused': this._pauseListener(); break; case 'Stopped': case 'Ended': this._stopListener(); break; } } }; this._streamStatusHandler = (ev) => { const currentStatus = ev.data?.status; const previousStatus = this._lastStreamStatus; this._lastStreamStatus = currentStatus; if (ev.data && currentStatus === 'Buffering') { this._bufferBeginListener(); } else if (previousStatus === 'Buffering' && currentStatus !== 'Buffering') { this._bufferEndListener(); } }; this._streamStartHandler = () => { if (!this.mediaElement) { this._tryGetMediaElement(); } this._joinListener(); }; this._streamStopHandler = () => { this._stopListener(); }; this._streamPauseHandler = () => { this._pauseListener(); }; this._streamResumeHandler = () => { this._resumeListener(); this._bufferEndListener(); }; this._trackCuePointHandler = (ev) => { if (ev.data && ev.data.cuePoint) { const cuePoint = ev.data.cuePoint; this._currentTrackTitle = cuePoint.cueTitle || null; this._currentArtist = cuePoint.artistName || null; this._currentAlbum = cuePoint.albumName || null; } }; this._errorHandler = (ev) => { this._errorListener(ev); }; this._streamFailHandler = (ev) => { this._errorListener(ev); }; this._geoBlockedHandler = () => { if (!this._hasErrorFired) { this._hasErrorFired = true; this.fireFatalError( 'GEO_BLOCKED', 'Stream is geo-blocked in this region', undefined, undefined, 'geoBlockedEvent' ); this.fireStop({}, 'geoBlockedEvent'); } }; this.player.addEventListener('media-playback-status', this._playbackStatusHandler); this.player.addEventListener('stream-status', this._streamStatusHandler); this.player.addEventListener('stream-start', this._streamStartHandler); this.player.addEventListener('stream-stop', this._streamStopHandler); this.player.addEventListener('stream-pause', this._streamPauseHandler); this.player.addEventListener('stream-resume', this._streamResumeHandler); this.player.addEventListener('media-error', this._errorHandler); this.player.addEventListener('stream-fail', this._streamFailHandler); this.player.addEventListener('stream-geo-blocked', this._geoBlockedHandler); this.player.addEventListener('track-cue-point', this._trackCuePointHandler); } unregisterListeners() { if (this._originalPlay && this.player) { this.player.play = this._originalPlay; this._originalPlay = null; } if (this._originalStop && this.player) { this.player.stop = this._originalStop; this._originalStop = null; } if (this._playbackStatusHandler) { this.player.removeEventListener('media-playback-status', this._playbackStatusHandler); this._playbackStatusHandler = null; } if (this._streamStatusHandler) { this.player.removeEventListener('stream-status', this._streamStatusHandler); this._streamStatusHandler = null; } if (this._streamStartHandler) { this.player.removeEventListener('stream-start', this._streamStartHandler); this._streamStartHandler = null; } if (this._streamStopHandler) { this.player.removeEventListener('stream-stop', this._streamStopHandler); this._streamStopHandler = null; } if (this._streamPauseHandler) { this.player.removeEventListener('stream-pause', this._streamPauseHandler); this._streamPauseHandler = null; } if (this._streamResumeHandler) { this.player.removeEventListener('stream-resume', this._streamResumeHandler); this._streamResumeHandler = null; } if (this._errorHandler) { this.player.removeEventListener('media-error', this._errorHandler); this._errorHandler = null; } if (this._streamFailHandler) { this.player.removeEventListener('stream-fail', this._streamFailHandler); this._streamFailHandler = null; } if (this._geoBlockedHandler) { this.player.removeEventListener('stream-geo-blocked', this._geoBlockedHandler); this._geoBlockedHandler = null; } if (this._trackCuePointHandler) { this.player.removeEventListener('track-cue-point', this._trackCuePointHandler); this._trackCuePointHandler = null; } this._cleanupMediaElement(); this._hasErrorFired = false; this._lastWebkitAudioBytes = undefined; this._currentPlayParams = null; } }