Agora:ReactNative 没有在视频通话中渲染显示远程用户视频

Posted

技术标签:

【中文标题】Agora:ReactNative 没有在视频通话中渲染显示远程用户视频【英文标题】:Agora: ReactNative is not rendering showing the remote user video in the video call 【发布时间】:2021-06-28 13:56:29 【问题描述】:

我正在使用 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", (uid, 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,
        height: 150,
        marginHorizontal: 2.5
    ,
    noUserText: 
        paddingHorizontal: 10,
        paddingVertical: 5,
        color: '#0093E9',
    ,
)

export default AgoraVideoCall;

当远程视频视图被渲染时,它正在渲染后面的矩形块,如下所示。

我的代码有什么问题,我该如何解决?

【问题讨论】:

你能分享你的控制台日志吗?如果正确,我会说仔细检查传递给 remoteView 的远程 UID。 嗨,我发现了问题。每次用户加入时,uid 都是新的。但是当用户离开并使用新的 id 和令牌再次加入时,之前的会话会保留在那里,而那些块仍然存在。 【参考方案1】:

卸载组件时尝试清除远程 userIds 状态。

【讨论】:

以上是关于Agora:ReactNative 没有在视频通话中渲染显示远程用户视频的主要内容,如果未能解决你的问题,请参考以下文章

Agora 的视频通话布局

agora 支持视频通话铃声吗

Agora WebRTC 更改视频通话视图

Flutter 中的 Agora 视频通话问题

在 Agora 视频通话 SDK 中启动 Unity 应用

如何在flutter中实现agora视频通话邀请