mirror of
https://github.com/Boof2015/astra-mobile.git
synced 2026-08-19 04:06:43 +02:00
82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
import TrackPlayer, { isPlaying } from 'react-native-track-player';
|
||
import type { Track } from '@/types/audio';
|
||
import { setupPlayer } from './trackPlayer';
|
||
import { SAMPLE_TRACKS, toRntpTrack } from './sampleTracks';
|
||
|
||
/**
|
||
* Transport actions screens call. Thin wrappers over RNTP so the UI never
|
||
* imports the engine directly — at M3/M4 this is where a custom Media3 module
|
||
* would slot in behind the same function signatures.
|
||
*/
|
||
|
||
/**
|
||
* Set up the player. Setup is deferred to here (a user-initiated play) rather
|
||
* than app launch: RNTP starts a foreground MediaSession service on setup, and
|
||
* Android only permits starting a foreground service while the app is in the
|
||
* foreground.
|
||
*/
|
||
async function ensurePlayerReady(): Promise<void> {
|
||
await setupPlayer();
|
||
}
|
||
|
||
/** Replace the queue with the given tracks and start playing at startIndex. */
|
||
export async function playTracks(tracks: Track[], startIndex = 0): Promise<void> {
|
||
if (tracks.length === 0) return;
|
||
await ensurePlayerReady();
|
||
await TrackPlayer.setQueue(tracks.map(toRntpTrack));
|
||
if (startIndex > 0) {
|
||
await TrackPlayer.skip(startIndex);
|
||
}
|
||
await TrackPlayer.play();
|
||
}
|
||
|
||
/** Fisher–Yates shuffle a copy of the tracks and play from the top. */
|
||
export async function shuffleTracks(tracks: Track[]): Promise<void> {
|
||
const shuffled = [...tracks];
|
||
for (let i = shuffled.length - 1; i > 0; i--) {
|
||
const j = Math.floor(Math.random() * (i + 1));
|
||
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
||
}
|
||
await playTracks(shuffled);
|
||
}
|
||
|
||
/** M0 demo entry point: load the streamed sample queue if nothing is queued. */
|
||
export async function playSample(): Promise<void> {
|
||
await ensurePlayerReady();
|
||
const queue = await TrackPlayer.getQueue();
|
||
if (queue.length === 0) {
|
||
await TrackPlayer.add(SAMPLE_TRACKS.map(toRntpTrack));
|
||
}
|
||
await TrackPlayer.play();
|
||
}
|
||
|
||
export const play = (): Promise<void> => TrackPlayer.play();
|
||
export const pause = (): Promise<void> => TrackPlayer.pause();
|
||
export const seekTo = (seconds: number): Promise<void> => TrackPlayer.seekTo(seconds);
|
||
|
||
export async function togglePlay(): Promise<void> {
|
||
const { playing } = await isPlaying();
|
||
if (playing) {
|
||
await TrackPlayer.pause();
|
||
} else {
|
||
await ensurePlayerReady();
|
||
await TrackPlayer.play();
|
||
}
|
||
}
|
||
|
||
export async function skipToNext(): Promise<void> {
|
||
try {
|
||
await TrackPlayer.skipToNext();
|
||
} catch {
|
||
// no next track — ignore
|
||
}
|
||
}
|
||
|
||
export async function skipToPrevious(): Promise<void> {
|
||
try {
|
||
await TrackPlayer.skipToPrevious();
|
||
} catch {
|
||
// no previous track — ignore
|
||
}
|
||
}
|