mirror of https://github.com/OpenVidu/openvidu.git
openvidu-components: Fixed bug requesting devices
parent
c0e45e8df7
commit
128dd3cfed
|
@ -114,7 +114,7 @@ import { TranslateService } from '../../services/translate/translate.service';
|
|||
styleUrls: ['./videoconference.component.css'],
|
||||
animations: [
|
||||
trigger('inOutAnimation', [
|
||||
transition(':enter', [style({ opacity: 0 }), animate('300ms ease-out', style({ opacity: 1 }))]),
|
||||
transition(':enter', [style({ opacity: 0 }), animate('300ms ease-out', style({ opacity: 1 }))])
|
||||
// transition(':leave', [style({ opacity: 1 }), animate('50ms ease-in', style({ opacity: 0.9 }))])
|
||||
])
|
||||
]
|
||||
|
@ -286,7 +286,8 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
|||
} else {
|
||||
this.log.w('No screen token found. Screenshare feature will be disabled');
|
||||
}
|
||||
this.loading = false;
|
||||
|
||||
this.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -434,32 +435,43 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
|||
|
||||
async ngOnInit() {
|
||||
this.subscribeToVideconferenceDirectives();
|
||||
}
|
||||
|
||||
private async start() {
|
||||
await this.deviceSrv.forceInitDevices();
|
||||
const nickname = this.externalParticipantName || this.storageSrv.getNickname() || `OpenVidu_User${Math.floor(Math.random() * 100)}`;
|
||||
this.participantService.initLocalParticipant({local: true, nickname});
|
||||
this.participantService.initLocalParticipant({ local: true, nickname });
|
||||
this.openviduService.initialize();
|
||||
if (this.deviceSrv.hasVideoDeviceAvailable() || this.deviceSrv.hasAudioDeviceAvailable()) {
|
||||
await this.initwebcamPublisher();
|
||||
}
|
||||
this.isSessionInitialized = true;
|
||||
this.onParticipantCreated.emit(this.participantService.getLocalParticipant());
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
private async initwebcamPublisher() {
|
||||
try {
|
||||
const publisher = await this.openviduService.initDefaultPublisher(undefined);
|
||||
if (publisher) {
|
||||
publisher.once('accessDenied', (e: any) => this.handlePublisherError(e));
|
||||
publisher.once('accessAllowed', async () => {
|
||||
await this.handlePublisherSuccess();
|
||||
this.participantReady = true;
|
||||
});
|
||||
// publisher.once('streamPlaying', () => (this.streamPlaying = true));
|
||||
private async initwebcamPublisher(): Promise<void> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const publisher = await this.openviduService.initDefaultPublisher();
|
||||
|
||||
if (publisher) {
|
||||
publisher.once('accessDenied', (e: any) => {
|
||||
this.handlePublisherError(e);
|
||||
resolve();
|
||||
});
|
||||
publisher.once('accessAllowed', async () => {
|
||||
await this.handlePublisherSuccess();
|
||||
this.participantReady = true;
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
this.actionService.openDialog(error.name.replace(/_/g, ' '), error.message, true);
|
||||
this.log.e(error);
|
||||
reject();
|
||||
}
|
||||
} catch (error) {
|
||||
this.actionService.openDialog(error.name.replace(/_/g, ' '), error.message, true);
|
||||
this.log.e(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async ngOnDestroy() {
|
||||
|
@ -649,8 +661,9 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
|||
this.onSessionCreated.emit(session);
|
||||
}
|
||||
|
||||
private handlePublisherError(e: any) {
|
||||
let message: string;
|
||||
private handlePublisherError(e: any): Promise<void> {
|
||||
let message: string = '';
|
||||
console.log('ERROR!', e);
|
||||
if (e.name === OpenViduErrorName.DEVICE_ALREADY_IN_USE) {
|
||||
this.log.w('Video device already in use. Disabling video device...');
|
||||
// Allow access to the room with only mic if camera device is already in use
|
||||
|
|
|
@ -16,12 +16,12 @@ import { StorageService } from '../storage/storage.service';
|
|||
providedIn: 'root'
|
||||
})
|
||||
export class DeviceService {
|
||||
private OV: OpenVidu = null;
|
||||
private OV: OpenVidu | null = null;
|
||||
private devices: Device[];
|
||||
private cameras: CustomDevice[] = [];
|
||||
private microphones: CustomDevice[] = [];
|
||||
private cameraSelected: CustomDevice;
|
||||
private microphoneSelected: CustomDevice;
|
||||
private cameraSelected: CustomDevice | null;
|
||||
private microphoneSelected: CustomDevice | null;
|
||||
private log: ILogger;
|
||||
private videoDevicesDisabled: boolean;
|
||||
private audioDevicesDisabled: boolean;
|
||||
|
@ -49,30 +49,33 @@ export class DeviceService {
|
|||
this.clear();
|
||||
try {
|
||||
this.OV = new OpenVidu();
|
||||
// Forcing media permissions request.
|
||||
// Sometimes, browser doens't launch the media permissions modal.
|
||||
const mediaStream = await this.OV.getUserMedia({ audioSource: undefined, videoSource: undefined });
|
||||
mediaStream?.getAudioTracks().forEach((track) => track.stop());
|
||||
mediaStream?.getVideoTracks().forEach((track) => track.stop());
|
||||
this.devices = await this.OV.getDevices();
|
||||
if(this.devices?.some(device => !device.deviceId || !device.label)){
|
||||
// Forcing media permissions request.
|
||||
// Sometimes, browser doesn't request the media permissions.
|
||||
await this.OV.getUserMedia({ audioSource: undefined, videoSource: undefined });
|
||||
}
|
||||
|
||||
await this.initializeDevices();
|
||||
this.updateAudioDeviceSelected();
|
||||
this.updateVideoDeviceSelected();
|
||||
|
||||
this._isVideoMuted = this.storageSrv.isVideoMuted() || this.libSrv.videoMuted.getValue();
|
||||
this._isAudioMuted = this.storageSrv.isAudioMuted() || this.libSrv.audioMuted.getValue();
|
||||
|
||||
this.log.d('Media devices', this.cameras, this.microphones);
|
||||
} catch (error) {
|
||||
this.deviceAccessDeniedError = (<OpenViduError>error).name === OpenViduErrorName.DEVICE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
await this.initializeDevices();
|
||||
this.updateAudioDeviceSelected();
|
||||
this.updateVideoDeviceSelected();
|
||||
|
||||
this._isVideoMuted = this.storageSrv.isVideoMuted() || this.libSrv.videoMuted.getValue();
|
||||
this._isAudioMuted = this.storageSrv.isAudioMuted() || this.libSrv.audioMuted.getValue();
|
||||
|
||||
this.log.d('Media devices', this.cameras, this.microphones);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize only the media devices available
|
||||
*/
|
||||
async initializeDevices() {
|
||||
this.devices = await this.OV.getDevices();
|
||||
if(this.devices?.some(device => !device.deviceId || !device.label)){
|
||||
this.devices = await this.OV?.getDevices() as Device [];
|
||||
}
|
||||
this.initializeCustomDevices();
|
||||
}
|
||||
|
||||
|
@ -156,11 +159,11 @@ export class DeviceService {
|
|||
return this.hasAudioDeviceAvailable() && this._isAudioMuted;
|
||||
}
|
||||
|
||||
getCameraSelected(): CustomDevice {
|
||||
getCameraSelected(): CustomDevice | null {
|
||||
return this.cameraSelected;
|
||||
}
|
||||
|
||||
getMicrophoneSelected(): CustomDevice {
|
||||
getMicrophoneSelected(): CustomDevice | null {
|
||||
return this.microphoneSelected;
|
||||
}
|
||||
|
||||
|
@ -175,11 +178,11 @@ export class DeviceService {
|
|||
}
|
||||
|
||||
needUpdateVideoTrack(newVideoSource: string): boolean {
|
||||
return this.cameraSelected.device !== newVideoSource;
|
||||
return this.cameraSelected?.device !== newVideoSource;
|
||||
}
|
||||
|
||||
needUpdateAudioTrack(newAudioSource: string): boolean {
|
||||
return this.microphoneSelected.device !== newAudioSource;
|
||||
return this.microphoneSelected?.device !== newAudioSource;
|
||||
}
|
||||
|
||||
getCameras(): CustomDevice[] {
|
||||
|
@ -226,14 +229,14 @@ export class DeviceService {
|
|||
}
|
||||
|
||||
private getCameraByDeviceField(deviceField: any): CustomDevice {
|
||||
return this.cameras.find((opt: CustomDevice) => opt.device === deviceField || opt.label === deviceField);
|
||||
return <CustomDevice>this.cameras.find((opt: CustomDevice) => opt.device === deviceField || opt.label === deviceField);
|
||||
}
|
||||
|
||||
private getMicrophoneByDeviceField(deviceField: any): CustomDevice {
|
||||
return this.microphones.find((opt: CustomDevice) => opt.device === deviceField || opt.label === deviceField);
|
||||
return <CustomDevice>this.microphones.find((opt: CustomDevice) => opt.device === deviceField || opt.label === deviceField);
|
||||
}
|
||||
|
||||
private getMicrophoneFromStogare(): CustomDevice {
|
||||
private getMicrophoneFromStogare(): CustomDevice | undefined {
|
||||
const storageDevice: CustomDevice = this.storageSrv.getAudioDevice();
|
||||
if (!!storageDevice && this.microphones.some((device) => device.device === storageDevice.device)) {
|
||||
return storageDevice;
|
||||
|
|
|
@ -19,10 +19,10 @@ import { OpenViduEdition } from '../../models/openvidu.model';
|
|||
})
|
||||
export class OpenViduService {
|
||||
private ovEdition: OpenViduEdition;
|
||||
protected OV: OpenVidu = null;
|
||||
protected OVScreen: OpenVidu = null;
|
||||
protected webcamSession: Session = null;
|
||||
protected screenSession: Session = null;
|
||||
protected OV: OpenVidu;
|
||||
protected OVScreen: OpenVidu;
|
||||
protected webcamSession: Session;
|
||||
protected screenSession: Session;
|
||||
protected videoSource = undefined;
|
||||
protected audioSource = undefined;
|
||||
protected log: ILogger;
|
||||
|
@ -166,14 +166,14 @@ export class OpenViduService {
|
|||
* @internal
|
||||
* Initialize a publisher checking devices saved on storage or if participant have devices available.
|
||||
*/
|
||||
async initDefaultPublisher(targetElement: string | HTMLElement): Promise<Publisher> {
|
||||
async initDefaultPublisher(): Promise<Publisher> {
|
||||
const hasVideoDevices = this.deviceService.hasVideoDeviceAvailable();
|
||||
const hasAudioDevices = this.deviceService.hasAudioDeviceAvailable();
|
||||
const isVideoActive = !this.deviceService.isVideoMuted();
|
||||
const isAudioActive = !this.deviceService.isAudioMuted();
|
||||
|
||||
let videoSource = null;
|
||||
let audioSource = null;
|
||||
let videoSource: string | boolean = false;
|
||||
let audioSource: string | boolean = false;
|
||||
|
||||
if (hasVideoDevices) {
|
||||
// Video is active, assign the device selected
|
||||
|
@ -200,7 +200,7 @@ export class OpenViduService {
|
|||
mirror
|
||||
};
|
||||
if (hasVideoDevices || hasAudioDevices) {
|
||||
const publisher = await this.initPublisher(targetElement, properties);
|
||||
const publisher = await this.initPublisher(undefined, properties);
|
||||
this.participantService.setMyCameraPublisher(publisher);
|
||||
this.participantService.updateLocalParticipant();
|
||||
return publisher;
|
||||
|
@ -325,7 +325,7 @@ export class OpenViduService {
|
|||
|
||||
const properties: PublisherProperties = {
|
||||
videoSource: ScreenType.SCREEN,
|
||||
audioSource: hasAudioDevicesAvailable ? this.deviceService.getMicrophoneSelected().device : null,
|
||||
audioSource: hasAudioDevicesAvailable ? this.deviceService.getMicrophoneSelected().device : false,
|
||||
publishVideo: true,
|
||||
publishAudio: hasAudio,
|
||||
mirror: false
|
||||
|
@ -450,7 +450,6 @@ export class OpenViduService {
|
|||
}
|
||||
}
|
||||
|
||||
//TODO: Uncomment this section when replaceTrack issue is fixed
|
||||
private async createMediaStream(pp: PublisherProperties): Promise<MediaStream> {
|
||||
let mediaStream: MediaStream;
|
||||
const isFirefoxPlatform = this.platformService.isFirefox();
|
||||
|
|
Loading…
Reference in New Issue