视频会议
This commit is contained in:
@@ -117,49 +117,74 @@ const resolveDom = (refValue) => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const applyVideo = () => {
|
// 当前已经贴到 video / audio 元素上的 track,用于幂等判断,避免重复 setSrcObject 触发闪烁
|
||||||
|
let boundVideoTrack = null
|
||||||
|
let boundAudioTrack = null
|
||||||
|
|
||||||
|
const applyVideo = (retry = 0) => {
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
if (props.videoTrack && props.videoEnabled) {
|
if (props.videoTrack && props.videoEnabled) {
|
||||||
|
const parent = resolveDom(mediaBox.value)
|
||||||
|
if (!parent) {
|
||||||
|
// DOM 尚未挂载,最多重试 10 次(≈500ms)
|
||||||
|
if (retry < 10) {
|
||||||
|
setTimeout(() => applyVideo(retry + 1), 50)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
const el = ensureMediaEl('video')
|
const el = ensureMediaEl('video')
|
||||||
if (el) {
|
if (!el) return
|
||||||
el.muted = props.isLocal
|
el.muted = props.isLocal
|
||||||
|
if (boundVideoTrack !== props.videoTrack) {
|
||||||
el.srcObject = new MediaStream([props.videoTrack])
|
el.srcObject = new MediaStream([props.videoTrack])
|
||||||
|
boundVideoTrack = props.videoTrack
|
||||||
|
}
|
||||||
const playPromise = el.play && el.play()
|
const playPromise = el.play && el.play()
|
||||||
if (playPromise && typeof playPromise.catch === 'function') {
|
if (playPromise && typeof playPromise.catch === 'function') {
|
||||||
playPromise.catch(() => {})
|
playPromise.catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
removeMediaEl('video')
|
removeMediaEl('video')
|
||||||
|
boundVideoTrack = null
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const applyAudio = () => {
|
const applyAudio = (retry = 0) => {
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
// 本地 tile 不挂载 audio(避免回声)
|
// 本地 tile 不挂载 audio(避免回声)
|
||||||
if (!props.isLocal && props.audioTrack && props.audioEnabled) {
|
if (!props.isLocal && props.audioTrack && props.audioEnabled) {
|
||||||
|
const parent = resolveDom(mediaBox.value)
|
||||||
|
if (!parent) {
|
||||||
|
if (retry < 10) {
|
||||||
|
setTimeout(() => applyAudio(retry + 1), 50)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
const el = ensureMediaEl('audio')
|
const el = ensureMediaEl('audio')
|
||||||
if (el) {
|
if (!el) return
|
||||||
|
if (boundAudioTrack !== props.audioTrack) {
|
||||||
el.srcObject = new MediaStream([props.audioTrack])
|
el.srcObject = new MediaStream([props.audioTrack])
|
||||||
|
boundAudioTrack = props.audioTrack
|
||||||
|
}
|
||||||
const playPromise = el.play && el.play()
|
const playPromise = el.play && el.play()
|
||||||
if (playPromise && typeof playPromise.catch === 'function') {
|
if (playPromise && typeof playPromise.catch === 'function') {
|
||||||
playPromise.catch(() => {})
|
playPromise.catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
removeMediaEl('audio')
|
removeMediaEl('audio')
|
||||||
|
boundAudioTrack = null
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => [props.videoTrack, props.videoEnabled], () => nextTick(applyVideo), { immediate: true })
|
watch(() => [props.videoTrack, props.videoEnabled], () => nextTick(() => applyVideo()), { immediate: true })
|
||||||
watch(() => [props.audioTrack, props.audioEnabled, props.isLocal], () => nextTick(applyAudio), { immediate: true })
|
watch(() => [props.audioTrack, props.audioEnabled, props.isLocal], () => nextTick(() => applyAudio()), { immediate: true })
|
||||||
|
|
||||||
// 修复刚进入会议时画面不显示问题:
|
// 修复刚进入会议时画面不显示、必须点切换才出图的问题:
|
||||||
// watch 的 immediate:true 在 setup 阶段就触发 applyVideo,此时 mediaBox ref 尚未绑定真实 DOM;
|
// 1) watch 的 immediate:true 在 setup 阶段就触发 applyVideo,此时 mediaBox ref 尚未绑定真实 DOM;
|
||||||
// 即便包了 nextTick,在 uni-h5 偶发条件下仍可能命中 ref 未就绪,导致 srcObject 没贴上。
|
// 2) 即便包了 nextTick,在 uni-h5 下 ref 偶发未就绪;
|
||||||
// 这里在 onMounted 里再补一次绑定,确保 DOM ready 后必然挂上 track。
|
// 现在 applyVideo/applyAudio 在 DOM 未就绪时会自动重试,并在 onMounted 再强制兜底一次。
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
applyVideo()
|
applyVideo()
|
||||||
|
|||||||
Reference in New Issue
Block a user