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.
chromecastReceiverAppIdsets 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(); // AVRoutePickerViewBy 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: trueinconfigure()and callsetLookaheadCache({ 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 fromhttpHeadersare 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.