diff --git a/projects/core/assets/scss/lobby.scss b/projects/core/assets/scss/lobby.scss index 90b70ce..55f792c 100644 --- a/projects/core/assets/scss/lobby.scss +++ b/projects/core/assets/scss/lobby.scss @@ -319,11 +319,16 @@ canvasOne { position: relative; } -.stream-video canvas { +.stream-video canvas, +.stream-video video +{ width: 100%; height: 100%; object-fit: cover; } +.stream-video video { + background-color: transparent; +} /*==================== Control elements ====================*/ .name-tag { diff --git a/projects/core/src/lib/component/guest-list/guest-list.component.ts b/projects/core/src/lib/component/guest-list/guest-list.component.ts index 80855ee..eb02f14 100644 --- a/projects/core/src/lib/component/guest-list/guest-list.component.ts +++ b/projects/core/src/lib/component/guest-list/guest-list.component.ts @@ -30,6 +30,7 @@ export class GuestListComponent implements OnInit { @Output() activateLobbyMediaStreamEvent = new EventEmitter(); @Output() deactivateLobbyMediaStreamEvent = new EventEmitter(); @Input() localGuest$!: Observable; + @Input() istHost: boolean = false; @ViewChild(GuestListDirective, {static: true}) shigGuestList!: GuestListDirective; public readonly cmpRefMap = new Map>(); @@ -57,7 +58,7 @@ export class GuestListComponent implements OnInit { ngOnInit() { this.localGuest$.subscribe((local) => { if (local !== undefined) { - this.upsertGuest(local); + this.upsertGuest(local, true); } }); } @@ -66,13 +67,15 @@ export class GuestListComponent implements OnInit { return this.cmpRefMap.has(guestId); } - private upsertGuest(lobbyMediaStream: LobbyMediaStream): void { + private upsertGuest(lobbyMediaStream: LobbyMediaStream, isLocal: boolean = false): void { if (this.hasGuest(lobbyMediaStream.streamId)) { this.cmpRefMap.get(lobbyMediaStream.streamId)?.instance.updateGuest(lobbyMediaStream); return; } const componentRef = this.shigGuestList.viewContainerRef.createComponent(GuestComponent); componentRef.instance.media = lobbyMediaStream; + componentRef.instance.isLocal = isLocal + componentRef.instance.onHost = this.istHost; componentRef.instance.activateGuestStreamCbk = (g: LobbyMediaStream) => this.activateLobbyMediaStreamEvent.emit(g); componentRef.instance.deactivateGuestStreamCbk = (g: LobbyMediaStream) => this.deactivateLobbyMediaStreamEvent.emit(g); this.cmpRefMap.set(lobbyMediaStream.streamId, componentRef); diff --git a/projects/core/src/lib/component/guest/guest.component.html b/projects/core/src/lib/component/guest/guest.component.html index 2efcc9d..1ebac2c 100644 --- a/projects/core/src/lib/component/guest/guest.component.html +++ b/projects/core/src/lib/component/guest/guest.component.html @@ -1,7 +1,7 @@
- - - + +
{{ media?.name }} diff --git a/projects/core/src/lib/component/guest/guest.component.ts b/projects/core/src/lib/component/guest/guest.component.ts index 4f9ff32..d2d934b 100644 --- a/projects/core/src/lib/component/guest/guest.component.ts +++ b/projects/core/src/lib/component/guest/guest.component.ts @@ -25,9 +25,11 @@ export class GuestComponent implements AfterViewInit, OnDestroy { @Input() activateGuestStreamCbk!: (g: LobbyMediaStream) => void; @Input() deactivateGuestStreamCbk!: (g: LobbyMediaStream) => void; @Input('media') media!: LobbyMediaStream; + @Input('onHost') onHost!: boolean; + @Input('isLocal') isLocal!: boolean; ngAfterViewInit() { - if(this.media && this.media.stream) { + if (this.media && this.media.stream) { this.getVideoElement().srcObject = this.media.stream; } } @@ -35,7 +37,7 @@ export class GuestComponent implements AfterViewInit, OnDestroy { public updateGuest(media: LobbyMediaStream): void { const oldMedia = this.media; this.media = media; - if(this.media.stream) { + if (this.media.stream) { this.getVideoElement().srcObject = this.media.stream; } if (oldMedia.streamId !== this.media.streamId) { @@ -46,14 +48,16 @@ export class GuestComponent implements AfterViewInit, OnDestroy { } ngOnDestroy(): void { + const isSelected = this.isSelected(); + if (isSelected) { + this.deactivateGuestStreamCbk(this.media); + } this.getVideoElement().srcObject = null; this.media.stopStream(); } toggleActive() { - const shadowRoot = document.getElementById(`switch-${this.media.streamId}`)?.shadowRoot; - const isSelected = !shadowRoot?.querySelector('div')?.classList.contains('selected'); - + const isSelected = this.isSelected(); if (isSelected) { this.activateGuestStreamCbk(this.media); } else { @@ -64,5 +68,10 @@ export class GuestComponent implements AfterViewInit, OnDestroy { private getVideoElement(): HTMLVideoElement { return this.videoRef.nativeElement; } + + private isSelected(): boolean { + const shadowRoot = document.getElementById(`switch-${this.media.streamId}`)?.shadowRoot; + return !shadowRoot?.querySelector('div')?.classList.contains('selected'); + } } diff --git a/projects/core/src/lib/component/lobby/lobby.component.html b/projects/core/src/lib/component/lobby/lobby.component.html index 8cc0023..9c70e2d 100644 --- a/projects/core/src/lib/component/lobby/lobby.component.html +++ b/projects/core/src/lib/component/lobby/lobby.component.html @@ -65,15 +65,14 @@
-
-
@@ -82,6 +81,7 @@
diff --git a/projects/core/src/lib/provider/lobby.service.ts b/projects/core/src/lib/provider/lobby.service.ts index 6933499..c41e631 100644 --- a/projects/core/src/lib/provider/lobby.service.ts +++ b/projects/core/src/lib/provider/lobby.service.ts @@ -66,7 +66,7 @@ export class LobbyService { if (event.type === 'add') { let stream = event.stream; if (stream !== undefined) { - console.log('###### Add track:stream', event.media.kind, event.media.trackId, stream?.id); + console.log('###### Add track:stream', event.media.kind, event.media.trackId, event.media.streamId); this.add$.next({media: event.media, stream}); } } diff --git a/projects/core/src/lib/provider/sdp-parser.ts b/projects/core/src/lib/provider/sdp-parser.ts index bcc33c0..068bba7 100644 --- a/projects/core/src/lib/provider/sdp-parser.ts +++ b/projects/core/src/lib/provider/sdp-parser.ts @@ -45,7 +45,7 @@ export class SdpParser { private static readDescription(description: string | undefined): { purpose: LobbyMediaPurpose, info: string } { let purpose: LobbyMediaPurpose = LobbyMediaPurpose.GUEST; - let info: string = ''; + let info: string = 'Guest'; if (description !== undefined) { purpose = getMediaStreamTypeByNumber(Number(description)); } diff --git a/projects/core/src/lib/provider/webrtc-connection.ts b/projects/core/src/lib/provider/webrtc-connection.ts index 946b8fb..8a07845 100644 --- a/projects/core/src/lib/provider/webrtc-connection.ts +++ b/projects/core/src/lib/provider/webrtc-connection.ts @@ -74,7 +74,6 @@ export class WebrtcConnection extends EventEmitter { .then(() => aw); } - public close(): Promise { this.pc.ontrack = null; this.pc.oniceconnectionstatechange = null; @@ -91,7 +90,6 @@ export class WebrtcConnection extends EventEmitter { private onReceiveChannelMessageCallback(me: MessageEvent): void { const msg = JSON.parse(new TextDecoder().decode(me.data as ArrayBuffer)) as ChannelMsg; if (msg?.type === ChannelMsgType.OfferMsg) { - } } @@ -107,13 +105,11 @@ export class WebrtcConnection extends EventEmitter { const track = ev.track; const stream = ev.streams[0]; if (media !== undefined) { - media.streamId = stream.id; - media.trackId = track.id; this.remoteMedia.set(media.mediaIndex, media); this.emit({type: 'add', media, track, stream}); } if (media === undefined) { - console.log('#### Misst!', ev.transceiver.mid, this.remoteMedia); + console.log('error! an transceiver without a media should not exits', ev.transceiver.mid, this.remoteMedia); } } @@ -128,16 +124,24 @@ export class WebrtcConnection extends EventEmitter { const mediaLines = SdpParser.getSdpMediaLine(sdp); mediaLines.forEach((line) => { const media = this.remoteMedia.get(line.mid); - if (!media) { - this.remoteMedia.set(line.mid, { - mediaIndex: line.mid, - purpose: line.purpose, - info: line.info, - kind: line.kind, - muted: true, - trackId: line.trackId, - streamId: line.streamId, - }); + const updateMedia: LobbyMedia = { + mediaIndex: line.mid, + purpose: line.purpose, + info: line.info, + kind: line.kind, + muted: true, + trackId: line.trackId, + streamId: line.streamId, + } + + if ((line.direction === 'inactive' || line.direction === 'recvonly') && !!media) { + updateMedia.trackId = media.trackId + updateMedia.streamId = media.streamId + this.remoteMedia.set(line.mid, updateMedia) + } + + if (line.direction !== 'inactive' && line.direction !== 'recvonly') { + this.remoteMedia.set(line.mid, updateMedia) } }); } @@ -147,8 +151,8 @@ export class WebrtcConnection extends EventEmitter { mediaLines.forEach((line) => { const media = this.remoteMedia.get(line.mid); if ((line.direction === 'inactive' || line.direction === 'recvonly') && !!media) { - this.emit({type: 'remove', media}); this.remoteMedia.delete(line.mid); + this.emit({type: 'remove', media}); } }); }