fix(room): починить чернеющее своё видео в Safari при выключении фона
Safari гасил собственный обходной путь для чёрного кадра — охрана от мерцания в livekit-client сравнивает srcObject с тем же объектом MediaStream, а detach/attach внутри библиотеки промахивался мимо обработанного трека и мутировал поток на месте. Переприцепляем элементы вручную после stopProcessor(), чтобы пересоздать MediaStream и дать защите сработать штатно.
This commit is contained in:
@@ -103,6 +103,22 @@ export function useVirtualBackground(
|
|||||||
if (!track || !desiredUrl) {
|
if (!track || !desiredUrl) {
|
||||||
if (track && processorRef.current) {
|
if (track && processorRef.current) {
|
||||||
await track.stopProcessor()
|
await track.stopProcessor()
|
||||||
|
// Safari-обход: `stopProcessor` внутри livekit-client меняет трек
|
||||||
|
// в элементе «на месте», переиспользуя тот же объект `MediaStream`
|
||||||
|
// (внутренний `detach` промахивается мимо обработанного трека,
|
||||||
|
// который реально висел в элементе). Из-за этого собственная
|
||||||
|
// защита библиотеки от мерцания (`srcObject !== mediaStream` в
|
||||||
|
// `attachToElement`) не даёт сработать её же обходному пути для
|
||||||
|
// чёрного кадра в Safari. Пересоздаём `MediaStream` вручную —
|
||||||
|
// detach обнулит `srcObject`, attach создаст новый объект, защита
|
||||||
|
// пропустит штатный `play()`. Элемент остаётся в своём документе,
|
||||||
|
// никуда не переезжает. Копия массива обязательна: `detach`
|
||||||
|
// правит `attachedElements` по ходу перебора. Уберётся, если
|
||||||
|
// библиотека когда-нибудь починит эту защиту.
|
||||||
|
for (const el of [...track.attachedElements]) {
|
||||||
|
track.detach(el)
|
||||||
|
track.attach(el)
|
||||||
|
}
|
||||||
await processorRef.current.destroy()
|
await processorRef.current.destroy()
|
||||||
processorRef.current = null
|
processorRef.current = null
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user