UNPKG

react-native-track-player

Version:
177 lines (150 loc) 5.59 kB
import { DeviceEventEmitter } from 'react-native'; import { Event, PlaybackState, State } from '../src'; import type { Track, UpdateOptions } from '../src'; import { PlaylistPlayer, RepeatMode } from './TrackPlayer'; import { SetupNotCalledError } from './TrackPlayer/SetupNotCalledError'; export class TrackPlayerModule extends PlaylistPlayer { protected emitter = DeviceEventEmitter; protected progressUpdateEventInterval: any; // Capabilities public readonly CAPABILITY_PLAY = 'CAPABILITY_PLAY'; public readonly CAPABILITY_PLAY_FROM_ID = 'CAPABILITY_PLAY_FROM_ID'; public readonly CAPABILITY_PLAY_FROM_SEARCH = 'CAPABILITY_PLAY_FROM_SEARCH'; public readonly CAPABILITY_PAUSE = 'CAPABILITY_PAUSE'; public readonly CAPABILITY_STOP = 'CAPABILITY_STOP'; public readonly CAPABILITY_SEEK_TO = 'CAPABILITY_SEEK_TO'; public readonly CAPABILITY_SKIP = 'CAPABILITY_SKIP'; public readonly CAPABILITY_SKIP_TO_NEXT = 'CAPABILITY_SKIP_TO_NEXT'; public readonly CAPABILITY_SKIP_TO_PREVIOUS = 'CAPABILITY_SKIP_TO_PREVIOUS'; public readonly CAPABILITY_JUMP_FORWARD = 'CAPABILITY_JUMP_FORWARD'; public readonly CAPABILITY_JUMP_BACKWARD = 'CAPABILITY_JUMP_BACKWARD'; public readonly CAPABILITY_SET_RATING = 'CAPABILITY_SET_RATING'; public readonly CAPABILITY_LIKE = 'CAPABILITY_LIKE'; public readonly CAPABILITY_DISLIKE = 'CAPABILITY_DISLIKE'; public readonly CAPABILITY_BOOKMARK = 'CAPABILITY_BOOKMARK'; // States public readonly STATE_NONE = 'STATE_NONE'; public readonly STATE_READY = 'STATE_READY'; public readonly STATE_PLAYING = 'STATE_PLAYING'; public readonly STATE_PAUSED = 'STATE_PAUSED'; public readonly STATE_STOPPED = 'STATE_STOPPED'; public readonly STATE_BUFFERING = 'STATE_BUFFERING'; public readonly STATE_CONNECTING = 'STATE_CONNECTING'; // Rating Types public readonly RATING_HEART = 'RATING_HEART'; public readonly RATING_THUMBS_UP_DOWN = 'RATING_THUMBS_UP_DOWN'; public readonly RATING_3_STARS = 'RATING_3_STARS'; public readonly RATING_4_STARS = 'RATING_4_STARS'; public readonly RATING_5_STARS = 'RATING_5_STARS'; public readonly RATING_PERCENTAGE = 'RATING_PERCENTAGE'; // Repeat Modes public readonly REPEAT_OFF = RepeatMode.Off; public readonly REPEAT_TRACK = RepeatMode.Track; public readonly REPEAT_QUEUE = RepeatMode.Playlist; // Pitch Algorithms public readonly PITCH_ALGORITHM_LINEAR = 'PITCH_ALGORITHM_LINEAR'; public readonly PITCH_ALGORITHM_MUSIC = 'PITCH_ALGORITHM_MUSIC'; public readonly PITCH_ALGORITHM_VOICE = 'PITCH_ALGORITHM_VOICE'; // observe and emit state changes public get state(): PlaybackState { return super.state; } public set state(newState: PlaybackState) { super.state = newState; this.emitter.emit(Event.PlaybackState, newState); } public async updateOptions(options: UpdateOptions) { this.setupProgressUpdates(options.progressUpdateEventInterval); } protected setupProgressUpdates(interval?: number) { // clear and reset interval this.clearUpdateEventInterval(); if (interval) { this.clearUpdateEventInterval() this.progressUpdateEventInterval = setInterval( async () => { if (this.state.state === State.Playing) { const progress = await this.getProgress() this.emitter.emit(Event.PlaybackProgressUpdated, { ...progress, track: this.currentIndex, }); } }, interval * 1000, ) } } protected clearUpdateEventInterval() { if (this.progressUpdateEventInterval) { clearInterval(this.progressUpdateEventInterval); } } protected async onTrackEnded() { const position = this.element!.currentTime; await super.onTrackEnded(); this.emitter.emit(Event.PlaybackTrackChanged, { track: this.lastIndex, position, nextTrack: this.currentIndex, }); } protected async onPlaylistEnded() { await super.onPlaylistEnded(); this.emitter.emit(Event.PlaybackQueueEnded, { track: this.currentIndex, position: this.element!.currentTime, }); } public get playWhenReady(): boolean { return super.playWhenReady; } public set playWhenReady(pwr: boolean) { const didChange = pwr !== this._playWhenReady; super.playWhenReady = pwr; if (didChange) { this.emitter.emit(Event.PlaybackPlayWhenReadyChanged, { playWhenReady: this._playWhenReady }); } } public getPlayWhenReady(): boolean { return this.playWhenReady; } public setPlayWhenReady(pwr: boolean): boolean { this.playWhenReady = pwr; return this.playWhenReady; } public async load(track: Track) { if (!this.element) throw new SetupNotCalledError(); const lastTrack = this.current; const lastPosition = this.element.currentTime; await super.load(track); this.emitter.emit(Event.PlaybackActiveTrackChanged, { lastTrack, lastPosition, lastIndex: this.lastIndex, index: this.currentIndex, track, }); } public getQueue(): Track[] { return this.playlist; } public getActiveTrack(): Track | undefined { return this.current; } public getActiveTrackIndex(): number | undefined { // per the existing spec, this should throw if setup hasn't been called if (!this.element || !this.player) throw new SetupNotCalledError(); return this.currentIndex; } /** * @deprecated * @returns State */ public getState(): State { return this.state.state; } public getPlaybackState(): PlaybackState { return this.state; } };