如何解决Agora:ReactNative 未渲染显示视频通话中的远程用户视频
我正在使用 ReactNative 构建群组视频聊天应用程序。对于视频通话,我使用 Agora for ReactNative,https://www.npmjs.com/package/react-native-agora。但是远程用户视频显示黑块。
这是我的代码。
const agoraAppId = "xxx";
const channelName = "myChannel";
const cerfificateKey = "xxxxx";
const token = "xxxxx";
import React,{ useEffect,useState } from 'react';
import { View,Text,StyleSheet,Dimensions,PermissionsAndroid,Button,ScrollView } from 'react-native';
import RtcEngine,{RtcLocalView,RtcRemoteView,VideoRenderMode} from 'react-native-agora'
const dimensions = {
width: Dimensions.get('window').width,height: Dimensions.get('window').height,}
//https://docs.agora.io/en/Video/start_call_react_native?platform=React%20Native
//TODO: pass the id from the previous screen
const AgoraVideoCall = (props) => {
let engine = null;
const userId = props.route.params.userId;
const [ initialised,setInitialised ] = useState(false);
const [ joinedChannel,setJoinedChannel ] = useState(false);
const [ engineInitialised,setEngineInitialised ] = useState(false);
const [ userIds,setUserIds ] = useState([ ]);
const requestCameraAndAudioPermission = async () => {
try {
const granted = await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.CAMERA,PermissionsAndroid.PERMISSIONS.RECORD_AUDIO
])
if (
granted['android.permission.RECORD_AUDIO'] === PermissionsAndroid.RESULTS.GRANTED
&& granted['android.permission.CAMERA'] === PermissionsAndroid.RESULTS.GRANTED
) {
console.log('You can use the cameras & mic')
} else {
console.log('Permission denied')
}
} catch (err) {
console.log(err);
}
}
const startCall = async () => {
try {
if (engine == null) {
await initialiseEngine()
}
await engine.joinChannel(token,channelName,null,userId)
console.log("StartCall is run")
} catch (err) {
console.log("StartCall throws error")
console.log(engine)
console.log(err)
}
}
const initialiseEngine = async () => {
try {
engine = await RtcEngine.create(agoraAppId);
console.log("Engine initiaised");
setEngineInitialised(true)
} catch (err) {
console.log("Unable to initialise engine");
console.log(err);
setEngineInitialised(false)
}
}
const setUpMeeting = async () => {
await engine.enableVideo();
engine.addListener("UserJoined",(uid,elapsed) => {
console.log(`User has joined,${uid}`);
if (uid != userId && userIds.filter(id => id == uid).length < 1) {
let tempUserIds = [ ...userIds ]
tempUserIds.push(uid);
setUserIds(tempUserIds);
console.log(`User ids have been updated`);
}
})
engine.addListener("UserOffline",reason) => {
console.log("User has gone offline");
})
engine.addListener("JoinChannelSuccess",(channel,uid,elapsed) => {
console.log(`Successfully joined the channel,${channel},${uid}`);
setJoinedChannel(true);
})
setInitialised(true)
}
useEffect(() => {
requestCameraAndAudioPermission()
.then(() => {
initialiseEngine()
.then(result => {
setUpMeeting()
})
})
},[ ])
const renderVideos = () => {
if (! joinedChannel) {
return null
}
return (
<View style={styles.fullView}>
<RtcLocalView.SurfaceView
style={styles.max}
channelId={channelName}
renderMode={VideoRenderMode.Hidden} />
{renderRemoteVideos()}
</View>
)
}
const renderRemoteVideos = () => {
if (userIds.length < 1) {
return null;
}
return (
<ScrollView
style={styles.remoteContainer}
contentContainerStyle={{paddingHorizontal: 2.5}}
horizontal={true}
>
{userIds.map((id,index) => {
return (
<RtcRemoteView.SurfaceView
key={index}
style={styles.remote}
channelId={channelName}
renderMode={VideoRenderMode.Hidden}
uid={id}
zOrderMediaOverlay={true}
/>
)
})}
</ScrollView>
)
}
const renderStartCallButton = () => {
if (joinedChannel) {
return null;
}
return (
<View style={styles.actionButton}>
<Button
title={"Start Call"}
onPress={() => {
startCall()
}}
/>
</View>
)
}
const leaveChannel = async () => {
try {
if (engine ==null) {
await initialiseEngine()
}
await engine.leaveChannel()
setJoinedChannel(false)
} catch (err) {
console.log("Unable to leave the channel")
console.log(engine)
console.log(err)
}
}
const renderLeaveChannelButton = () => {
if (! joinedChannel) {
return null
}
return (
<View style={styles.actionButton}>
<Button
title={"Leave Channel"}
onPress={() => {
leaveChannel()
}}
/>
</View>
)
}
const renderContent = () => {
if (!engineInitialised) {
return <Text>Initializing the Agora engine</Text>
}
if (! initialised) {
return <Text>Initializing the meeting</Text>
}
if (joinedChannel) {
return (
<View style={styles.max}>
<View style={styles.actionButtonsContainer}>
{renderLeaveChannelButton()}
</View>
<View style={styles.max}>
{renderVideos()}
</View>
</View>
)
}
return (
<View>
<View style={styles.actionButtonsContainer}>
{renderStartCallButton()}
</View>
</View>
)
}
return (
<View style={styles.container}>
<ScrollView>
{renderContent()}
</ScrollView>
</View>
)
}
const styles = StyleSheet.create({
container: {
justifyContent: "center",alignItems: "center",flex: 1
},actionButtonsContainer: {
flexDirection: "row"
},actionButton: {
padding: 10
},max: {
flex: 1,},buttonHolder: {
height: 100,alignItems: 'center',flex: 1,flexDirection: 'row',justifyContent: 'space-evenly',button: {
paddingHorizontal: 20,paddingVertical: 10,backgroundColor: '#0093E9',borderRadius: 25,buttonText: {
color: '#fff',fullView: {
width: dimensions.width,height: dimensions.height - 100,remoteContainer: {
width: '100%',height: 150,position: 'absolute',top: 5
},remote: {
width: 150,marginHorizontal: 2.5
},noUserText: {
paddingHorizontal: 10,paddingVertical: 5,color: '#0093E9',})
export default AgoraVideoCall;
渲染远程视频视图时,渲染后面的矩形块如下。
我的代码有什么问题,我该如何修复?
解决方法
尝试在卸载组件时清除远程 userIds 状态。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。