-
Notifications
You must be signed in to change notification settings - Fork 49
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Version
v2.0.2
Which operating systems have you used?
- Android
- iOS
Environment that reproduces the issue
Trying to start a stream with the example setup
I have also changed the node modules package to do the post-install patch on RNLiveStreamView.mm
I have also attempted to use facebooks rtmps with my stream key but without any luck.
I've tried different audio/video rates and resolutions without any luck.
Is it reproducible in the example application?
Yes
RTMP Server
rtmp://broadcast.api.video/s
Reproduction steps
// @ts-ignore
import { ApiVideoLiveStreamView } from "@api.video/react-native-livestream";
import { useCameraPermissions, useMicrophonePermissions } from "expo-camera";
import React, { useRef, useState } from "react";
import {
Alert,
Platform,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
export default function Stream() {
const [cameraPermission, requestCameraPermission] = useCameraPermissions();
const [micPermission, requestMicPermission] = useMicrophonePermissions();
const [streaming, setStreaming] = useState(false);
const [camera, setCamera] = useState<"front" | "back">("back");
const [audioMuted, setAudioMuted] = useState(false);
const ref = useRef<any>(null);
const isAndroid = Platform.OS === "android";
const STREAM_KEY = "";
const RTMP_ENDPOINT = `rtmp://broadcast.api.video/s`;
if (!cameraPermission || !micPermission) {
return (
<View style={styles.center}>
<Text style={styles.text}>Checking permissions…</Text>
</View>
);
}
if (!cameraPermission.granted || !micPermission.granted) {
return (
<View style={styles.center}>
<Text style={styles.text}>Camera & microphone access needed</Text>
<TouchableOpacity
style={styles.button}
onPress={async () => {
await requestCameraPermission();
await requestMicPermission();
}}
>
<Text style={styles.buttonText}>Grant Permissions</Text>
</TouchableOpacity>
</View>
);
}
const handleStreaming = (): void => {
if (streaming) {
ref.current?.stopStreaming();
setStreaming(false);
} else {
ref.current
?.startStreaming(STREAM_KEY, RTMP_ENDPOINT)
.then((success: boolean) => {
if (success) {
console.log("Streaming started successfully");
setStreaming(true);
} else {
console.log("Streaming failed to initialize");
setStreaming(false);
}
})
.catch((e: any) => {
console.error("Failed to start streaming: ", e);
Alert.alert("Streaming Error", `Failed to start: ${e.message || e}`);
setStreaming(false);
});
}
};
const handleCamera = (): void => {
if (camera === "back") {
setCamera("front");
} else {
setCamera("back");
}
};
return (
<View style={styles.container}>
<ApiVideoLiveStreamView
style={styles.livestreamView}
ref={ref}
camera={camera}
video={{
bitrate: 500000,
fps: 30,
resolution: "360p",
}}
audio={{
bitrate: 44100,
sampleRate: 48000,
isStereo: true,
}}
isMuted={audioMuted}
enablePinchedZoom={true}
onConnectionSuccess={() => {
console.log("✅ Connection successful");
}}
onConnectionFailed={(reason: string) => {
console.log("❌ Connection failed:", reason);
Alert.alert("Connection Failed", reason);
setStreaming(false);
}}
onDisconnect={() => {
console.log("🔌 Disconnected");
setStreaming(false);
}}
/>
<View style={[styles.buttonContainer, { bottom: isAndroid ? 20 : 40 }]}>
<TouchableOpacity style={styles.streamButton} onPress={handleStreaming}>
<Text style={styles.streamText}>
{streaming ? "Stop Streaming" : "Start Streaming"}
</Text>
</TouchableOpacity>
</View>
<View
style={[
styles.buttonContainer,
{ bottom: isAndroid ? 20 : 40, left: 20 },
]}
>
<TouchableOpacity
style={styles.iconButton}
onPress={() => setAudioMuted(!audioMuted)}
>
<Text style={styles.iconText}>{audioMuted ? "🔇" : "🎤"}</Text>
</TouchableOpacity>
</View>
<View
style={[
styles.buttonContainer,
{ bottom: isAndroid ? 20 : 40, right: 20 },
]}
>
<TouchableOpacity style={styles.iconButton} onPress={handleCamera}>
<Text style={styles.iconText}>🔄</Text>
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "black",
},
livestreamView: {
flex: 1,
backgroundColor: "black",
alignSelf: "stretch",
},
center: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "black",
padding: 20,
},
text: {
color: "white",
fontSize: 16,
textAlign: "center",
marginBottom: 20,
},
button: {
backgroundColor: "#0A84FF",
paddingHorizontal: 30,
paddingVertical: 15,
borderRadius: 25,
},
buttonText: {
color: "white",
fontSize: 16,
fontWeight: "600",
},
buttonContainer: {
position: "absolute",
alignSelf: "center",
},
streamButton: {
backgroundColor: "#0A84FF",
paddingHorizontal: 40,
paddingVertical: 15,
borderRadius: 25,
},
streamText: {
color: "white",
fontSize: 18,
fontWeight: "600",
},
iconButton: {
backgroundColor: "rgba(0,0,0,0.5)",
width: 60,
height: 60,
borderRadius: 30,
justifyContent: "center",
alignItems: "center",
},
iconText: {
fontSize: 24,
},
});
Expected result
Stream starts successfully
Actual result
The app just freezes and crashes soon as i hit start stream.
Additional context
"@api.video/react-native-livestream": "^2.0.2",
"expo": "~54.0.27",
"react-native": "0.81.5",
Relevant logs output
Thread 1: Swift runtime failure: force unwrapped a nil valueReactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working