关闭 WebRTC 轨道不会关闭相机设备或标签相机指示器

问题描述

用这个把我的头撞到墙上,我似乎无法理解相机视频流上的内容以及在 MediaStreamTrack.stop() 调用时没有关闭内容

我有一个打字稿类,我在其中处理获取 WebRTC 流轨道并使用可观察事件将其传递给功能性 reactjs 组件,下面的代码是组件注册到事件并使用流轨道的状态。

const [videoStreamTrack,setVideoStreamTrack] = useState < MediaStreamTrack > (
    null
)

useEffect(() => {
    return () => {
        videoStreamTrack?.stop()
        videoElement.current.srcObject.getVideoTracks().forEach((track) => {
            track.stop()
            videoElement.current.srcObject.removeTrack(track)
        })
        videoElement.current.srcObject = null
    }
},[])

case RoomEvents.WebcamProducerAdded:
case RoomEvents.VideoStreamReplaced: {
  if (result.data?.track) {
      if (result.data.track.kind === 'video') {
        previewVideoStreamTrack?.stop()
        setPreviewVideoStreamTrack(null)
        setVideoStreamTrack(result.data.track)
      }
    }
  break
}

在“房间”类中,我使用以下代码获取流。

const videoDevice = this.webcam.device
if (!videoDevice) {
    throw new Error('no webcam devices')
}

const userMedia = await navigator.mediaDevices.getUserMedia({
    video: this.environmentPlatformService.isMobile ?
        true : {
            deviceid: {
                exact: this.webcam.device.deviceid
            },...VIDEO_CONSTRAINS[this.webcam.resolution],},})

const videoTrack = userMedia.getVideoTracks()[0]

this.eventSubject.next({
    eventName: RoomEvents.WebcamProducerAdded,data: {
        track: videoTrack,})

我保留使用以下代码this.webcam.device 详细信息。

async updateInputOutputMediaDevices(): Promise < MediaDeviceInfo[] > {
    await navigator.mediaDevices.getUserMedia({
        audio: true,video: true
    })
    const devices = await navigator.mediaDevices.enumerateDevices()
    await this.updateWebcams(devices)
    await this.updateAudioInputs(devices)
    await this.updateAudioOutputs(devices)
    return devices
}

private async updateWebcams(devices: MediaDeviceInfo[]) {
    this.webcams = new Map < string,MediaDeviceInfo > ()

    for (const device of devices.filter((d) => d.kind === 'videoinput')) {
        this.webcams.set(device.deviceid,device)
    }

    const array = Array.from(this.webcams.values())

    this.eventSubject.next({
        eventName: RoomEvents.CanChangeWebcam,data: {
            canChangeWebcam: array.length > 1,mediaDevices: array,})
}

刷新页面关闭相机和标签指示器。

解决方法

useEffect(() => {
    return () => {
        videoStreamTrack?.stop()
        videoElement.current.srcObject.getVideoTracks().forEach((track) => {
            track.stop()
            videoElement.current.srcObject.removeTrack(track)
        })
        videoElement.current.srcObject = null
    }
},[])

因此,您正在搜索和销毁视频轨道。似乎是正确的;我们会看到

async updateInputOutputMediaDevices(): Promise < MediaDeviceInfo[] > {
    await navigator.mediaDevices.getUserMedia({
        audio: true,video: true
    })
    const devices = await navigator.mediaDevices.enumerateDevices()
    await this.updateWebcams(devices)
    await this.updateAudioInputs(devices)
    await this.updateAudioOutputs(devices)
    return devices
}

上面我看到有音频呼叫可能是打嗝的地方?不能过度检查,但也许您同时打开并关闭视频?尝试循环播放所有曲目,而不仅仅是视频,看看有什么?

,

@blanknamefornow 的回答帮助我解决了这个问题。

  1. 我们不仅在 处理 mediasoup 动作的“房间”类也很重要 预览/设备选择/等并没有真正关闭 检索到的曲目。
  2. 有时,这些音轨会保存在 useState 中 变量和组件卸载时,如果您尝试访问 变量它们已经被 reactjs 清零了。解决方法是 因为 HTML 元素仍然被引用,所以当 需要。我相信这是尝试时缺少的成分 想办法。