You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复Android端React Native AWS Chime RNVideoView层级覆盖问题

React Native AWS Chime SDK 安卓端本地视频小窗口被远程视频遮挡问题

我基于React Native实现了AWS Chime SDK的双人视频通话Demo,预期效果是本地设备视频以小窗口固定在屏幕底部右侧,远程设备视频全屏显示,且本地窗口始终处于上层。但在Android设备上,当双方都开启视频后,远程视频会直接覆盖本地小窗口,只有重启本地视频才能恢复显示,这个问题在iOS端完全不存在。

相关代码

视频Tile状态监听代码

const [localDevice, setLocalDevice] = useState({
    videoEnabled: false,
    videoTileId: null
})
const [remoteDevice, setRemoteDevice] = useState({
    videoEnabled: false,
    videoTileId: null
})

// ON ATTENDEE START VIDEO
useEffect(()=>{
    onAddVideoTileSubscription.current = getSDKEventEmitter().addListener(
        MobileSDKEvent.OnAddVideoTile,
        tileState => {
            if(tileState.isLocal){
                setLocalDevice({
                    videoEnabled: true,
                    videoTileId: tileState.tileId
                })
            }else if(!tileState.isLocal){
                setRemoteDevice({
                    videoEnabled: true,
                    videoTileId: tileState.tileId
                })
            }
        },
    );
    return () => {
        if (onAddVideoTileSubscription.current) {
            onAddVideoTileSubscription.current.remove();
        }
    };
},[])

// ON ATTENDEE END VIDEO
useEffect(()=>{
    onRemoveVideoTileSubscription.current = getSDKEventEmitter().addListener(
        MobileSDKEvent.OnRemoveVideoTile,
        tileState => {
            if(tileState.isLocal){
                setLocalDevice({
                    videoEnabled: false,
                    videoTileId: tileState.tileId
                })
            }else if(!tileState.isLocal){
                setRemoteDevice({
                    videoEnabled: false,
                    videoTileId: tileState.tileId
                })
            }
        },
    );
    return () => {
        if (onRemoveVideoTileSubscription.current) {
            onRemoveVideoTileSubscription.current.remove();
        }
    };
},[])

渲染逻辑代码

return (
    <View style={styles.callContainer}>
        {remoteDevice.videoEnabled ? (
            <View style={styles.remoteDeviceVideoContainer}>
                <RNVideoRenderView
                    style={styles.remoteDeviceVideo}
                    key={remoteDevice.videoTileId}
                    tileId={remoteDevice.videoTileId}
                />
            </View>
        ): (
            null
        )}
        {localDevice.videoEnabled ? (
            <View style={styles.localDeviceVideoContainer}>
                <RNVideoRenderView
                    style={styles.localDeviceVideo}
                    key={localDevice.videoTileId}
                    tileId={localDevice.videoTileId}
                />
            </View>
        ): (
            null
        )}
        <FlatList
            style={styles.attendeeList}
            data={state.attendees}
            renderItem={({item}) => (
                <AttendeeItem
                    attendeeName={
                        attendeeNameMap[item] ? attendeeNameMap[item] : item
                    }
                    muted={state.mutedAttendee.includes(item)}
                />
            )}
            ItemSeparatorComponent={() => <View style={styles.separator} />}
            keyExtractor={item => item}
        />

        <View style={styles.buttonContainer}>
            <MuteButton
                muted={currentMuted}
                onPress={() => NativeFunction.setMute(!currentMuted)}
            />
            <CameraButton
                disabled={localDevice.videoEnabled}
                onPress={() =>
                    NativeFunction.setCameraOn(!localDevice.videoEnabled)
                }
            />
            <View style={styles.hangOffButtonContainer}>
                <HangOffButton onPress={() => NativeFunction.stopMeeting()} />
            </View>
        </View>
    </View>
);

样式代码

callContainer:{
    backgroundColor: '#1D1D1D',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
    justifyContent: 'flex-start'
},
localDeviceVideoContainer:{
    position: 'absolute',
    bottom: 100,
    right: 15,
    height: 175,
    width: 132,
    zIndex: 1,
    elevation: 1,
},
localDeviceVideo:{
    height: '100%',
    width: '100%'
},
remoteDeviceVideoContainer:{
    height: '100%',
    width: '100%',
    backgroundColor:'pink',
},
remoteDeviceVideo:{
    width: '100%',
    height: '100%',
},

已尝试的解决方案

  • 交换远程视频和本地视频组件的渲染顺序,确保本地组件在后面渲染
  • 给本地视频容器设置zIndex和elevation属性,强制提升层级
  • 将远程视频透明度设置为0,确认本地窗口是被遮挡而非未渲染

有没有人遇到过AWS Chime SDK的这个安卓端层级问题?

内容的提问来源于stack exchange,提问作者Dylon Jaynes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 16:44:57