Skip to main content

Cast manager

Discovery, connection, and route control for Chromecast and AirPlay. Get the singleton with getCastManager(). For end-to-end setup (plugin flag, receiver app ID, permissions) see the Casting guide.

import { getCastManager } from 'react-native-queue-player';

const cast = getCastManager();
await cast.startDiscovery();
const receivers = cast.getReceivers();
await cast.connect(receivers[0].id, { password: '' });

Methods

getSupportedProtocols(): CastProtocol[] // 'local' | 'airplay' | 'chromecast' | 'dlna' | 'sonos'
configure(config: CastConfigureOptions): Promise<void> // AirPlay name + discovery filters

startDiscovery(): Promise<void>
stopDiscovery(): Promise<void>
isDiscovering(): boolean
getReceivers(): CastReceiver[]

getCurrentRoute(): CastRoute
connect(receiverId: string, options: CastConnectOptions): Promise<void> // options: { password: string }
disconnect(): Promise<void>
showSystemPicker(): Promise<void> // iOS AVRoutePickerView; no-op on Android

getRouteVolume(): number // NaN when no remote session
setRouteVolume(value: number): Promise<void>
submitPairingPin(pin: string): Promise<void>

getLocalNetworkPermissionState(): CastLocalNetworkPermission // 'undetermined' | 'granted' | 'denied'
requestLocalNetworkPermission(): Promise<CastLocalNetworkPermission>

getCurrentAudioRoute(): AudioRoute

Events

Each returns a disposer; the route/receiver/discovery/permission listeners fire once on subscribe with current state.

onRouteChange(cb: (route: CastRoute) => void): () => void
onReceiversChange(cb: (receivers: CastReceiver[]) => void): () => void
onDiscoveryStateChange(cb: (state: { isDiscovering: boolean }) => void): () => void
onSessionDied(cb: (event: { receiverId: string; reason: CastSessionEndReason }) => void): () => void
onLocalNetworkPermissionChange(cb: (event: { state: CastLocalNetworkPermission }) => void): () => void
onAudioRouteChange(cb: (route: AudioRoute) => void): () => void

The Cast namespace

A convenience wrapper is exported as Cast, with the same operations plus listener handles that use a { remove() } pattern:

import { Cast } from 'react-native-queue-player';

await Cast.startDiscovery();
const sub = Cast.addRouteListener((route) => { /* … */ });
sub.remove();

Connection errors

connect() rejects when a connection can't be established. The CastErrorCode values (exposed under the Cast namespace as Cast.CastErrorCodes) identify why:

import { Cast } from 'react-native-queue-player';
CodeValueMeaning
Cast.CastErrorCodes.CONNECT_FAILED'cast_connect_failed'The connection attempt failed.
Cast.CastErrorCodes.AUTH_REQUIRED'cast_auth_required'The receiver needs pairing — prompt for a PIN and call submitPairingPin().

Types (selected)

type CastReceiver = {
id: string;
castProtocol: CastProtocol;
name: string;
iconHint: CastDeviceKind; // 'phone'|'speaker'|'tv'|'display'|'speakerGroup'|'unknown'
capabilities: { supportsRemoteVolume: boolean; streamingModel: 'pushPcm'|'pullUrl'; requiresPairing: boolean };
protocolVersion: string;
modelName: string;
};

type AudioRoute = {
kind: AudioRouteKind; // 'speaker'|'wired'|'bluetoothA2DP'|'carPlay'|'airplay'|'chromecast'|…
name: string;
identifier: string;
isExternal: boolean;
isSystemManaged: boolean;
};

type CastConfigureOptions = {
deviceName: string; // advertised AirPlay handshake name (falls back to OS device name)
hideAirPlayComputers?: boolean; // hide un-connectable Mac AirPlay receivers; default true
};

Hiding Mac AirPlay receivers

macOS AirPlay Receiver only accepts Apple senders on the same Apple ID, so a Mac cannot be cast to from this library — it shows up as a dead entry in the picker. configure hides Mac receivers by default; pass hideAirPlayComputers: false to surface them anyway. Android-only — on iOS the AirPlay receiver list is owned by the system picker.

await Cast.configure({ deviceName: 'Living Room', hideAirPlayComputers: false });

In React, see useCast and useAudioRoute.