openvidu-components: Improved user-settings component

- Changed replaceTrack to republishTrack until replaceTrack issue is fixed (https://github.com/OpenVidu/openvidu/pull/700)
- Fixed bug in mat options 
- Added audio detector
pull/707/head
csantosm 2022-02-25 14:36:36 +01:00
parent 99a5c945b3
commit f23f39dd6f
4 changed files with 104 additions and 87 deletions

View File

@ -47,6 +47,12 @@
bottom: 0px; bottom: 0px;
} }
#audio-wave-container {
position: absolute;
right: 20px;
top: 30px;
}
.cameraMessageContainer { .cameraMessageContainer {
height: 100%; height: 100%;
width: 100%; width: 100%;
@ -1074,7 +1080,7 @@
padding: 35px; padding: 35px;
} }
.videoContainer{ .videoContainer{
width: 90%; width: 100%;
} }
} }
@media (min-width: 768px) { @media (min-width: 768px) {

View File

@ -34,6 +34,9 @@
<span *ngIf="!hasVideoDevices && hasAudioDevices">Oops! Camera is not available</span> <span *ngIf="!hasVideoDevices && hasAudioDevices">Oops! Camera is not available</span>
<span *ngIf="hasVideoDevices && !hasAudioDevices">Oops! Microphone is not available</span> <span *ngIf="hasVideoDevices && !hasAudioDevices">Oops! Microphone is not available</span>
</div> </div>
<div id="audio-wave-container" *ngIf="stream.type === 'CAMERA'">
<ov-audio-wave [streamManager]="stream.streamManager"></ov-audio-wave>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -56,11 +59,8 @@
</div> </div>
<div class="two" fxFlex="80" fxLayoutAlign="center center"> <div class="two" fxFlex="80" fxLayoutAlign="center center">
<mat-form-field class="alternate-theme"> <mat-form-field class="alternate-theme">
<mat-select <mat-label>Camera Options</mat-label>
placeholder="Camera Options" <mat-select [disabled]="isVideoMuted" (selectionChange)="onCameraSelected($event)">
[ngModel]="!isVideoMuted && !!cameraSelected ? cameraSelected.device : 'None'"
(selectionChange)="onCameraSelected($event)"
>
<mat-option *ngFor="let camera of cameras" [value]="camera.device"> <mat-option *ngFor="let camera of cameras" [value]="camera.device">
{{ camera.label }} {{ camera.label }}
</mat-option> </mat-option>
@ -86,11 +86,8 @@
</div> </div>
<div class="two" fxFlex="80" fxLayoutAlign="center center"> <div class="two" fxFlex="80" fxLayoutAlign="center center">
<mat-form-field class="alternate-theme"> <mat-form-field class="alternate-theme">
<mat-select <mat-label>Microphone Options</mat-label>
placeholder="Microphone Options" <mat-select [disabled]="isAudioMuted" (selectionChange)="onMicrophoneSelected($event)">
[ngModel]="!isAudioMuted && microphoneSelected ? microphoneSelected.device : 'None'"
(selectionChange)="onMicrophoneSelected($event)"
>
<mat-option *ngFor="let microphone of microphones" [value]="microphone.device"> <mat-option *ngFor="let microphone of microphones" [value]="microphone.device">
{{ microphone.label }} {{ microphone.label }}
</mat-option> </mat-option>

View File

@ -98,9 +98,14 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
// Is New deviceId different from the old one? // Is New deviceId different from the old one?
if (this.deviceSrv.needUpdateVideoTrack(videoSource)) { if (this.deviceSrv.needUpdateVideoTrack(videoSource)) {
const mirror = this.deviceSrv.cameraNeedsMirror(videoSource); const mirror = this.deviceSrv.cameraNeedsMirror(videoSource);
const pp: PublisherProperties = { videoSource, audioSource: false, mirror }; //TODO: Uncomment this when replaceTrack issue is fixed
// const pp: PublisherProperties = { videoSource, audioSource: false, mirror };
// await this.openviduService.replaceTrack(VideoType.CAMERA, pp);
// TODO: Remove this when replaceTrack issue is fixed
const pp: PublisherProperties = { videoSource, audioSource: this.microphoneSelected.device, mirror };
await this.openviduService.republishTrack(pp);
await this.openviduService.replaceTrack(VideoType.CAMERA, pp);
this.cameraSelected = videoSource; this.cameraSelected = videoSource;
this.deviceSrv.setCameraSelected(this.cameraSelected); this.deviceSrv.setCameraSelected(this.cameraSelected);
} }
@ -115,8 +120,14 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
const audioSource = event?.value; const audioSource = event?.value;
// Is New deviceId different than older? // Is New deviceId different than older?
if (this.deviceSrv.needUpdateAudioTrack(audioSource)) { if (this.deviceSrv.needUpdateAudioTrack(audioSource)) {
const pp: PublisherProperties = { audioSource, videoSource: false }; //TODO: Uncomment this when replaceTrack issue is fixed
await this.openviduService.replaceTrack(VideoType.CAMERA, pp); // const pp: PublisherProperties = { audioSource, videoSource: false };
// await this.openviduService.replaceTrack(VideoType.CAMERA, pp);
// TODO: Remove this when replaceTrack issue is fixed
const mirror = this.deviceSrv.cameraNeedsMirror(this.cameraSelected.device);
const pp: PublisherProperties = { videoSource: this.cameraSelected.device, audioSource, mirror };
await this.openviduService.republishTrack(pp);
this.microphoneSelected = audioSource; this.microphoneSelected = audioSource;
this.deviceSrv.setMicSelected(this.microphoneSelected); this.deviceSrv.setMicSelected(this.microphoneSelected);
} }

View File

@ -163,22 +163,6 @@ export class OpenViduService {
return await this.OV.initPublisherAsync(targetElement, properties); return await this.OV.initPublisherAsync(targetElement, properties);
} }
//TODO: This method is used by republishTrack. Check if it's neecessary
// private destroyPublisher(publisher: Publisher): void {
// if (!!publisher) {
// // publisher.off('streamAudioVolumeChange');
// if (publisher.stream.getWebRtcPeer()) {
// publisher.stream.disposeWebRtcPeer();
// }
// publisher.stream.disposeMediaStream();
// if (publisher.id === this.participantService.getMyCameraPublisher().id) {
// this.participantService.setMyCameraPublisher(publisher);
// } else if (publisher.id === this.participantService.getMyScreenPublisher().id) {
// this.participantService.setMyScreenPublisher(publisher);
// }
// }
// }
async publish(publisher: Publisher): Promise<void> { async publish(publisher: Publisher): Promise<void> {
if (!!publisher) { if (!!publisher) {
if (publisher === this.participantService.getMyCameraPublisher()) { if (publisher === this.participantService.getMyCameraPublisher()) {
@ -220,39 +204,41 @@ export class OpenViduService {
} }
} }
// Used replaceTrack instead // TODO: Remove this method when replaceTrack issue is fixed
// republishTrack(videoSource: string, audioSource: string, mirror: boolean = true): Promise<void> { // https://github.com/OpenVidu/openvidu/pull/700
// return new Promise(async (resolve, reject) => { republishTrack(properties: PublisherProperties): Promise<void> {
// if (!!videoSource) { const {videoSource, audioSource, mirror} = properties;
// this.log.d('Replacing video track ' + videoSource); return new Promise(async (resolve, reject) => {
// this.videoSource = videoSource; if (!!videoSource) {
// } this.log.d('Replacing video track ' + videoSource);
// if (!!audioSource) { this.videoSource = videoSource;
// this.log.d('Replacing audio track ' + audioSource); }
// this.audioSource = audioSource; if (!!audioSource) {
// } this.log.d('Replacing audio track ' + audioSource);
// this.destroyPublisher(this.participantService.getMyCameraPublisher()); this.audioSource = audioSource;
// const properties: PublisherProperties = { }
// videoSource: this.videoSource, this.destroyPublisher(this.participantService.getMyCameraPublisher());
// audioSource: this.audioSource, const properties: PublisherProperties = {
// publishVideo: this.participantService.hasCameraVideoActive(), videoSource: this.videoSource,
// publishAudio: this.participantService.hasCameraAudioActive(), audioSource: this.audioSource,
// mirror publishVideo: this.participantService.hasCameraVideoActive(),
// }; publishAudio: this.participantService.hasCameraAudioActive(),
mirror
};
// const publisher = await this.initPublisher(undefined, properties); const publisher = await this.initPublisher(undefined, properties);
// this.participantService.setMyCameraPublisher(publisher); this.participantService.setMyCameraPublisher(publisher);
// publisher.once('streamPlaying', () => { publisher.once('streamPlaying', () => {
// this.participantService.setMyCameraPublisher(publisher); this.participantService.setMyCameraPublisher(publisher);
// resolve(); resolve();
// }); });
// publisher.once('accessDenied', () => { publisher.once('accessDenied', () => {
// reject(); reject();
// }); });
// }); });
// } }
sendSignal(type: Signal, connections?: Connection[], data?: any): void { sendSignal(type: Signal, connections?: Connection[], data?: any): void {
const signalOptions: SignalOptions = { const signalOptions: SignalOptions = {
@ -273,33 +259,36 @@ export class OpenViduService {
this.log.d(`Replacing ${videoType} track`, props); this.log.d(`Replacing ${videoType} track`, props);
if (videoType === VideoType.CAMERA) { if (videoType === VideoType.CAMERA) {
let mediaStream: MediaStream; //TODO: Uncomment this section when replaceTrack issue is fixed
const oldMediaStream = this.participantService.getMyCameraPublisher().stream.getMediaStream(); // https://github.com/OpenVidu/openvidu/pull/700
const isFirefoxPlatform = this.platformService.isFirefox(); throw('Replace track feature has a bug. We are trying to fix it');
const isReplacingAudio = !!props.audioSource; // let mediaStream: MediaStream;
const isReplacingVideo = !!props.videoSource; // const oldMediaStream = this.participantService.getMyCameraPublisher().stream.getMediaStream();
// const isFirefoxPlatform = this.platformService.isFirefox();
// const isReplacingAudio = !!props.audioSource;
// const isReplacingVideo = !!props.videoSource;
if (isReplacingVideo) { // if (isReplacingVideo) {
if (isFirefoxPlatform) { // if (isFirefoxPlatform) {
// Firefox throw an exception trying to get a new MediaStreamTrack if the older one is not stopped // // Firefox throw an exception trying to get a new MediaStreamTrack if the older one is not stopped
// NotReadableError: Concurrent mic process limit. Stopping tracks before call to getUserMedia // // NotReadableError: Concurrent mic process limit. Stopping tracks before call to getUserMedia
oldMediaStream.getVideoTracks()[0].stop(); // oldMediaStream.getVideoTracks()[0].stop();
} // }
mediaStream = await this.createMediaStream(props); // mediaStream = await this.createMediaStream(props);
// Replace video track // // Replace video track
const videoTrack: MediaStreamTrack = mediaStream.getVideoTracks()[0]; // const videoTrack: MediaStreamTrack = mediaStream.getVideoTracks()[0];
await this.participantService.getMyCameraPublisher().replaceTrack(videoTrack); // await this.participantService.getMyCameraPublisher().replaceTrack(videoTrack);
} else if (isReplacingAudio) { // } else if (isReplacingAudio) {
if (isFirefoxPlatform) { // if (isFirefoxPlatform) {
// Firefox throw an exception trying to get a new MediaStreamTrack if the older one is not stopped // // Firefox throw an exception trying to get a new MediaStreamTrack if the older one is not stopped
// NotReadableError: Concurrent mic process limit. Stopping tracks before call to getUserMedia // // NotReadableError: Concurrent mic process limit. Stopping tracks before call to getUserMedia
oldMediaStream.getAudioTracks()[0].stop(); // oldMediaStream.getAudioTracks()[0].stop();
} // }
mediaStream = await this.createMediaStream(props); // mediaStream = await this.createMediaStream(props);
// Replace audio track // // Replace audio track
const audioTrack: MediaStreamTrack = mediaStream.getAudioTracks()[0]; // const audioTrack: MediaStreamTrack = mediaStream.getAudioTracks()[0];
await this.participantService.getMyCameraPublisher().replaceTrack(audioTrack); // await this.participantService.getMyCameraPublisher().replaceTrack(audioTrack);
} // }
} else if (videoType === VideoType.SCREEN) { } else if (videoType === VideoType.SCREEN) {
let newScreenMediaStream; let newScreenMediaStream;
try { try {
@ -315,6 +304,20 @@ export class OpenViduService {
} }
} }
private destroyPublisher(publisher: Publisher): void {
if (!!publisher) {
if (publisher.stream.getWebRtcPeer()) {
publisher.stream.disposeWebRtcPeer();
}
publisher.stream.disposeMediaStream();
if (publisher.id === this.participantService.getMyCameraPublisher().id) {
this.participantService.setMyCameraPublisher(publisher);
} else if (publisher.id === this.participantService.getMyScreenPublisher().id) {
this.participantService.setMyScreenPublisher(publisher);
}
}
}
private async createMediaStream(pp: PublisherProperties): Promise<MediaStream> { private async createMediaStream(pp: PublisherProperties): Promise<MediaStream> {
let mediaStream: MediaStream; let mediaStream: MediaStream;
const isFirefoxPlatform = this.platformService.isFirefox(); const isFirefoxPlatform = this.platformService.isFirefox();