tien / react-airplay

Airplay bridge for React Native
MIT License
38 stars 8 forks source link

Question: Any way to select which source to Airplay? #228

Open watadarkstar opened 1 year ago

watadarkstar commented 1 year ago

I have an app that is using react-native-track-player for audio and react-native-video for video. I want the Airplay to use the video when air playing to a device. However, it is currently only playing the audio and not the video.

I found that when I comment out this line it plays video:

import TrackPlayer from "react-native-track-player"

TrackPlayer.registerPlaybackService(() => addTrackPlayerListeners)

I want to be able to use my Video component from react-native-video for Airplay but for some reason track player is taking priority over the video on the screen.

tien commented 2 months ago

Hey sorry hasn't got time to maintain this library in a while 😅 Do you still have this issue? From what I know, I don't think you manually select the "source". Maybe try the prioritizesVideoDevices property.

techgerm commented 1 month ago

@watadarkstar did you have to do any special setup to get AirPlay video to work with react-native-video after you commented out the track player registration?

I'm experiencing a similar issue where I have a starter Expo app with react-native-video and no react-native-track-player but every time I attempt to AirPlay, only audio plays on my TV and the video remains playing on my phone.

It's a POC so very bare bones - does the code below look similar to what you have?

Thanks in advance for your time!

import React, { useRef } from 'react';
import { SafeAreaView, StyleSheet, StatusBar, View, Button, Text } from 'react-native';
import Video, { VideoRef, TextTrackType } from 'react-native-video';
import {
  AirplayButton,
  showRoutePicker,
  useAirplayConnectivity,
  useExternalPlaybackAvailability,
  useAvAudioSessionRoutes,
} from 'react-airplay';

export const App = () => {
  const videoRef = useRef<VideoRef>(null);

  const isAirplayConnected = useAirplayConnectivity();
  const isExternalPlaybackAvailable = useExternalPlaybackAvailability();
  const routes = useAvAudioSessionRoutes();

  console.log('IS AIRPLAY CONNECTED:', isAirplayConnected);
  console.log('IS EXTERNAL PLAYBACK AVAILABLE:', isExternalPlaybackAvailable);
  console.log('ROUTES:', routes);

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView
        style={{
          flex: 1,
        }}
      >
        <Video
          // Store reference
          ref={videoRef}
          source={{
            uri: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
          }}
          onLoad={(data) => console.log('LOAD:', data)}
          // Callback when remote video is buffering
          onBuffer={(buffer) => console.log('BUFFER:', buffer)}
          // Callback when video cannot be loaded
          onError={(error) => console.log('ERROR:', error)}
          onExternalPlaybackChange={(e) => console.log('EXTERNAL PLAYBACK:', e)}
          style={styles.backgroundVideo}
          allowsExternalPlayback={true}
          controls={true}
          textTracks={[
            {
              title: 'German',
              uri: 'https://images-cdn.getgalatea.com/subtitles/a1e01f33-4889-4ba1-8fdf-7f676934e05e-105-149-1.srt',
              type: TextTrackType.SUBRIP,
              language: 'de',
            },
          ]}
        />
        <View style={{ position: 'absolute', top: 100, left: 100 }}>
          {isExternalPlaybackAvailable && (
            <>
              <AirplayButton
                prioritizesVideoDevices={true}
                tintColor={'red'}
                activeTintColor={'blue'}
                style={{
                  width: 24,
                  height: 24,
                }}
              />

              <Button title="Custom Button" onPress={() => showRoutePicker({ prioritizesVideoDevices: true })} />
              {routes.length && <Text>Currently playing on {routes.map((route) => route.portName).join(', ')}</Text>}
            </>
          )}
        </View>
      </SafeAreaView>
    </>
  );
};

// Later on in your styles..
const styles = StyleSheet.create({
  backgroundVideo: {
    position: 'absolute',
    top: 0,
    left: 0,
    bottom: 0,
    right: 0,
    zIndex: -1,
  },
});

export default App;
techgerm commented 1 month ago

I found the problem, it's because I'm using textTracks 😞

Screenshot 2024-09-06 at 9 16 40 AM