Refactored participant preview modal

- Commented not necessary code in user-settings which forced a new publisher init if device labels were empty
- Added more conditional cases initializing the default publisher in webrtc service
- Added video background color
pull/690/head
csantosm 2022-01-26 11:14:15 +01:00
parent 3c1876769b
commit e9e3bbaf09
6 changed files with 74 additions and 32 deletions

View File

@ -58,7 +58,7 @@
<mat-form-field class="alternate-theme">
<mat-select
placeholder="Camera Options"
[ngModel]="isVideoActive && cameraSelected ? cameraSelected.device : 'None'"
[ngModel]="isVideoActive && !!cameraSelected ? cameraSelected.device : 'None'"
(selectionChange)="onCameraSelected($event)"
>
<mat-option *ngFor="let camera of cameras" [value]="camera.device">

View File

@ -106,11 +106,16 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
// Publish Webcam video
this.openViduWebRTCService.publishVideo(this.participantService.getMyCameraPublisher(), true);
this.isVideoActive = true;
return;
} else {
// Videosource is 'null' because of the user has selected 'None' or muted the camera
// Unpublish webcam
this.openViduWebRTCService.publishVideo(this.participantService.getMyCameraPublisher(), false);
//TODO: save 'None' device in storage
// this.deviceSrv.setCameraSelected(videoSource);
// this.cameraSelected = this.deviceSrv.getCameraSelected();
this.isVideoActive = false;
}
// Unpublish webcam video
this.openViduWebRTCService.publishVideo(this.participantService.getMyCameraPublisher(), false);
this.isVideoActive = false;
}
async onMicrophoneSelected(event: any) {
@ -229,6 +234,10 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
this.cameras = this.deviceSrv.getCameras();
this.cameraSelected = this.deviceSrv.getCameraSelected();
this.microphoneSelected = this.deviceSrv.getMicrophoneSelected();
this.isVideoActive = this.hasVideoDevices && this.cameraSelected.label !== 'None';
this.isAudioActive = this.hasAudioDevices && this.microphoneSelected.label !== 'None';
}
private scrollToBottom(): void {
@ -255,28 +264,31 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
private async initwebcamPublisher() {
const publisher = await this.openViduWebRTCService.initDefaultPublisher(undefined);
if (publisher) {
this.handlePublisherSuccess(publisher);
// this.handlePublisherSuccess(publisher);
this.handlePublisherError(publisher);
}
}
private handlePublisherSuccess(publisher: Publisher) {
publisher.once('accessAllowed', async () => {
if (this.deviceSrv.areEmptyLabels()) {
await this.deviceSrv.forceUpdate();
if (this.hasAudioDevices) {
const audioLabel = publisher?.stream?.getMediaStream()?.getAudioTracks()[0]?.label;
this.deviceSrv.setMicSelected(audioLabel);
}
//? After test in Chrome and Firefox, the devices always have labels.
//? It's not longer needed
// private handlePublisherSuccess(publisher: Publisher) {
// publisher.once('accessAllowed', async () => {
// if (this.deviceSrv.areEmptyLabels()) {
// await this.deviceSrv.forceUpdate();
// if (this.hasAudioDevices) {
// const audioLabel = publisher?.stream?.getMediaStream()?.getAudioTracks()[0]?.label;
// this.deviceSrv.setMicSelected(audioLabel);
// }
if (this.hasVideoDevices) {
const videoLabel = publisher?.stream?.getMediaStream()?.getVideoTracks()[0]?.label;
this.deviceSrv.setCameraSelected(videoLabel);
}
this.setDevicesInfo();
}
});
}
// if (this.hasVideoDevices) {
// const videoLabel = publisher?.stream?.getMediaStream()?.getVideoTracks()[0]?.label;
// this.deviceSrv.setCameraSelected(videoLabel);
// }
// this.setDevicesInfo();
// }
// });
// }
private handlePublisherError(publisher: Publisher) {
publisher.once('accessDenied', (e: any) => {

View File

@ -9,6 +9,7 @@ video {
border: 0;
font-size: 100%;
border-radius: 5px;
background-color: #000000;
}
.poster_img {

View File

@ -5,7 +5,7 @@ import { VideoType } from '../../models/video-type.model';
@Component({
selector: 'ov-video',
template: `
<img *ngIf="!_streamManager?.stream?.videoActive && _streamManager?.stream?.typeOfVideo === 'CAMERA'" class="poster_img" alt="OpenVidu Logo" src="assets/images/poster.png" />
<img *ngIf="!_streamManager?.stream?.videoActive && (type === 'CAMERA' || !type)" class="poster_img" alt="OpenVidu Logo" src="assets/images/poster.png" />
<video
#videoElement
[attr.id]="streamManager && _streamManager.stream ? 'video-' + _streamManager.stream.streamId : 'video-undefined'"
@ -22,6 +22,7 @@ export class VideoComponent implements AfterViewInit {
_streamManager: StreamManager;
_videoElement: ElementRef;
type: VideoType = VideoType.CAMERA;
ngAfterViewInit() {
setTimeout(() => {
@ -41,7 +42,8 @@ export class VideoComponent implements AfterViewInit {
setTimeout(() => {
this._streamManager = streamManager;
if (!!this._videoElement && this._streamManager) {
if (this._streamManager.stream.typeOfVideo === VideoType.SCREEN) {
this.type = <VideoType>this._streamManager?.stream?.typeOfVideo;
if (this.type === VideoType.SCREEN) {
this._videoElement.nativeElement.style.objectFit = 'contain';
this._videoElement.nativeElement.style.background = '#272727';
this.enableVideoSizeBig();

View File

@ -34,13 +34,16 @@ export class DeviceService {
async initializeDevices() {
// Requesting media permissions. Sometimes, browser doens't launch the media permissions modal.
await this.OV.getUserMedia({audioSource: undefined, videoSource: undefined });
const mediaStream = await this.OV.getUserMedia({audioSource: undefined, videoSource: undefined });
this.devices = await this.OV.getDevices();
const customDevices = this.initializeCustomDevices(this.devices);
this.cameras = customDevices.cameras;
this.microphones = customDevices.microphones;
mediaStream?.getAudioTracks().forEach((track) => track.stop());
mediaStream?.getVideoTracks().forEach((track) => track.stop());
this.log.d('Media devices',customDevices);
}

View File

@ -118,19 +118,43 @@ export class WebrtcService {
*/
async initDefaultPublisher(targetElement: string | HTMLElement): Promise<Publisher> {
await this.deviceService.initializeDevices();
const publishAudio = this.deviceService.hasAudioDeviceAvailable();
const publishVideo = this.deviceService.hasVideoDeviceAvailable();
const videoSource = publishVideo ? this.deviceService.getCameraSelected().device : false;
const audioSource = publishAudio ? this.deviceService.getMicrophoneSelected().device : false;
const hasVideoDevices = this.deviceService.hasVideoDeviceAvailable();
const hasAudioDevices = this.deviceService.hasAudioDeviceAvailable();
const isVideoActive = hasVideoDevices && this.deviceService.getCameraSelected().label !== 'None';
const isAudioActive = hasAudioDevices && this.deviceService.getMicrophoneSelected().label !== 'None';
let videoSource = null;
let audioSource = null;
if(isVideoActive){
// Video is active, assign the device selected
videoSource = this.deviceService.getCameraSelected().device
} else if(!isVideoActive && hasVideoDevices) {
// Video is muted, assign the default device
videoSource = undefined;
}
if(isAudioActive){
// Audio is active, assign the device selected
audioSource = this.deviceService.getMicrophoneSelected().device
} else if(!isAudioActive && hasAudioDevices) {
// Audio is muted, assign the default device
audioSource = undefined;
}
// const videoSource = publishVideo ? this.deviceService.getCameraSelected().device : false;
// const audioSource = publishAudio ? this.deviceService.getMicrophoneSelected().device : false;
const mirror = this.deviceService.getCameraSelected() && this.deviceService.getCameraSelected().type === CameraType.FRONT;
const properties: PublisherProperties = {
videoSource,
audioSource,
publishVideo,
publishAudio,
publishVideo: isVideoActive,
publishAudio: isAudioActive,
mirror
};
if (publishAudio || publishVideo) {
if (isVideoActive || isAudioActive) {
const publisher = this.initPublisher(targetElement, properties);
this.participantService.setMyCameraPublisher(publisher);
return publisher;