mirror of https://github.com/OpenVidu/openvidu.git
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 colorpull/690/head
parent
3c1876769b
commit
e9e3bbaf09
|
@ -58,7 +58,7 @@
|
||||||
<mat-form-field class="alternate-theme">
|
<mat-form-field class="alternate-theme">
|
||||||
<mat-select
|
<mat-select
|
||||||
placeholder="Camera Options"
|
placeholder="Camera Options"
|
||||||
[ngModel]="isVideoActive && cameraSelected ? cameraSelected.device : 'None'"
|
[ngModel]="isVideoActive && !!cameraSelected ? cameraSelected.device : 'None'"
|
||||||
(selectionChange)="onCameraSelected($event)"
|
(selectionChange)="onCameraSelected($event)"
|
||||||
>
|
>
|
||||||
<mat-option *ngFor="let camera of cameras" [value]="camera.device">
|
<mat-option *ngFor="let camera of cameras" [value]="camera.device">
|
||||||
|
|
|
@ -106,11 +106,16 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
|
||||||
// Publish Webcam video
|
// Publish Webcam video
|
||||||
this.openViduWebRTCService.publishVideo(this.participantService.getMyCameraPublisher(), true);
|
this.openViduWebRTCService.publishVideo(this.participantService.getMyCameraPublisher(), true);
|
||||||
this.isVideoActive = 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) {
|
async onMicrophoneSelected(event: any) {
|
||||||
|
@ -229,6 +234,10 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
|
||||||
this.cameras = this.deviceSrv.getCameras();
|
this.cameras = this.deviceSrv.getCameras();
|
||||||
this.cameraSelected = this.deviceSrv.getCameraSelected();
|
this.cameraSelected = this.deviceSrv.getCameraSelected();
|
||||||
this.microphoneSelected = this.deviceSrv.getMicrophoneSelected();
|
this.microphoneSelected = this.deviceSrv.getMicrophoneSelected();
|
||||||
|
|
||||||
|
this.isVideoActive = this.hasVideoDevices && this.cameraSelected.label !== 'None';
|
||||||
|
this.isAudioActive = this.hasAudioDevices && this.microphoneSelected.label !== 'None';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private scrollToBottom(): void {
|
private scrollToBottom(): void {
|
||||||
|
@ -255,28 +264,31 @@ export class UserSettingsComponent implements OnInit, OnDestroy {
|
||||||
private async initwebcamPublisher() {
|
private async initwebcamPublisher() {
|
||||||
const publisher = await this.openViduWebRTCService.initDefaultPublisher(undefined);
|
const publisher = await this.openViduWebRTCService.initDefaultPublisher(undefined);
|
||||||
if (publisher) {
|
if (publisher) {
|
||||||
this.handlePublisherSuccess(publisher);
|
|
||||||
|
// this.handlePublisherSuccess(publisher);
|
||||||
this.handlePublisherError(publisher);
|
this.handlePublisherError(publisher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private handlePublisherSuccess(publisher: Publisher) {
|
//? After test in Chrome and Firefox, the devices always have labels.
|
||||||
publisher.once('accessAllowed', async () => {
|
//? It's not longer needed
|
||||||
if (this.deviceSrv.areEmptyLabels()) {
|
// private handlePublisherSuccess(publisher: Publisher) {
|
||||||
await this.deviceSrv.forceUpdate();
|
// publisher.once('accessAllowed', async () => {
|
||||||
if (this.hasAudioDevices) {
|
// if (this.deviceSrv.areEmptyLabels()) {
|
||||||
const audioLabel = publisher?.stream?.getMediaStream()?.getAudioTracks()[0]?.label;
|
// await this.deviceSrv.forceUpdate();
|
||||||
this.deviceSrv.setMicSelected(audioLabel);
|
// if (this.hasAudioDevices) {
|
||||||
}
|
// const audioLabel = publisher?.stream?.getMediaStream()?.getAudioTracks()[0]?.label;
|
||||||
|
// this.deviceSrv.setMicSelected(audioLabel);
|
||||||
|
// }
|
||||||
|
|
||||||
if (this.hasVideoDevices) {
|
// if (this.hasVideoDevices) {
|
||||||
const videoLabel = publisher?.stream?.getMediaStream()?.getVideoTracks()[0]?.label;
|
// const videoLabel = publisher?.stream?.getMediaStream()?.getVideoTracks()[0]?.label;
|
||||||
this.deviceSrv.setCameraSelected(videoLabel);
|
// this.deviceSrv.setCameraSelected(videoLabel);
|
||||||
}
|
// }
|
||||||
this.setDevicesInfo();
|
// this.setDevicesInfo();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
private handlePublisherError(publisher: Publisher) {
|
private handlePublisherError(publisher: Publisher) {
|
||||||
publisher.once('accessDenied', (e: any) => {
|
publisher.once('accessDenied', (e: any) => {
|
||||||
|
|
|
@ -9,6 +9,7 @@ video {
|
||||||
border: 0;
|
border: 0;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
background-color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.poster_img {
|
.poster_img {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { VideoType } from '../../models/video-type.model';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ov-video',
|
selector: 'ov-video',
|
||||||
template: `
|
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
|
<video
|
||||||
#videoElement
|
#videoElement
|
||||||
[attr.id]="streamManager && _streamManager.stream ? 'video-' + _streamManager.stream.streamId : 'video-undefined'"
|
[attr.id]="streamManager && _streamManager.stream ? 'video-' + _streamManager.stream.streamId : 'video-undefined'"
|
||||||
|
@ -22,6 +22,7 @@ export class VideoComponent implements AfterViewInit {
|
||||||
_streamManager: StreamManager;
|
_streamManager: StreamManager;
|
||||||
|
|
||||||
_videoElement: ElementRef;
|
_videoElement: ElementRef;
|
||||||
|
type: VideoType = VideoType.CAMERA;
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -41,7 +42,8 @@ export class VideoComponent implements AfterViewInit {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this._streamManager = streamManager;
|
this._streamManager = streamManager;
|
||||||
if (!!this._videoElement && this._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.objectFit = 'contain';
|
||||||
this._videoElement.nativeElement.style.background = '#272727';
|
this._videoElement.nativeElement.style.background = '#272727';
|
||||||
this.enableVideoSizeBig();
|
this.enableVideoSizeBig();
|
||||||
|
|
|
@ -34,13 +34,16 @@ export class DeviceService {
|
||||||
|
|
||||||
async initializeDevices() {
|
async initializeDevices() {
|
||||||
// Requesting media permissions. Sometimes, browser doens't launch the media permissions modal.
|
// 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();
|
this.devices = await this.OV.getDevices();
|
||||||
const customDevices = this.initializeCustomDevices(this.devices);
|
const customDevices = this.initializeCustomDevices(this.devices);
|
||||||
this.cameras = customDevices.cameras;
|
this.cameras = customDevices.cameras;
|
||||||
this.microphones = customDevices.microphones;
|
this.microphones = customDevices.microphones;
|
||||||
|
|
||||||
|
mediaStream?.getAudioTracks().forEach((track) => track.stop());
|
||||||
|
mediaStream?.getVideoTracks().forEach((track) => track.stop());
|
||||||
|
|
||||||
this.log.d('Media devices',customDevices);
|
this.log.d('Media devices',customDevices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,19 +118,43 @@ export class WebrtcService {
|
||||||
*/
|
*/
|
||||||
async initDefaultPublisher(targetElement: string | HTMLElement): Promise<Publisher> {
|
async initDefaultPublisher(targetElement: string | HTMLElement): Promise<Publisher> {
|
||||||
await this.deviceService.initializeDevices();
|
await this.deviceService.initializeDevices();
|
||||||
const publishAudio = this.deviceService.hasAudioDeviceAvailable();
|
|
||||||
const publishVideo = this.deviceService.hasVideoDeviceAvailable();
|
const hasVideoDevices = this.deviceService.hasVideoDeviceAvailable();
|
||||||
const videoSource = publishVideo ? this.deviceService.getCameraSelected().device : false;
|
const hasAudioDevices = this.deviceService.hasAudioDeviceAvailable();
|
||||||
const audioSource = publishAudio ? this.deviceService.getMicrophoneSelected().device : false;
|
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 mirror = this.deviceService.getCameraSelected() && this.deviceService.getCameraSelected().type === CameraType.FRONT;
|
||||||
const properties: PublisherProperties = {
|
const properties: PublisherProperties = {
|
||||||
videoSource,
|
videoSource,
|
||||||
audioSource,
|
audioSource,
|
||||||
publishVideo,
|
publishVideo: isVideoActive,
|
||||||
publishAudio,
|
publishAudio: isAudioActive,
|
||||||
mirror
|
mirror
|
||||||
};
|
};
|
||||||
if (publishAudio || publishVideo) {
|
if (isVideoActive || isAudioActive) {
|
||||||
const publisher = this.initPublisher(targetElement, properties);
|
const publisher = this.initPublisher(targetElement, properties);
|
||||||
this.participantService.setMyCameraPublisher(publisher);
|
this.participantService.setMyCameraPublisher(publisher);
|
||||||
return publisher;
|
return publisher;
|
||||||
|
|
Loading…
Reference in New Issue