LiveKit React Native SDK双客户端音视频流收发异常问题
LiveKit React Native 音视频收发异常问题
问题描述
基于LiveKit示例App开发,已实现示例全部功能,成功连接到https://example.livekit.io/房间,能接收网页端音频,但无法读取视频流,也完全无法发送音频或视频。
重现步骤
- 在
index.js中添加以下代码:
import { registerRootComponent } from "expo"; import { registerGlobals } from "livekit-react-native"; import App from "./App"; registerRootComponent(App); registerGlobals();
- 在
App.tsx中渲染以下组件(仅移除了屏幕共享和消息逻辑,其余与示例一致):
import { Participant, Room, Track } from "livekit-client"; import { useRoom, useParticipant, AudioSession, VideoView, } from "livekit-react-native"; import { useEffect, useState } from "react"; import { Text, ListRenderItem, StyleSheet, FlatList, View } from "react-native"; import { ParticipantView } from "./ParticipantView"; import { RoomControls } from "./RoomControls"; import type { TrackPublication } from "livekit-client"; const App = () => { // Create a room state const [, setIsConnected] = useState(false); const [room] = useState( () => new Room({ publishDefaults: { simulcast: false }, adaptiveStream: true, }) ); // Get the participants from the room const { participants } = useRoom(room); const url = "[hard-coded-url]"; const token = "[hard-coded-token]"; useEffect(() => { let connect = async () => { // If you wish to configure audio, uncomment the following: await AudioSession.configureAudio({ android: { preferredOutputList: ["speaker"], }, ios: { defaultOutput: "speaker", }, }); await AudioSession.startAudioSession(); await room.connect(url, token, {}); await room.localParticipant.setCameraEnabled(true); await room.localParticipant.setMicrophoneEnabled(true); await room.localParticipant.enableCameraAndMicrophone(); console.log("connected to ", url); setIsConnected(true); }; connect(); return () => { room.disconnect(); AudioSession.stopAudioSession(); }; }, [url, token, room]); // Setup views. const stageView = participants.length > 0 && ( <ParticipantView participant={participants[0]} style={styles.stage} /> ); const renderParticipant: ListRenderItem<Participant> = ({ item }) => { return ( <ParticipantView participant={item} style={styles.otherParticipantView} /> ); }; const otherParticipantsView = participants.length > 0 && ( <FlatList data={participants} renderItem={renderParticipant} keyExtractor={(item) => item.sid} horizontal={true} style={styles.otherParticipantsList} /> ); const { cameraPublication, microphonePublication } = useParticipant( room.localParticipant ); return ( <View style={styles.container}> {stageView} {otherParticipantsView} <RoomControls micEnabled={isTrackEnabled(microphonePublication)} setMicEnabled={(enabled: boolean) => { room.localParticipant.setMicrophoneEnabled(enabled); }} cameraEnabled={isTrackEnabled(cameraPublication)} setCameraEnabled={(enabled: boolean) => { room.localParticipant.setCameraEnabled(enabled); }} onDisconnectClick={() => { // navigation.pop(); console.log("disconnected"); }} /> </View> ); }; function isTrackEnabled(pub?: TrackPublication): boolean { return !(pub?.isMuted ?? true); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: "center", justifyContent: "center", }, stage: { flex: 1, width: "100%", }, otherParticipantsList: { width: "100%", height: 150, flexGrow: 0, }, otherParticipantView: { width: 150, height: 150, }, }); export default App;
- 使用Expo开发构建运行应用
- 日志显示已连接,能听到远端参与者声音,但看不到视频,也无法发送任何声音
- 若在
useEffect中添加await room.localParticipant.enableCameraAndMicrophone();,会抛出以下错误:
Possible Unhandled Promise Rejection (id: 0): Error: Not implemented. getSettings@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:103733:24 @http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:120307:109 generatorResume@[native code] asyncGeneratorStep@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21908:26 _next@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21927:29 @http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21932:14 tryCallTwo@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26656:9 doResolve@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26788:25 Promise@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26675:14 @http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21924:25 @http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:120173:52 generatorResume@[native code] asyncGeneratorStep@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21908:26 _next@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21927:29 tryCallOne@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26648:16 @http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:26729:27 @http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27687:26 _callTimer@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27602:17 _callReactNativeMicrotasksPass@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27635:17 callReactNativeMicrotasks@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:27799:44 __callReactNativeMicrotasks@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:21006:46 @http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20806:45 __guard@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20986:15 flushedQueue@http://192.168.1.150:8081/index.bundle?platform=ios&dev=true&hot=false:20805:21 flushedQueue@[native code]
预期行为
双客户端之间应能正常收发音视频流
解决方案
移除
enableCameraAndMicrophone()调用
这个方法在LiveKit React Native SDK中并未实现(从报错信息Error: Not implemented可确认),你已经调用了setCameraEnabled(true)和setMicrophoneEnabled(true),这两个方法已经足够启用本地音视频设备并发布流,无需额外调用enableCameraAndMicrophone()。检查权限配置
Expo环境下需要确保已配置相机和麦克风权限:- 在
app.json中添加权限声明:"ios": { "infoPlist": { "NSCameraUsageDescription": "需要访问相机进行视频通话", "NSMicrophoneUsageDescription": "需要访问麦克风进行语音通话" } }, "android": { "permissions": ["CAMERA", "RECORD_AUDIO"] } - 在代码中主动请求权限:
import * as Permissions from 'expo-permissions'; // 在connect函数开头添加权限请求 const { status: cameraStatus } = await Permissions.askAsync(Permissions.CAMERA); const { status: micStatus } = await Permissions.askAsync(Permissions.MICROPHONE); if (cameraStatus !== 'granted' || micStatus !== 'granted') { alert('需要授予相机和麦克风权限才能使用'); return; }
- 在
修复远端视频不显示问题
确保ParticipantView组件正确渲染远端视频轨道:// ParticipantView示例实现 import { VideoView } from 'livekit-react-native'; import { useParticipant } from 'livekit-react-native'; export const ParticipantView = ({ participant, style }) => { const { videoTrack } = useParticipant(participant); return videoTrack ? ( <VideoView track={videoTrack} style={style} /> ) : null; };调整Room配置
建议开启simulcast(移动端默认支持),优化视频发布配置:new Room({ publishDefaults: { simulcast: true }, adaptiveStream: true, })
内容的提问来源于stack exchange,提问作者Alaa Mady
相关产品推荐
相关产品推荐

