Skip to main content

Casting

Play to Chromecast and AirPlay devices through one API — getCastManager(). See the Cast manager API for the full surface.

Chromecast​

Enable the plugin flag​

{
"expo": {
"plugins": [["react-native-queue-player", {
"chromecast": true,
"chromecastReceiverAppId": "CC1AD845"
}]]
}
}
  • On iOS this adds the Cast pod, the Bonjour / local-network Info.plist keys, and the AppDelegate Cast init. chromecastReceiverAppId sets the iOS receiver app (defaults to Google's Default Media Receiver).
  • On Android the Cast components are merged from the library manifest automatically.

Run npx expo prebuild --clean after changing the flag; a prebuild without --clean does not remove what the flag added once it is turned off.

Bare React Native: there's no plugin — add pod 'QueuePlayer/Chromecast' to your Podfile, the Bonjour / local-network Info.plist keys (NSLocalNetworkUsageDescription, NSBonjourServices, QueuePlayerChromecastReceiverApplicationID), and call ChromecastSupport.installWithDefaults() in your AppDelegate by hand. See the bare-RN setup table.

Local-network permission​

Chromecast discovery needs local-network access. Check and request it before discovering:

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

const cast = getCastManager();
if (cast.getLocalNetworkPermissionState() !== 'granted') {
await cast.requestLocalNetworkPermission();
}

On newer Android versions, also request the runtime local-network permission from your app.

AirPlay​

  • iOS — AirPlay is OS-managed. Present the system route picker:

    await getCastManager().showSystemPicker(); // AVRoutePickerView

    By default the player renders the audio on the device and AirPlay carries it, for every receiver type. The lookahead cache, EQ, ReplayGain, crossfade and the visualizer work the same over AirPlay as on the speaker.

    Some receivers, such as an Apple TV or a Mac, also support external playback: AVPlayer hands the track URL to the receiver and the receiver plays it itself. To allow it, set allowsExternalPlayback: true in configure() and call setLookaheadCache({ enabled: false }) before queueing tracks. The cache is on by default, and a remote track queued while it is on plays from a loopback URL that only the device can reach, so a receiver given that URL fails it. Tracks queued before the cache was disabled keep that URL. The receiver fetches the URL itself, so headers from httpHeaders are not guaranteed to reach it. While a receiver plays the URL, the device does not render the audio, so EQ, ReplayGain, crossfade, the visualizer and end-of-track events may not behave as on local output.

  • Android — a native AirPlay sender is included and wired automatically; AirPlay receivers appear alongside Chromecast devices in discovery.

    AirPlay receivers running on Mac computers are hidden by default: macOS AirPlay Receiver only accepts Apple senders on the same Apple ID, so it can't be cast to from here and would only be a dead entry in your picker. To surface them anyway:

    await getCastManager().configure({ deviceName: 'My App', hideAirPlayComputers: false });

Discover, connect, control​

const cast = getCastManager();

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

await cast.setRouteVolume(0.6); // 0.0 – 1.0
await cast.disconnect();

Playback state — the queue, position, and play/pause — is maintained across local ↔ remote transitions.

React​

import { useCast, useAudioRoute } from 'react-native-queue-player';

function CastButton() {
const { receivers, route, isDiscovering } = useCast();
const output = useAudioRoute(); // current output route (speaker, BT, AirPlay, Chromecast, …)
// render a picker from `receivers`, show `route` / `output` as the active target
}

See the Cast manager API for events, pairing, and the Cast convenience namespace.