Setting Up Dependencies
In order to use the LuraPlayer in your React Native Project, you need to first setup your React Native Project. See Quick Start for creating a sample app.
React Native SDK Installation
First step is to install the lura-player-react-native
package from npm.
npm install @akta-tech/lura-player-react-native
Adding fonts for Caption Styling
If you are using expo
Download and extract the fonts to the assets/fonts folder
Install the
expo-font
library
npx expo install expo-font
- Call
useFont
hook from the "expo-font" library for these fonts.
import React, { useRef } from "react";
import { Button, SafeAreaView, StyleSheet, Text } from "react-native";
import { LuraPlayer, type UnifiedPlayer } from "@akta-tech/lura-player-react-native";
import { LuraPlayerControls } from "@akta-tech/lura-player-react-native-ui";
import { useFonts } from "expo-font";
export default function App() {
const [loaded, error] = useFonts({
"Alegreya-Sans-SC": require("./assets/fonts/Alegreya-Sans-SC.ttf"),
"Alegreya-SC": require("./assets/fonts/Alegreya-SC.ttf"),
"Courier-Prime": require("./assets/fonts/Courier-Prime.ttf"),
Dekko: require("./assets/fonts/Dekko.ttf"),
Inter: require("./assets/fonts/Inter.ttf"),
"Petit-Formal-Script": require("./assets/fonts/Petit-Formal-Script.ttf"),
"Roboto-Medium": require("./assets/fonts/Roboto-Medium.ttf"),
"Roboto-Mono": require("./assets/fonts/Roboto-Mono.ttf"),
"Roboto-Regular": require("./assets/fonts/Roboto-Regular.ttf"),
Tinos: require("./assets/fonts/Tinos.ttf"),
});
const playerRef = useRef<UnifiedPlayer>(null);
return (
<SafeAreaView>
<LuraPlayer ref={playerRef} style={styles.player}>
<LuraPlayerControls></LuraPlayerControls>
</LuraPlayer>
<Button
title="Watch Sintel"
onPress={() => {
playerRef.current?.setConfig({
lura: {
appKey: "tqylhUC5n_I4DTH0924LKBxYDTnDmesfzOnHFn3LwUmE4usyMz5rJMjLimCuSH3sSHBjwTX_FNTohzKSBO-zGiD0zHOMGHcg_9OOcvHxDaQ",
assetId: "5179686",
},
controls: {
autoplay: true,
},
});
}}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
player: {
backgroundColor: "#000",
width: "100%",
maxWidth: 640,
aspectRatio: 16 / 9,
},
});
If you are not using additional framework
Download and extract the fonts to the assets/fonts folder
Add fonts to your react-native.config.js
module.exports = {
...
assets: ["./assets/fonts/"],
...
}
- Run the auto linking/unlinking command.
npx react-native-asset
Enabling Screen State Capabilities
To enable Fullscreen and Picture in Picture capabilities in your application, you need to make some modifications.
Picture in Picture Mode Support in Android
To enable Picture-in-Picture (PiP) mode support, you need to make sure that your activity is configured correctly for Android. You need to add supportsPictureInPicture and the following configChanges parameters your app level AndroidManifest.xml:
<activity android:name=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation|keyboardHidden"
...
Since the Picture-in-Picture (PiP) mode on Android is an Activity displayed in a small floating window, you should hide all the UI elements other then the LuraPlayer. LuraPlayerControls will be hidden on Android when pressed on PiP icon for the app to handle the seamless transition. You can listen to
SCREEN_STATE_CHANGED
event to track the current screen state, and adjust the UI accordingly.Please check more about enabling Picture-in-Picture (PiP) mode in Android here
Picture in Picture Mode Support in iOS
To enable Picture-in-Picture (PiP) mode support:
- You should open the ios > YOUR_APP.xcworkspace in XCode.
- Press the YOUR_APP project and go to Build Phases tab.
- Open link binary with libraries section.
- Press
+
icon. - Search for
AVKit.framework
and add it. - Press the YOUR_APP project and go to Signing & Capabilities tab
- On the left side, press the
+ Capability
button, search forBackground Modes
and add it to the project. - After you add Background Modes to the project, check the
Audio, Airplay and Picture in Picture
checkbox.
And you are ready to see picture in picture mode support.
Fullscreen Mode Support
To enable LuraPlayer to support fullscreen mode, a fullscreen state handler should be implemented within the app. The player view itself won't automatically update; instead, it will trigger events that the application must handle to manage fullscreen behavior, allowing the app to define what fullscreen means in the context of its integration with the LuraPlayer library.
Here is a sample implementation:
import React, { useRef, useEffect, useState } from "react";
import { Button, SafeAreaView, StyleSheet, Text, View } from "react-native";
import { LuraPlayer, ScreenState, UnifiedEventName, type UnifiedPlayer } from "@akta-tech/lura-player-react-native";
import { LuraPlayerControls } from "@akta-tech/lura-player-react-native-ui";
export default function App() {
const playerRef = useRef<UnifiedPlayer>(null);
const [isPlayerFullscreen, setIsPlayerFullscreen] = useState<boolean>(false);
useEffect(() => {
if (!playerRef.current) return;
const listenerId = playerRef.current.addListener((e) => {
switch (e.type) {
case UnifiedEventName.SCREEN_STATE_CHANGED:
switch (e.data.state) {
case ScreenState.FULLSCREEN:
// You need to handle your fullscreen behaviour here
// You can hide the navigation bars, status bars, top/bottom bars
// home indicator etc.
//
// If your app prefers landscape mode during fullscreen
// you can use third party libraries like "react-native-orientation-locker"
// and "react-native-system-navigation-bar" or you can write a Turbo Module,
// and call the locking method from your Turbo Module.
setIsPlayerFullscreen(true);
break;
case ScreenState.PICTURE_IN_PICTURE:
setIsPlayerFullscreen(false);
break;
case ScreenState.WINDOWED:
setIsPlayerFullscreen(false);
break;
}
break;
}
});
return () => {
playerRef.current?.removeListener(listenerId);
};
}, [playerRef]);
return (
<View>
<SafeAreaView />
<LuraPlayer
ref={playerRef}
style={
// Apply style based on `isPlayerFullscreen` state value
isPlayerFullscreen ? styles.playerFullscreen : styles.player
}>
<LuraPlayerControls></LuraPlayerControls>
</LuraPlayer>
{/* Hide the rest of the components if fullscreen */}
{!isPlayerFullscreen && (
<Button
title="Watch Sintel"
onPress={() => {
playerRef.current?.setConfig({
lura: {
appKey: "tqylhUC5n_I4DTH0924LKBxYDTnDmesfzOnHFn3LwUmE4usyMz5rJMjLimCuSH3sSHBjwTX_FNTohzKSBO-zGiD0zHOMGHcg_9OOcvHxDaQ",
assetId: "5179686",
},
controls: {
autoplay: true,
},
});
}}
/>
)}
</View>
);
}
const styles = StyleSheet.create({
player: {
backgroundColor: "#000",
width: "100%",
maxWidth: 640,
aspectRatio: 16 / 9,
},
playerFullscreen: {
backgroundColor: "#000",
position: "absolute",
zIndex: Number.MAX_SAFE_INTEGER,
elevation: Platform.OS === "android" ? 50 : 0,
top: 0,
right: 0,
bottom: 0,
left: 0,
width: "100%",
height: "100%",
},
});