UNPKG

react-native-theoplayer

Version:

A THEOplayer video component for react-native.

418 lines (411 loc) 13.4 kB
"use strict"; import { DefaultEventDispatcher } from './event/DefaultEventDispatcher'; import { addTrack, findMediaTrackByUid, MediaTrackEventType, MediaTrackType, PlayerEventType, PresentationMode, removeTrack, TrackListEventType } from 'react-native-theoplayer'; import { THEOplayerNativeAdsAdapter } from './ads/THEOplayerNativeAdsAdapter'; import { THEOplayerNativeCastAdapter } from './cast/THEOplayerNativeCastAdapter'; import { AbrAdapter } from './abr/AbrAdapter'; import { NativeModules, Platform, StatusBar } from 'react-native'; import { TextTrackStyleAdapter } from './track/TextTrackStyleAdapter'; import { EventBroadcastAdapter } from './broadcast/EventBroadcastAdapter'; import { DefaultNativePlayerState } from './DefaultNativePlayerState'; import { THEOAdsNativeAdapter } from './theoads/THEOAdsNativeAdapter'; import { TheoLiveNativeAdapter } from './theolive/TheoLiveNativeAdapter'; const NativePlayerModule = NativeModules.THEORCTPlayerModule; export class THEOplayerAdapter extends DefaultEventDispatcher { _externalEventRouter = undefined; constructor(view) { super(); this._view = view; this._state = new DefaultNativePlayerState(this); this._adsAdapter = new THEOplayerNativeAdsAdapter(this._view); this._theoAdsAdapter = new THEOAdsNativeAdapter(this._view); this._castAdapter = new THEOplayerNativeCastAdapter(this, this._view); this._abrAdapter = new AbrAdapter(this._view); this._textTrackStyleAdapter = new TextTrackStyleAdapter(this._view); this._theoliveAdapter = new TheoLiveNativeAdapter(this._view); this.addEventListener(PlayerEventType.LOADED_METADATA, this.onLoadedMetadata); this.addEventListener(PlayerEventType.PAUSE, this.onPause); this.addEventListener(PlayerEventType.PLAYING, this.onPlaying); this.addEventListener(PlayerEventType.TIME_UPDATE, this.onTimeupdate); this.addEventListener(PlayerEventType.DURATION_CHANGE, this.onDurationChange); this.addEventListener(PlayerEventType.RATE_CHANGE, this.onRateChange); this.addEventListener(PlayerEventType.SEEKING, this.onSeeking); this.addEventListener(PlayerEventType.SEEKED, this.onSeeked); this.addEventListener(PlayerEventType.PROGRESS, this.onProgress); this.addEventListener(PlayerEventType.MEDIA_TRACK, this.onMediaTrack); this.addEventListener(PlayerEventType.MEDIA_TRACK_LIST, this.onMediaTrackList); this.addEventListener(PlayerEventType.PRESENTATIONMODE_CHANGE, this.onPresentationModeChange); this.addEventListener(PlayerEventType.RESIZE, this.onResize); } hasValidSource() { return this._state.source !== undefined; } onPause = () => { this._state.paused = true; }; onPlaying = () => { this._state.paused = false; }; onPresentationModeChange = event => { this._state.presentationMode = event.presentationMode; if (Platform.OS === 'ios') { StatusBar.setHidden(event.presentationMode === PresentationMode.fullscreen, 'slide'); } }; onTimeupdate = event => { this._state.currentTime = event.currentTime; this._state.currentProgramDateTime = event.currentProgramDateTime; }; onResize = event => { this._state.width = event.width; this._state.height = event.height; }; onLoadedMetadata = event => { this._state.duration = event.duration; this._state.audioTracks = event.audioTracks; this._state.videoTracks = event.videoTracks; this._state.selectedAudioTrack = event.selectedAudioTrack; this._state.selectedVideoTrack = event.selectedVideoTrack; if (isFinite(this._state.duration)) { this._state.seekable = [{ start: 0, end: this._state.duration }]; } }; onDurationChange = event => { this._state.duration = event.duration; }; onRateChange = event => { this._state.playbackRate = event.playbackRate; }; onSeeking = () => { this._state.seeking = true; }; onSeeked = () => { this._state.seeking = false; }; onProgress = event => { this._state.seekable = event.seekable?.sort((a, b) => a.end - b.end); this._state.buffered = event.buffered?.sort((a, b) => a.end - b.end); }; onMediaTrack = event => { const { subType, trackType, trackUid } = event; const tracks = trackType === MediaTrackType.VIDEO ? this._state.videoTracks : this._state.audioTracks; const track = findMediaTrackByUid(tracks, trackUid); switch (subType) { case MediaTrackEventType.ACTIVE_QUALITY_CHANGED: // Update local state if (track) { Object.assign(track, { ...track, activeQuality: event.qualities }); } break; } }; onMediaTrackList = event => { const { subType, trackType, track } = event; const isAudio = trackType === MediaTrackType.AUDIO; switch (subType) { case TrackListEventType.ADD_TRACK: if (isAudio) { this._state.audioTracks = addTrack(this._state.audioTracks, track); } else { this._state.videoTracks = addTrack(this._state.videoTracks, track); } break; case TrackListEventType.REMOVE_TRACK: if (isAudio) { this._state.audioTracks = removeTrack(this._state.audioTracks, track); } else { this._state.videoTracks = removeTrack(this._state.videoTracks, track); } break; case TrackListEventType.CHANGE_TRACK: if (isAudio) { this._state.audioTracks = removeTrack(this._state.audioTracks, track); this._state.audioTracks = addTrack(this._state.audioTracks, track); if (track.enabled) { this._state.selectedAudioTrack = track.uid; } } else { this._state.videoTracks = removeTrack(this._state.videoTracks, track); this._state.videoTracks = addTrack(this._state.videoTracks, track); if (track.enabled) { this._state.selectedVideoTrack = track.uid; } } break; } }; get abr() { return this._abrAdapter; } get ads() { return this._adsAdapter; } get theoads() { return this._theoAdsAdapter; } get theolive() { return this._theoliveAdapter; } set autoplay(autoplay) { this._state.autoplay = autoplay; NativePlayerModule.setAutoplay(this._view.nativeHandle, autoplay); } get autoplay() { return this._state.autoplay; } set preload(type) { this._state.preload = type; NativePlayerModule.setPreload(this._view.nativeHandle, type); } get preload() { return this._state.preload; } get seekable() { return this._state.seekable ?? []; } seekableEnd() { const ranges = this.seekable; return ranges.length === 0 ? 0 : ranges[ranges.length - 1].end; } get buffered() { return this._state.buffered ?? []; } get cast() { return this._castAdapter; } get currentTime() { return this._state.currentTime; } set currentTime(currentTime) { if (!this.hasValidSource()) { return; } if (isNaN(currentTime)) { return; } // Sanitise currentTime let seekTime = currentTime; if (currentTime === Infinity) { seekTime = this.seekableEnd(); } this._state.currentTime = seekTime; NativePlayerModule.setCurrentTime(this._view.nativeHandle, seekTime); } get currentProgramDateTime() { return this._state.currentProgramDateTime; } get duration() { return this._state.duration; } get pipConfiguration() { return this._state.pipConfig; } set pipConfiguration(pipConfiguration) { this._state.pipConfig = pipConfiguration; NativePlayerModule.setPipConfig(this._view.nativeHandle, pipConfiguration); } get backgroundAudioConfiguration() { return this._state.backgroundAudioConfig; } set backgroundAudioConfiguration(backgroundAudioConfiguration) { this._state.backgroundAudioConfig = backgroundAudioConfiguration; NativePlayerModule.setBackgroundAudioConfig(this._view.nativeHandle, backgroundAudioConfiguration); } get presentationMode() { return this._state.presentationMode; } set presentationMode(presentationMode) { this._state.presentationMode = presentationMode; NativePlayerModule.setPresentationMode(this._view.nativeHandle, presentationMode); } get muted() { return this._state.muted; } set muted(muted) { this._state.muted = muted; NativePlayerModule.setMuted(this._view.nativeHandle, muted); } get seeking() { return this._state.seeking; } get paused() { return this._state.paused; } get playbackRate() { return this._state.playbackRate; } set playbackRate(playbackRate) { this._state.playbackRate = playbackRate; NativePlayerModule.setPlaybackRate(this._view.nativeHandle, playbackRate); } get audioTracks() { return this._state.audioTracks; } get selectedAudioTrack() { return this._state.selectedAudioTrack; } set selectedAudioTrack(trackUid) { if (!this.hasValidSource()) { return; } this._state.selectedAudioTrack = trackUid; NativePlayerModule.setSelectedAudioTrack(this._view.nativeHandle, trackUid !== undefined ? trackUid : -1); } get videoTracks() { return this._state.videoTracks; } get selectedVideoTrack() { return this._state.selectedVideoTrack; } set selectedVideoTrack(trackUid) { if (!this.hasValidSource()) { return; } this._state.selectedVideoTrack = trackUid; this._state.targetVideoQuality = undefined; NativePlayerModule.setSelectedVideoTrack(this._view.nativeHandle, trackUid !== undefined ? trackUid : -1); } get textTracks() { return this._state.textTracks; } get selectedTextTrack() { return this._state.selectedTextTrack; } set selectedTextTrack(trackUid) { this._state.selectedTextTrack = trackUid; // Apply native selection NativePlayerModule.setSelectedTextTrack(this._view.nativeHandle, trackUid !== undefined ? trackUid : -1); } get textTrackStyle() { return this._textTrackStyleAdapter; } get source() { return this._state.source; } set source(source) { // This is to correctly reset autoplay during a source change. this.pause(); this._state.source = source; NativePlayerModule.setSource(this._view.nativeHandle, source); // Reset state for play-out of new source this._state.apply({ playbackRate: 1, seeking: false, audioTracks: [], videoTracks: [], textTracks: [], seekable: [], buffered: [], selectedTextTrack: undefined, selectedVideoTrack: undefined, selectedAudioTrack: undefined, targetVideoQuality: undefined }); } get targetVideoQuality() { return this._state.targetVideoQuality; } set targetVideoQuality(target) { if (!this.hasValidSource()) { return; } // Always pass an array for targetVideoQuality. this._state.targetVideoQuality = target === undefined ? [] : Array.isArray(target) ? target : [target]; // Update local state const track = findMediaTrackByUid(this._state.videoTracks, this.selectedVideoTrack); if (track) { Object.assign(track, { ...track, targetQuality: this._state.targetVideoQuality }); } NativePlayerModule.setTargetVideoQuality(this._view.nativeHandle, this._state.targetVideoQuality); } get volume() { return this._state.volume; } set volume(volume) { this._state.volume = volume; NativePlayerModule.setVolume(this._view.nativeHandle, volume); } get aspectRatio() { return this._state.aspectRatio; } set aspectRatio(ratio) { this._state.aspectRatio = ratio; NativePlayerModule.setAspectRatio(this._view.nativeHandle, ratio); } get renderingTarget() { return this._state.renderingTarget; } set renderingTarget(target) { if (Platform.OS === 'android') { this._state.renderingTarget = target; NativePlayerModule.setRenderingTarget(this._view.nativeHandle, target); } } get keepScreenOn() { return this._state.keepScreenOn; } set keepScreenOn(value) { this._state.keepScreenOn = value; NativePlayerModule.setKeepScreenOn(this._view.nativeHandle, value); } pause() { if (this.hasValidSource()) { this._state.paused = true; NativePlayerModule.setPaused(this._view.nativeHandle, true); } } play() { if (this.hasValidSource()) { this._state.paused = false; NativePlayerModule.setPaused(this._view.nativeHandle, false); } } get version() { return this._playerVersion; } // @internal get nativeHandle() { return this._view.nativeHandle; } // @internal get broadcast() { return this._externalEventRouter ?? (this._externalEventRouter = new EventBroadcastAdapter(this)); } /** * initializeFromNativePlayer is called when the native player is ready and has sent the `onNativePlayerReady` event. * * @param version The native player version. * @param state An optional initial player state. */ async initializeFromNativePlayer_(version, state) { this._playerVersion = version; if (state) { this._state.apply(state); } await this._castAdapter.init_(); } get width() { return this._state.width; } get height() { return this._state.height; } } //# sourceMappingURL=THEOplayerAdapter.js.map