【问题标题】:Agora: ReactNative is not rendering showing the remote user video in the video callAgora:ReactNative 没有在视频通话中渲染显示远程用户视频
【发布时间】: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 和令牌再次加入时,之前的会话会保留在那里,而那些块仍然存在。

标签: android react-native agora.io


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-09
    • 1970-01-01
    • 2020-01-29
    相关资源
    最近更新 更多