关闭 WebRTC 轨道不会关闭摄像头设备或标签摄像头指示器
Closing WebRTC track will not close camera device or tab camera indicator
用这个把我的头撞到墙上,我似乎无法理解在 MediaStreamTrack.stop()
调用时相机视频流上有什么并且没有关闭。
我有一个打字稿class,我在其中处理获取 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
}
在“房间”中class我使用下面的代码来抓取流。
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 的回答帮助我解决了这个问题。
- 我们不仅在
“room” class 处理 mediasoup 动作,但也 fore
preview/device-selection/etc 并没有真正关闭
检索到曲目。
- 有时,这些曲目会保留在 useState 中
如果您尝试访问变量和卸载组件的时间
变量它们已经被 reactjs 清空了。解决方法是
因为 HTML 元素仍然被引用,所以当
需要。我相信这是尝试时缺少的成分
搞清楚。
用这个把我的头撞到墙上,我似乎无法理解在 MediaStreamTrack.stop()
调用时相机视频流上有什么并且没有关闭。
我有一个打字稿class,我在其中处理获取 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
}
在“房间”中class我使用下面的代码来抓取流。
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 的回答帮助我解决了这个问题。
- 我们不仅在 “room” class 处理 mediasoup 动作,但也 fore preview/device-selection/etc 并没有真正关闭 检索到曲目。
- 有时,这些曲目会保留在 useState 中 如果您尝试访问变量和卸载组件的时间 变量它们已经被 reactjs 清空了。解决方法是 因为 HTML 元素仍然被引用,所以当 需要。我相信这是尝试时缺少的成分 搞清楚。