fix(room): в Chrome пропадал звук после возврата из мини-окна
RoomAudioRenderer жил внутри RoomStage и рендерился дважды — в ветке variant="pip" и в основной. При открытии Document PiP сцена размонтируется в основном окне и монтируется в PiP-окне, поэтому скрытые <audio> с чужими аудиотреками физически переезжали в ДРУГОЙ документ, а при возврате — обратно. После такого переезда Chrome теряет аудиовыход у remote-трека: пакеты продолжают приходить (packetsReceived растёт), но totalSamplesDuration и totalAudioEnergy замирают, и трек молчит даже в свежесозданном <audio> со свежим MediaStream. Тот же цикл detach/attach в пределах одного документа безвреден — дело именно в переезде между документами. В Safari бага не было: там Document PiP не используется (video-фолбэк), сцена остаётся в основном окне. Рендерер вынесен в RoomPage — один экземпляр, всегда в основном документе. В PiP-окне аудиоэлементов теперь нет вовсе, цикл «открыл мини-окно → вернул» их не касается.
This commit is contained in:
@@ -4,7 +4,6 @@ import { Track, type Participant } from 'livekit-client'
|
|||||||
import {
|
import {
|
||||||
CarouselLayout,
|
CarouselLayout,
|
||||||
FocusLayoutContainer,
|
FocusLayoutContainer,
|
||||||
RoomAudioRenderer,
|
|
||||||
isTrackReference,
|
isTrackReference,
|
||||||
useRoomContext,
|
useRoomContext,
|
||||||
useSpeakingParticipants,
|
useSpeakingParticipants,
|
||||||
@@ -400,7 +399,6 @@ export function RoomStage({
|
|||||||
<section className="stage room-single-tile">
|
<section className="stage room-single-tile">
|
||||||
{focusTrack && <RoomParticipantTile trackRef={focusTrack} onStopSharing={handleStopSharing} />}
|
{focusTrack && <RoomParticipantTile trackRef={focusTrack} onStopSharing={handleStopSharing} />}
|
||||||
<PipMicToggle />
|
<PipMicToggle />
|
||||||
<RoomAudioRenderer />
|
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -496,7 +494,6 @@ export function RoomStage({
|
|||||||
<span>Показать остальных ({sideTracks.length})</span>
|
<span>Показать остальных ({sideTracks.length})</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<RoomAudioRenderer />
|
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|||||||
import { createPortal } from 'react-dom'
|
import { createPortal } from 'react-dom'
|
||||||
import { useLocation, useNavigate, useParams } from 'react-router-dom'
|
import { useLocation, useNavigate, useParams } from 'react-router-dom'
|
||||||
import { PictureInPicture2 } from 'lucide-react'
|
import { PictureInPicture2 } from 'lucide-react'
|
||||||
import { LiveKitRoom, usePersistentUserChoices } from '@livekit/components-react'
|
import { LiveKitRoom, RoomAudioRenderer, usePersistentUserChoices } from '@livekit/components-react'
|
||||||
import type { RoomOptions } from 'livekit-client'
|
import type { RoomOptions } from 'livekit-client'
|
||||||
import '@livekit/components-styles'
|
import '@livekit/components-styles'
|
||||||
import '@/styles/room.css'
|
import '@/styles/room.css'
|
||||||
@@ -285,6 +285,21 @@ export function RoomPage() {
|
|||||||
options={roomOptions}
|
options={roomOptions}
|
||||||
onDisconnected={handleDisconnected}
|
onDisconnected={handleDisconnected}
|
||||||
>
|
>
|
||||||
|
{/* Звук комнаты рендерится ЗДЕСЬ, а не внутри `RoomStage`, и ровно
|
||||||
|
одним экземпляром на всю страницу. `RoomAudioRenderer` — это набор
|
||||||
|
скрытых `<audio>`, к которым LiveKit привязывает чужие аудиотреки
|
||||||
|
(`track.attach(el)`). Пока он жил в сцене, открытие мини-плеера
|
||||||
|
переносило эти элементы в ДРУГОЙ документ (Document PiP — отдельное
|
||||||
|
окно со своим `document`), а возврат — обратно, и после возврата
|
||||||
|
звук чужих участников пропадал: Chrome теряет аудиовыход у
|
||||||
|
remote-трека, переехавшего между документами. Замерено: пакеты
|
||||||
|
продолжают приходить (`packetsReceived` растёт), а
|
||||||
|
`totalSamplesDuration`/`totalAudioEnergy` замирают, и трек молчит
|
||||||
|
даже в свежесозданном `<audio>` со свежим `MediaStream`. Тот же
|
||||||
|
цикл detach/attach В ПРЕДЕЛАХ ОДНОГО документа безвреден — дело
|
||||||
|
именно в переезде. Здесь элементы живут в основном документе
|
||||||
|
непрерывно, весь цикл «открыл мини-окно → вернул» их не касается. */}
|
||||||
|
<RoomAudioRenderer />
|
||||||
<div data-lk-theme="default" className="room-shell">
|
<div data-lk-theme="default" className="room-shell">
|
||||||
<RoomTopbar title={joinState.title ?? null} slug={slug} number={joinState.number} />
|
<RoomTopbar title={joinState.title ?? null} slug={slug} number={joinState.number} />
|
||||||
<div className="room-main">
|
<div className="room-main">
|
||||||
|
|||||||
Reference in New Issue
Block a user