OpenViduError added

pull/20/head
pabloFuente 2017-10-04 10:30:15 +02:00
parent 9497ba7ea2
commit 9cf9d2a309
12 changed files with 262 additions and 106 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -18,6 +18,7 @@ import { OpenViduInternal } from '../OpenViduInternal/OpenViduInternal';
import { Session } from './Session';
import { Publisher } from './Publisher';
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/OpenViduError';
import * as adapter from 'webrtc-adapter';
import * as screenSharing from '../ScreenSharing/Screen-Capturing.js';
@ -77,7 +78,7 @@ export class OpenVidu {
} else {
if (adapter.browserDetails.browser === 'firefox' && adapter.browserDetails.version >= 52) {
publisher = new Publisher(this.openVidu.initPublisherScreen(parentId), parentId, true);
publisher = new Publisher(this.openVidu.initPublisherScreen(parentId, callback), parentId, true);
screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => {
cameraOptions = {
sendAudio: cameraOptions.audio != null ? cameraOptions.audio : true,
@ -123,19 +124,14 @@ export class OpenVidu {
screenSharingAuto.getScreenId((error, sourceId, screenConstraints) => {
if (error === 'not-installed') {
console.error('Error capturing the screen: an extension is needed');
if (confirm('You need an extension to share your screen!\n\n' +
'This is the URL where you can install it:\n' +
'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk\n\n' +
'Click OK to install it (Pop-Up can be blocked) and then reload this page')) {
window.open(
'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk',
'_blank'
);
}
let error = new OpenViduError(OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, 'https://chrome.google.com/webstore/detail/screen-capturing/ajhifddimkapgcifgcodmmfdlknahffk');
console.error(error);
if (callback) callback(error);
return;
} else if (error === 'permission-denied') {
console.error('Error capturing the screen: Permission Denied');
let error = new OpenViduError(OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
console.error(error);
if (callback) callback(error);
return;
}
@ -156,7 +152,7 @@ export class OpenVidu {
console.error('getScreenId error', error);
return;
});
publisher = new Publisher(this.openVidu.initPublisherScreen(parentId), parentId, true);
publisher = new Publisher(this.openVidu.initPublisherScreen(parentId, callback), parentId, true);
console.info("'Publisher' initialized");
return publisher;
} else {

View File

@ -0,0 +1,21 @@
export enum OpenViduErrorName {
CAMERA_ACCESS_DENIED = 'CAMERA_ACCESS_DENIED',
MICROPHONE_ACCESS_DENIED = 'MICROPHONE_ACCESS_DENIED',
SCREEN_CAPTURE_DENIED = 'SCREEN_CAPTURE_DENIED',
NO_VIDEO_DEVICE = 'NO_VIDEO_DEVICE',
NO_INPUT_DEVICE = 'NO_INPUT_DEVICE',
SCREEN_EXTENSION_NOT_INSTALLED = 'SCREEN_EXTENSION_NOT_INSTALLED',
GENERIC_ERROR = 'GENERIC_ERROR'
}
export class OpenViduError {
name: OpenViduErrorName;
message: string;
constructor(name: OpenViduErrorName, message: string) {
this.name = name;
this.message = message;
}
}

View File

@ -15,6 +15,7 @@
*
*/
import { SessionInternal, SessionOptions } from './SessionInternal';
import { OpenViduError, OpenViduErrorName } from './OpenViduError';
import { Stream } from './Stream';
import * as RpcBuilder from '../KurentoUtils/kurento-jsonrpc';
@ -48,10 +49,12 @@ export class OpenViduInternal {
this.camera.requestCameraAccess((error, camera) => {
if (error) {
console.error("Error accessing the camera", error);
// Neither camera or microphone device is allowed/able to capture media
console.error(error);
if (callback) {
callback(error);
}
this.camera.ee.emitEvent('access-denied-by-publisher');
} else {
this.camera.setVideoElement(this.cameraReady(camera!, parentId));
if (callback) {
@ -67,9 +70,13 @@ export class OpenViduInternal {
this.camera.addOnceEventListener('can-request-screen', () => {
this.camera.requestCameraAccess((error, camera) => {
if (error) {
console.error("Error capturing the screen", error);
this.camera.ee.emitEvent('access-denied-by-publisher');
let errorName: OpenViduErrorName = OpenViduErrorName.SCREEN_CAPTURE_DENIED;
let errorMessage = 'You must allow access to one window of your desktop';
let e = new OpenViduError(errorName, errorMessage);
console.error(e);
if (callback) {
callback(error);
callback(e);
}
}
else {
@ -87,8 +94,12 @@ export class OpenViduInternal {
})
.catch(error => {
this.camera.ee.emitEvent('access-denied-by-publisher');
console.error("Access denied", error);
if (callback) callback(error, this);
console.error("Error accessing the microphone", error);
if (callback) {
let errorName: OpenViduErrorName = OpenViduErrorName.MICROPHONE_ACCESS_DENIED;
let errorMessage = error.toString();
callback(new OpenViduError(errorName, errorMessage));
}
});
} else {
this.camera.isScreenRequestedReady = true;

View File

@ -8,6 +8,7 @@
import { Connection } from './Connection';
import { SessionInternal } from './SessionInternal';
import { OpenViduInternal, Callback } from './OpenViduInternal';
import { OpenViduError, OpenViduErrorName } from './OpenViduError';
import EventEmitter = require('wolfy87-eventemitter');
import * as kurentoUtils from '../KurentoUtils/kurento-utils-js';
@ -82,11 +83,13 @@ export class Stream {
public accessIsAllowed: boolean = false;
public accessIsDenied: boolean = false;
public isScreenRequestedReady: boolean = false;
private isScreenRequested = false;
constructor(private openVidu: OpenViduInternal, private local: boolean, private room: SessionInternal, options: any) {
if (options !== 'screen-options') {
this.configureOptions(options);
} else {
this.isScreenRequested = true;
this.connection = this.room.getLocalParticipant();
}
this.addEventListener('src-added', (srcEvent) => {
@ -361,9 +364,16 @@ export class Stream {
this.userMediaHasVideo((hasVideo) => {
if (!hasVideo) {
if (this.sendVideo) {
callback(new OpenViduError(OpenViduErrorName.NO_VIDEO_DEVICE, 'You have requested camera access but there is no video input device available. Trying to connect with an audio input device only'), this);
}
if (!this.sendAudio) {
callback(new OpenViduError(OpenViduErrorName.NO_INPUT_DEVICE, 'You must init Publisher object with audio or video streams enabled'), undefined);
} else {
constraints.video = false;
this.sendVideo = false;
this.requestCameraAccesAux(constraints, callback);
}
} else {
this.requestCameraAccesAux(constraints, callback);
}
@ -376,21 +386,16 @@ export class Stream {
this.cameraAccessSuccess(userStream, callback);
})
.catch(error => {
/*// Try to ask for microphone only
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(userStream => {
constraints.video = false;
this.sendVideo = false;
this.sendAudio = true;
this.cameraAccessSuccess(userStream, callback);
})
.catch(error => {*/
this.accessIsDenied = true;
this.accessIsAllowed = false;
this.ee.emitEvent('access-denied-by-publisher');
console.error("Access denied", error);
callback(error, this);
let errorName: OpenViduErrorName;
let errorMessage = error.toString();;
if (!this.isScreenRequested) {
errorName = this.sendVideo ? OpenViduErrorName.CAMERA_ACCESS_DENIED : OpenViduErrorName.MICROPHONE_ACCESS_DENIED;
} else {
errorName = OpenViduErrorName.SCREEN_CAPTURE_DENIED; // This code is only reachable for Firefox
}
callback(new OpenViduError(errorName, errorMessage), undefined);
});
}
@ -413,6 +418,12 @@ export class Stream {
}
private userMediaHasVideo(callback) {
// If the user is going to publish its screen there's a video source
if (this.isScreenRequested) {
callback(true);
return;
} else {
// List all input devices and serach for a video kind
navigator.mediaDevices.enumerateDevices().then(function (mediaDevices) {
var videoInput = mediaDevices.filter(function (deviceInfo) {
return deviceInfo.kind === 'videoinput';
@ -420,6 +431,7 @@ export class Stream {
callback(videoInput != null);
});
}
}
publishVideoCallback(error, sdpOfferParam, wp) {

View File

@ -2,3 +2,4 @@ export * from './OpenViduInternal';
export * from './Connection';
export * from './SessionInternal';
export * from './Stream';
export * from './OpenViduError';

View File

@ -10,6 +10,7 @@ import { AppComponent } from './app.component';
import { TestSessionsComponent } from './components/test-sessions/test-sessions.component';
import { TestApirestComponent } from './components/test-apirest/test-apirest.component';
import { OpenviduInstanceComponent } from './components/openvidu-instance/openvidu-instance.component';
import { ExtensionDialogComponent } from './components/openvidu-instance/extension-dialog.component';
import { OpenviduRestService } from './services/openvidu-rest.service';
import { OpenviduParamsService } from './services/openvidu-params.service';
@ -18,7 +19,8 @@ import { OpenviduParamsService } from './services/openvidu-params.service';
AppComponent,
OpenviduInstanceComponent,
TestSessionsComponent,
TestApirestComponent
TestApirestComponent,
ExtensionDialogComponent
],
imports: [
BrowserModule,
@ -32,6 +34,7 @@ import { OpenviduParamsService } from './services/openvidu-params.service';
OpenviduRestService,
OpenviduParamsService
],
entryComponents: [ ExtensionDialogComponent ],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -0,0 +1,36 @@
import { Component, Inject } from '@angular/core';
import { MdDialog, MD_DIALOG_DATA, MdDialogConfig } from '@angular/material';
@Component({
selector: 'app-extension-dialog',
template: `
<div *ngIf="installView">
<h2 md-dialog-title>Install extension</h2>
<md-dialog-content>An extension is needed to share your screen!</md-dialog-content>
<md-dialog-actions>
<button md-button md-dialog-close>CANCEL</button>
<button md-button (click)="goToExtension()">INSTALL</button>
</md-dialog-actions>
</div>
<div *ngIf="!installView" style="text-align: center">
<button md-button (click)="reloadPage()">RELOAD PAGE<br>AFTER INSTALLED</button>
</div>
`
})
export class ExtensionDialogComponent {
installView = true;
constructor(public dialog: MdDialog, @Inject(MD_DIALOG_DATA) public data: any) { }
goToExtension() {
window.open(this.data.url, '_blank');
this.installView = false;
}
reloadPage() {
window.location.reload();
}
}

View File

@ -91,7 +91,9 @@
</md-chip-list>-->
</div>
</div>
<div [attr.id]="'remote-vid-' + session.connection.connectionId" fxFlex="270px" class="video-container"><div [attr.id]="'local-vid-' + session.connection.connectionId"></div></div>
<div [attr.id]="'remote-vid-' + session.connection.connectionId" fxFlex="270px" class="video-container">
<div [attr.id]="'local-vid-' + session.connection.connectionId"></div>
</div>
</div>
</md-card>
</div>

View File

@ -3,6 +3,8 @@ import {
OnInit, OnDestroy, OnChanges
} from '@angular/core';
import { OpenVidu, Session, Subscriber, Publisher, Stream } from 'openvidu-browser';
import { MdDialog, MdDialogRef } from '@angular/material';
import { ExtensionDialogComponent } from './extension-dialog.component';
declare var $: any;
@ -79,7 +81,9 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
events: OpenViduEvent[] = [];
constructor(private changeDetector: ChangeDetectorRef) {
openviduError: any;
constructor(private changeDetector: ChangeDetectorRef, public extensionDialog: MdDialog) {
this.generateSessionInfo();
}
@ -182,17 +186,37 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
this.updateAudioIcon();
this.updateVideoIcon();
this.publisher = OV.initPublisher('local-vid-' + this.session.connection.connectionId, {
this.publisher = OV.initPublisher(
'local-vid-' + this.session.connection.connectionId,
{
audio: this.sendAudio,
video: this.sendVideo,
activeAudio: this.activeAudio,
activeVideo: this.activeVideo,
quality: 'MEDIUM',
screen: this.optionsVideo === 'screen' ? true : false
},
(err) => {
if (err) {
console.warn(err);
this.openviduError = err;
if (err.name === 'SCREEN_EXTENSION_NOT_INSTALLED') {
this.extensionDialog.open(ExtensionDialogComponent, {
data: { url: err.message },
disableClose: true,
width: '250px'
});
}
}
});
this.publisher.on('videoElementCreated', (event) => {
if (this.publishTo && !this.sendVideo) {
if (this.publishTo &&
(!this.sendVideo ||
this.sendVideo &&
!(this.optionsVideo !== 'screen') &&
this.openviduError &&
this.openviduError.name === 'NO_VIDEO_DEVICE')) {
$(event.element).css({ 'background-color': '#4d4d4d' });
$(event.element).attr('poster', 'assets/images/volume.png');
}