如何修复 React Native Chime RNVideoView 显示在其他 RNVideoView 上的问题

问题描述 投票:0回答:1

我获得了适用于 React Native 的 AWS Chime SDK 演示,两个人可以在移动设备上加入视频通话。本地设备的摄像机显示在屏幕底部的小图块中,而远程设备占据整个屏幕,本地图块位于其顶部。但是,我注意到,在 Android 上,当您启动本地视频,然后从其他设备启动本地视频时,来自远程设备的视频会覆盖 Android 本地磁贴。 Android 设备可以通过停止并再次启动视频来恢复本地图块,但它一开始就不应该消失。

这是我的视频磁贴状态更改事件的侦听器:

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 没有任何变化。我确信该图块出现在全屏视频后面,因为我将全屏视频的不透明度设置为 0 并看到了它后面的组件。我知道它在 iOS 设备上运行得很好,而且小图块会留在前台。我已经尝试了很多方法来使其发挥作用,但不知道发生了什么。有人处理过这个 AWS Chime SDK 问题吗?

javascript android amazon-web-services react-native aws-chime-sdk
1个回答
0
投票

我想为其他可能遇到 Chime SDK RNVideoViews 重叠时行为不按预期问题的人回答我自己的问题。

发现即使我将远程图块不透明度设置为 0 并看到另一个图块,它实际上不是在远程图块的后面而是在远程图块的顶部。它似乎消失了,但实际上就像在本地图块上打了一个洞,显示远程设备摄像头的视频源。事实证明,AWS DefaultVideoRenderView 使用的底层视图 SurfaceView 不能与其他 SurfaceView 很好地配合,除非您在希望始终位于顶部的 SurfaceView 上设置

"setZOrderOnTop(true)"
在 Android 中支持多个活动重叠表面视图

将其以及 zindex 设置为 1 后,视图的行为符合预期。在 Android 和 iOS 上,小型本地设备图块显示在全屏远程设备视频图块上。

© www.soinside.com 2019 - 2024. All rights reserved.