UNPKG

react-native-audio-api

Version:

react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification

88 lines (73 loc) 2.17 kB
import { isFfmpegEnabled } from './flags'; export function isRemoteHttpUrl(path: string): boolean { return path.startsWith('http://') || path.startsWith('https://'); } function isHlsPlaylistUrl(path: string): boolean { return path.split('?')[0].toLowerCase().includes('.m3u8'); } /** Detect whether the server supports HTTP byte ranges (HEAD, then Range probe). */ async function detectHttpByteRanges( url: string, headers?: Record<string, string> ): Promise<boolean> { try { const headResponse = await fetch(url, { method: 'HEAD', headers }); if (headResponse.ok) { const acceptRanges = headResponse.headers .get('Accept-Ranges') ?.toLowerCase(); if (acceptRanges === 'bytes') { return true; } return false; } } catch { // HEAD may be blocked or unsupported — fall through to a Range GET probe. } try { const rangeResponse = await fetch(url, { headers: { ...headers, Range: 'bytes=0-0' }, }); if (rangeResponse.status === 206) { return true; } // Server ignored Range and returned the full resource. if (rangeResponse.status === 200) { return false; } } catch { return false; } return false; } async function downloadRemoteHttpSource( url: string, headers?: Record<string, string> ): Promise<ArrayBuffer> { const response = await fetch(url, { headers }); if (!response.ok) { throw new Error(`Failed to download remote audio (${response.status}).`); } return response.arrayBuffer(); } /** * Stream via native URL when FFmpeg is enabled and byte ranges work (or HLS); * otherwise download fully so miniaudio can decode without FFmpeg. */ export async function loadRemoteHttpSource( url: string, headers?: Record<string, string>, forceDownload = false ): Promise<ArrayBuffer | string> { if (isHlsPlaylistUrl(url)) { return url; } if (!isFfmpegEnabled() || forceDownload) { return downloadRemoteHttpSource(url, headers); } const hasByteRanges = await detectHttpByteRanges(url, headers); if (hasByteRanges) { return url; } return downloadRemoteHttpSource(url, headers); }