Web client: video from a call's other side no longer stays black
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Admin panel (push) Canceled after 0s
CI / Web client (push) Canceled after 0s
CI / Desktop client (ubuntu-24.04) (push) Canceled after 0s
CI / Desktop client (windows-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Admin panel (push) Canceled after 0s
CI / Web client (push) Canceled after 0s
CI / Desktop client (ubuntu-24.04) (push) Canceled after 0s
CI / Desktop client (windows-latest) (push) Canceled after 0s
In an encrypted call, video that arrives before its sender's key is dropped, keyframe and all, and the decoder waits for another keyframe that may never come. When a participant's first key arrives, subscribe to their video again so the server asks for a fresh one. Also keep your own tile in the corner of a call of two: the tile's own "relative" class won over the "absolute" it was given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4dd91c4f2c
commit
994e6afd49
2 files changed
+23
-8
No files matched your search
@@ -195,12 +195,10 @@ onBeforeUnmount(() => window.removeEventListener('keydown', onKey))
|
||||
<!-- Two of you: them on the stage, you in the corner. -->
|
||||
<div v-else-if="pair && remotes[0]" :class="['relative', expanded ? 'h-full' : 'aspect-video']">
|
||||
<CallTile :tile="remotes[0]" :compact="!expanded" class="h-full w-full" />
|
||||
<CallTile
|
||||
v-if="self"
|
||||
:tile="self"
|
||||
compact
|
||||
class="absolute right-3 bottom-3 aspect-video w-1/4 min-w-28 shadow-float"
|
||||
/>
|
||||
<!-- A wrapper: the tile's own "relative" would win over "absolute". -->
|
||||
<div v-if="self" class="absolute right-3 bottom-3 aspect-video w-1/4 min-w-28 shadow-float">
|
||||
<CallTile :tile="self" compact class="h-full w-full" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- More: a grid, or whoever is speaking when shrunk. -->
|
||||
|
||||
@@ -455,8 +455,24 @@ export const useCall = defineStore('call', () => {
|
||||
})
|
||||
}
|
||||
|
||||
function onEncryptionKey(key: Uint8Array, index: number, _membership: unknown, backendIdentity: string) {
|
||||
void keyProvider?.setParticipantKey(key, index, backendIdentity)
|
||||
/** Remote participants whose media key has arrived. */
|
||||
const keyed = new Set<string>()
|
||||
|
||||
async function onEncryptionKey(key: Uint8Array, index: number, _membership: unknown, backendIdentity: string) {
|
||||
const provider = keyProvider
|
||||
if (!provider) return
|
||||
await provider.setParticipantKey(key, index, backendIdentity)
|
||||
if (keyProvider !== provider || keyed.has(backendIdentity)) return
|
||||
keyed.add(backendIdentity)
|
||||
// Video that came before its key was dropped, keyframe and all, and
|
||||
// the decoder waits for another that may never come: black, while the
|
||||
// audio plays on. Subscribing again makes the server ask for one.
|
||||
const p = lk.value?.remoteParticipants.get(backendIdentity)
|
||||
for (const pub of p?.videoTrackPublications.values() ?? []) {
|
||||
if (!pub.isSubscribed) continue
|
||||
pub.setSubscribed(false)
|
||||
pub.setSubscribed(true)
|
||||
}
|
||||
}
|
||||
|
||||
function onMembershipError(e: unknown) {
|
||||
@@ -573,6 +589,7 @@ export const useCall = defineStore('call', () => {
|
||||
session = null
|
||||
lk.value = null
|
||||
keyProvider = null
|
||||
keyed.clear()
|
||||
sentNotification = null
|
||||
hadCompany = false
|
||||
window.clearInterval(lengthTimer)
|
||||
|
||||
Reference in new issue
Block a user