From e4cf86bc22c0d1c2787843c049029f9ac814317b Mon Sep 17 00:00:00 2001 From: csantosm <4a.santos@gmail.com> Date: Wed, 20 Jul 2022 14:01:34 +0200 Subject: [PATCH] ionic-cordova: Added mute and toggle media devices --- openvidu-ionic/package.json | 2 +- openvidu-ionic/src/app/app.component.css | 4 + openvidu-ionic/src/app/app.component.html | 153 +++-- openvidu-ionic/src/app/app.component.ts | 759 +++++++++++++--------- 4 files changed, 531 insertions(+), 387 deletions(-) diff --git a/openvidu-ionic/package.json b/openvidu-ionic/package.json index 1f946db5..e7768055 100644 --- a/openvidu-ionic/package.json +++ b/openvidu-ionic/package.json @@ -26,7 +26,7 @@ "@ionic/angular": "6.1.11", "@ionic/cordova-builders": "^6.1.0", "compare-func": "2.0.0", - "cordova-android": "10.1.2", + "cordova-android": "11.0.0", "cordova-ios": "6.2.0", "cordova-plugin-android-permissions": "1.1.3", "cordova-plugin-device": "2.1.0", diff --git a/openvidu-ionic/src/app/app.component.css b/openvidu-ionic/src/app/app.component.css index f9ffd4f6..e83cda7d 100644 --- a/openvidu-ionic/src/app/app.component.css +++ b/openvidu-ionic/src/app/app.component.css @@ -23,4 +23,8 @@ ion-col { padding: 1px; +} + +.action-button { + padding: 5px; } \ No newline at end of file diff --git a/openvidu-ionic/src/app/app.component.html b/openvidu-ionic/src/app/app.component.html index 237e5209..13fd94af 100644 --- a/openvidu-ionic/src/app/app.component.html +++ b/openvidu-ionic/src/app/app.component.html @@ -1,72 +1,103 @@ + + + + + + + + + + - - - - - - - - - - + +
+ +
+

Join a video session

+ + Participant + + + + Session + + - + + + Join + -
-

Join a video session

- - Participant - - - - Session - - + + + + + +
- - - Join - + +
+

{{ mySessionId }}

+
- - - - - + + + + +
+ +
+
-
+ +
+ +
+
+ + - -
-

{{mySessionId}}

-
+ + + + - - - - -
- -
-
+ + + - -
- -
-
+ + + -
-
- - - - - - -
- -
\ No newline at end of file + + + + + + diff --git a/openvidu-ionic/src/app/app.component.ts b/openvidu-ionic/src/app/app.component.ts index 21730e69..5df4c7dd 100644 --- a/openvidu-ionic/src/app/app.component.ts +++ b/openvidu-ionic/src/app/app.component.ts @@ -1,363 +1,472 @@ -import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Component, HostListener, OnDestroy } from '@angular/core'; -import { AndroidPermissions } from '@ionic-native/android-permissions/ngx'; -import { SplashScreen } from '@ionic-native/splash-screen/ngx'; -import { StatusBar } from '@ionic-native/status-bar/ngx'; -import { Platform, AlertController } from '@ionic/angular'; -import { OpenVidu, Publisher, Session, StreamEvent, StreamManager, Subscriber } from 'openvidu-browser'; -import { throwError as observableThrowError } from 'rxjs'; -import { catchError } from 'rxjs/operators'; +import { HttpClient, HttpHeaders } from "@angular/common/http"; +import { Component, HostListener, OnDestroy } from "@angular/core"; +import { AndroidPermissions } from "@ionic-native/android-permissions/ngx"; +import { SplashScreen } from "@ionic-native/splash-screen/ngx"; +import { StatusBar } from "@ionic-native/status-bar/ngx"; +import { Platform, AlertController } from "@ionic/angular"; +import { + Device, + OpenVidu, + Publisher, + PublisherProperties, + Session, + StreamEvent, + StreamManager, + Subscriber, +} from "openvidu-browser"; +import { throwError as observableThrowError } from "rxjs"; +import { catchError } from "rxjs/operators"; @Component({ - selector: 'app-root', - templateUrl: 'app.component.html', - styleUrls: ['app.component.css'], + selector: "app-root", + templateUrl: "app.component.html", + styleUrls: ["app.component.css"], }) export class AppComponent implements OnDestroy { + OPENVIDU_SERVER_URL = "https://" + location.hostname + ":4443"; + OPENVIDU_SERVER_SECRET = "MY_SECRET"; - OPENVIDU_SERVER_URL = 'https://' + location.hostname + ':4443'; - OPENVIDU_SERVER_SECRET = 'MY_SECRET'; + ANDROID_PERMISSIONS = [ + this.androidPermissions.PERMISSION.CAMERA, + this.androidPermissions.PERMISSION.RECORD_AUDIO, + this.androidPermissions.PERMISSION.MODIFY_AUDIO_SETTINGS, + ]; - ANDROID_PERMISSIONS = [ - this.androidPermissions.PERMISSION.CAMERA, - this.androidPermissions.PERMISSION.RECORD_AUDIO, - this.androidPermissions.PERMISSION.MODIFY_AUDIO_SETTINGS - ]; + // OpenVidu objects + OV: OpenVidu; + session: Session; + publisher: StreamManager; // Local + subscribers: StreamManager[] = []; // Remotes - // OpenVidu objects - OV: OpenVidu; - session: Session; - publisher: StreamManager; // Local - subscribers: StreamManager[] = []; // Remotes + // Join form + mySessionId: string; + myUserName: string; - // Join form - mySessionId: string; - myUserName: string; + cameraIcon = "videocam"; + microphoneIcon = "mic"; - constructor( - private platform: Platform, - private splashScreen: SplashScreen, - private statusBar: StatusBar, - private httpClient: HttpClient, - private androidPermissions: AndroidPermissions, - public alertController: AlertController - ) { - this.initializeApp(); - this.generateParticipantInfo(); - } + private devices: Device[]; + private cameras: Device[]; + private microphones: Device[]; + private cameraSelected: Device; + private microphoneSelected: Device; + private isFrontCamera: boolean = false; - initializeApp() { - this.platform.ready().then(() => { - this.statusBar.overlaysWebView(false); - this.splashScreen.hide(); - }); - } + constructor( + private platform: Platform, + private splashScreen: SplashScreen, + private statusBar: StatusBar, + private httpClient: HttpClient, + private androidPermissions: AndroidPermissions, + public alertController: AlertController + ) { + this.initializeApp(); + this.generateParticipantInfo(); + } - @HostListener('window:beforeunload') - beforeunloadHandler() { - // On window closed leave session - this.leaveSession(); - } + initializeApp() { + this.platform.ready().then(() => { + this.statusBar.overlaysWebView(false); + this.splashScreen.hide(); + }); + } - ngOnDestroy() { - // On component destroyed leave session - this.leaveSession(); - } + @HostListener("window:beforeunload") + beforeunloadHandler() { + // On window closed leave session + this.leaveSession(); + } - joinSession() { - // --- 1) Get an OpenVidu object --- + ngOnDestroy() { + // On component destroyed leave session + this.leaveSession(); + } - this.OV = new OpenVidu(); + async joinSession() { + // --- 1) Get an OpenVidu object --- - // --- 2) Init a session --- + this.OV = new OpenVidu(); - this.session = this.OV.initSession(); + this.initDevices(); - // --- 3) Specify the actions when events take place in the session --- + // --- 2) Init a session --- - // On every new Stream received... - this.session.on('streamCreated', (event: StreamEvent) => { - // Subscribe to the Stream to receive it. Second parameter is undefined - // so OpenVidu doesn't create an HTML video on its own - const subscriber: Subscriber = this.session.subscribe(event.stream, undefined); - this.subscribers.push(subscriber); - }); + this.session = this.OV.initSession(); - // On every Stream destroyed... - this.session.on('streamDestroyed', (event: StreamEvent) => { - // Remove the stream from 'subscribers' array - this.deleteSubscriber(event.stream.streamManager); - }); + // --- 3) Specify the actions when events take place in the session --- - // On every asynchronous exception... - this.session.on('exception', (exception) => { - console.warn(exception); - }); + // On every new Stream received... + this.session.on("streamCreated", (event: StreamEvent) => { + // Subscribe to the Stream to receive it. Second parameter is undefined + // so OpenVidu doesn't create an HTML video on its own + const subscriber: Subscriber = this.session.subscribe( + event.stream, + undefined + ); + this.subscribers.push(subscriber); + }); - // --- 4) Connect to the session with a valid user token --- + // On every Stream destroyed... + this.session.on("streamDestroyed", (event: StreamEvent) => { + // Remove the stream from 'subscribers' array + this.deleteSubscriber(event.stream.streamManager); + }); - // 'getToken' method is simulating what your server-side should do. - // 'token' parameter should be retrieved and returned by your own backend - this.getToken().then((token) => { - // First param is the token got from OpenVidu Server. Second param will be used by every user on event - // 'streamCreated' (property Stream.connection.data), and will be appended to DOM as the user's nickname - this.session - .connect(token, { clientData: this.myUserName }) - .then(() => { - // --- 5) Requesting and Checking Android Permissions - if (this.platform.is('cordova')) { - // Ionic platform - if (this.platform.is('android')) { - console.log('Android platform'); - this.checkAndroidPermissions() - .then(() => this.initPublisher()) - .catch(err => console.error(err)); - } else if (this.platform.is('ios')) { - console.log('iOS platform'); - this.initPublisher(); - } - } else { - this.initPublisher(); - } - }) - .catch(error => { - console.log('There was an error connecting to the session:', error.code, error.message); - }); - }); - } + // On every asynchronous exception... + this.session.on("exception", (exception) => { + console.warn(exception); + }); - initPublisher() { - // Init a publisher passing undefined as targetElement (we don't want OpenVidu to insert a video - // element: we will manage it on our own) and with the desired properties - const publisher: Publisher = this.OV.initPublisher(undefined, { - audioSource: undefined, // The source of audio. If undefined default microphone - videoSource: undefined, // The source of video. If undefined default webcam - publishAudio: true, // Whether you want to start publishing with your audio unmuted or not - publishVideo: true, // Whether you want to start publishing with your video enabled or not - resolution: '640x480', // The resolution of your video - frameRate: 30, // The frame rate of your video - insertMode: 'APPEND', // How the video is inserted in the target element 'video-container' - mirror: true // Whether to mirror your local video or not - }); + // --- 4) Connect to the session with a valid user token --- - // --- 6) Publish your stream --- + try { + // 'getToken' method is simulating what your server-side should do. + // 'token' parameter should be retrieved and returned by your own backend + const token = await this.getToken(); + // First param is the token got from OpenVidu Server. Second param will be used by every user on event + // 'streamCreated' (property Stream.connection.data), and will be appended to DOM as the user's nickname + await this.session.connect(token, { clientData: this.myUserName }); - this.session.publish(publisher).then(() => { - // Store our Publisher - this.publisher = publisher; - }); - } + // --- 5) Requesting and Checking Android Permissions + if (this.platform.is("cordova")) { + // Ionic platform + if (this.platform.is("android")) { + console.log("Android platform"); + await this.checkAndroidPermissions(); + this.initPublisher(); + } else if (this.platform.is("ios")) { + console.log("iOS platform"); + this.initPublisher(); + } + } else { + this.initPublisher(); + } + } catch (error) { + console.log( + "There was an error connecting to the session:", + error.code, + error.message + ); + } + } - leaveSession() { - // --- 7) Leave the session by calling 'disconnect' method over the Session object --- + async initPublisher() { + // Init a publisher passing undefined as targetElement (we don't want OpenVidu to insert a video + // element: we will manage it on our own) and with the desired properties + const publisher: Publisher = await this.OV.initPublisherAsync(undefined, { + audioSource: this.microphones[0].deviceId, // The source of audio. If undefined default microphone + videoSource: this.cameras[0].deviceId, // The source of video. If undefined default webcam + publishAudio: true, // Whether you want to start publishing with your audio unmuted or not + publishVideo: true, // Whether you want to start publishing with your video enabled or not + resolution: "640x480", // The resolution of your video + frameRate: 30, // The frame rate of your video + insertMode: "APPEND", // How the video is inserted in the target element 'video-container' + mirror: this.isFrontCamera, // Whether to mirror your local video or not + }); - if (this.session) { - this.session.disconnect(); - } + // --- 6) Publish your stream --- - // Empty all properties... - this.subscribers = []; - delete this.publisher; - delete this.session; - delete this.OV; - this.generateParticipantInfo(); - } + await this.session.publish(publisher); + // Store our Publisher + this.publisher = publisher; + } - private checkAndroidPermissions(): Promise { - return new Promise((resolve, reject) => { - this.platform.ready().then(() => { - this.androidPermissions - .requestPermissions(this.ANDROID_PERMISSIONS) - .then(() => { - this.androidPermissions - .checkPermission(this.androidPermissions.PERMISSION.CAMERA) - .then(camera => { - this.androidPermissions - .checkPermission(this.androidPermissions.PERMISSION.RECORD_AUDIO) - .then(audio => { - this.androidPermissions - .checkPermission(this.androidPermissions.PERMISSION.MODIFY_AUDIO_SETTINGS) - .then(modifyAudio => { - if (camera.hasPermission && audio.hasPermission && modifyAudio.hasPermission) { - resolve(); - } else { - reject( - new Error( - 'Permissions denied: ' + - '\n' + - ' CAMERA = ' + - camera.hasPermission + - '\n' + - ' AUDIO = ' + - audio.hasPermission + - '\n' + - ' AUDIO_SETTINGS = ' + - modifyAudio.hasPermission, - ), - ); - } - }) - .catch(err => { - console.error( - 'Checking permission ' + - this.androidPermissions.PERMISSION.MODIFY_AUDIO_SETTINGS + - ' failed', - ); - reject(err); - }); - }) - .catch(err => { - console.error( - 'Checking permission ' + this.androidPermissions.PERMISSION.RECORD_AUDIO + ' failed', - ); - reject(err); - }); - }) - .catch(err => { - console.error('Checking permission ' + this.androidPermissions.PERMISSION.CAMERA + ' failed'); - reject(err); - }); - }) - .catch(err => console.error('Error requesting permissions: ', err)); - }); - }); - } + leaveSession() { + // --- 7) Leave the session by calling 'disconnect' method over the Session object --- - private generateParticipantInfo() { - // Random user nickname and sessionId - this.mySessionId = 'SessionA'; - this.myUserName = 'Participant' + Math.floor(Math.random() * 100); - } + if (this.session) { + this.session.disconnect(); + } - private deleteSubscriber(streamManager: StreamManager): void { - const index = this.subscribers.indexOf(streamManager, 0); - if (index > -1) { - this.subscribers.splice(index, 1); - } - } + // Empty all properties... + this.subscribers = []; + delete this.publisher; + delete this.session; + delete this.OV; + this.generateParticipantInfo(); + } - async presentSettingsAlert() { - const alert = await this.alertController.create({ - header: 'OpenVidu Server config', - inputs: [ - { - name: 'url', - type: 'text', - value: 'https://demos.openvidu.io', - placeholder: 'URL' - }, - { - name: 'secret', - type: 'text', - value: 'MY_SECRET', - placeholder: 'Secret' - } - ], - buttons: [ - { - text: 'Cancel', - role: 'cancel', - cssClass: 'secondary' - }, { - text: 'Ok', - handler: data => { - this.OPENVIDU_SERVER_URL = data.url; - this.OPENVIDU_SERVER_SECRET = data.secret; - } - } - ] - }); + async swapCamera() { + try { + const newCamera = this.cameras.find( + (cam) => cam.deviceId !== this.cameraSelected.deviceId + ); + if (!!newCamera) { - await alert.present(); - } + this.isFrontCamera = !this.isFrontCamera; + const pp: PublisherProperties = { + videoSource: newCamera.deviceId, + audioSource: false, + mirror: this.isFrontCamera + }; - /* - * -------------------------- - * SERVER-SIDE RESPONSIBILITY - * -------------------------- - * This method retrieve the mandatory user token from OpenVidu Server, - * in this case making use Angular http API. - * This behaviour MUST BE IN YOUR SERVER-SIDE IN PRODUCTION. In this case: - * 1) Initialize a Session in OpenVidu Server (POST /openvidu/api/sessions) - * 2) Create a Connection in OpenVidu Server (POST /openvidu/api/sessions//connection) - * 3) The Connection.token must be consumed in Session.connect() method - */ + // Stopping the video tracks after request for another MediaStream + this.publisher.stream.getMediaStream().getVideoTracks().forEach((track) => { + track.stop(); + }); + const newTrack = await this.OV.getUserMedia(pp); + const videoTrack: MediaStreamTrack = newTrack.getVideoTracks()[0]; + await (this.publisher as Publisher).replaceTrack(videoTrack); + this.cameraSelected = newCamera; + } + } catch (error) { + console.error(error); + } + } + toggleCamera() { + const publish = !this.publisher.stream.videoActive; + (this.publisher as Publisher).publishVideo(publish, true); + this.cameraIcon = publish ? "videocam" : "eye-off"; + } - getToken(): Promise { - if (this.platform.is('ios') && this.platform.is('cordova') && this.OPENVIDU_SERVER_URL === 'https://localhost:4443') { - // To make easier first steps with iOS apps, use demos OpenVidu Sever if no custom valid server is configured - this.OPENVIDU_SERVER_URL = 'https://demos.openvidu.io'; - } - return this.createSession(this.mySessionId).then((sessionId) => { - return this.createToken(sessionId); - }); - } + toggleMicrophone() { + const publish = !this.publisher.stream.audioActive; + (this.publisher as Publisher).publishAudio(publish); + this.microphoneIcon = publish ? "mic" : "mic-off"; + } - createSession(sessionId) { - return new Promise((resolve, reject) => { - const body = JSON.stringify({ customSessionId: sessionId }); - const options = { - headers: new HttpHeaders({ - Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + this.OPENVIDU_SERVER_SECRET), - 'Content-Type': 'application/json', - }), - }; - return this.httpClient - .post(this.OPENVIDU_SERVER_URL + '/openvidu/api/sessions', body, options) - .pipe( - catchError((error) => { - if (error.status === 409) { - resolve(sessionId); - } else { - console.warn( - 'No connection to OpenVidu Server. This may be a certificate error at ' + - this.OPENVIDU_SERVER_URL, - ); - if ( - window.confirm( - 'No connection to OpenVidu Server. This may be a certificate error at "' + - this.OPENVIDU_SERVER_URL + - // tslint:disable-next-line:max-line-length - '"\n\nClick OK to navigate and accept it. If no certificate warning is shown, then check that your OpenVidu Server' + - 'is up and running at "' + - this.OPENVIDU_SERVER_URL + - '"', - ) - ) { - location.assign(this.OPENVIDU_SERVER_URL + '/accept-certificate'); - } - } - return observableThrowError(error); - }), - ) - .subscribe((response) => { - console.log(response); - resolve(response['id']); - }); - }); - } + private async initDevices() { + this.devices = await this.OV.getDevices(); - createToken(sessionId): Promise { - return new Promise((resolve, reject) => { - const body = JSON.stringify({}); - const options = { - headers: new HttpHeaders({ - Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + this.OPENVIDU_SERVER_SECRET), - 'Content-Type': 'application/json', - }), - }; - return this.httpClient - .post(this.OPENVIDU_SERVER_URL + '/openvidu/api/sessions/' + sessionId + '/connection', body, options) - .pipe( - catchError((error) => { - reject(error); - return observableThrowError(error); - }), - ) - .subscribe((response) => { - console.log(response); - resolve(response['token']); - }); - }); - } + this.cameras = this.devices.filter((d) => d.kind === "videoinput"); + this.microphones = this.devices.filter( + (d) => d.kind === "audioinput" && d.label !== "Default" + ); + + this.cameraSelected = this.cameras[0]; + this.microphoneSelected = this.microphones[0]; + } + + private checkAndroidPermissions(): Promise { + return new Promise((resolve, reject) => { + this.platform.ready().then(() => { + this.androidPermissions + .requestPermissions(this.ANDROID_PERMISSIONS) + .then(() => { + this.androidPermissions + .checkPermission(this.androidPermissions.PERMISSION.CAMERA) + .then((camera) => { + this.androidPermissions + .checkPermission( + this.androidPermissions.PERMISSION.RECORD_AUDIO + ) + .then((audio) => { + this.androidPermissions + .checkPermission( + this.androidPermissions.PERMISSION.MODIFY_AUDIO_SETTINGS + ) + .then((modifyAudio) => { + if ( + camera.hasPermission && + audio.hasPermission && + modifyAudio.hasPermission + ) { + resolve(); + } else { + reject( + new Error( + "Permissions denied: " + + "\n" + + " CAMERA = " + + camera.hasPermission + + "\n" + + " AUDIO = " + + audio.hasPermission + + "\n" + + " AUDIO_SETTINGS = " + + modifyAudio.hasPermission + ) + ); + } + }) + .catch((err) => { + console.error( + "Checking permission " + + this.androidPermissions.PERMISSION + .MODIFY_AUDIO_SETTINGS + + " failed" + ); + reject(err); + }); + }) + .catch((err) => { + console.error( + "Checking permission " + + this.androidPermissions.PERMISSION.RECORD_AUDIO + + " failed" + ); + reject(err); + }); + }) + .catch((err) => { + console.error( + "Checking permission " + + this.androidPermissions.PERMISSION.CAMERA + + " failed" + ); + reject(err); + }); + }) + .catch((err) => console.error("Error requesting permissions: ", err)); + }); + }); + } + + private generateParticipantInfo() { + // Random user nickname and sessionId + this.mySessionId = "SessionA"; + this.myUserName = "Participant" + Math.floor(Math.random() * 100); + } + + private deleteSubscriber(streamManager: StreamManager): void { + const index = this.subscribers.indexOf(streamManager, 0); + if (index > -1) { + this.subscribers.splice(index, 1); + } + } + + async presentSettingsAlert() { + const alert = await this.alertController.create({ + header: "OpenVidu Server config", + inputs: [ + { + name: "url", + type: "text", + value: "https://demos.openvidu.io", + placeholder: "URL", + }, + { + name: "secret", + type: "text", + value: "MY_SECRET", + placeholder: "Secret", + }, + ], + buttons: [ + { + text: "Cancel", + role: "cancel", + cssClass: "secondary", + }, + { + text: "Ok", + handler: (data) => { + this.OPENVIDU_SERVER_URL = data.url; + this.OPENVIDU_SERVER_SECRET = data.secret; + }, + }, + ], + }); + + await alert.present(); + } + + /* + * -------------------------- + * SERVER-SIDE RESPONSIBILITY + * -------------------------- + * This method retrieve the mandatory user token from OpenVidu Server, + * in this case making use Angular http API. + * This behaviour MUST BE IN YOUR SERVER-SIDE IN PRODUCTION. In this case: + * 1) Initialize a Session in OpenVidu Server (POST /openvidu/api/sessions) + * 2) Create a Connection in OpenVidu Server (POST /openvidu/api/sessions//connection) + * 3) The Connection.token must be consumed in Session.connect() method + */ + + getToken(): Promise { + if ( + this.platform.is("ios") && + this.platform.is("cordova") && + this.OPENVIDU_SERVER_URL === "https://localhost:4443" + ) { + // To make easier first steps with iOS apps, use demos OpenVidu Sever if no custom valid server is configured + this.OPENVIDU_SERVER_URL = "https://demos.openvidu.io"; + } + return this.createSession(this.mySessionId).then((sessionId) => { + return this.createToken(sessionId); + }); + } + + createSession(sessionId) { + return new Promise((resolve, reject) => { + const body = JSON.stringify({ customSessionId: sessionId }); + const options = { + headers: new HttpHeaders({ + Authorization: + "Basic " + btoa("OPENVIDUAPP:" + this.OPENVIDU_SERVER_SECRET), + "Content-Type": "application/json", + }), + }; + return this.httpClient + .post( + this.OPENVIDU_SERVER_URL + "/openvidu/api/sessions", + body, + options + ) + .pipe( + catchError((error) => { + if (error.status === 409) { + resolve(sessionId); + } else { + console.warn( + "No connection to OpenVidu Server. This may be a certificate error at " + + this.OPENVIDU_SERVER_URL + ); + if ( + window.confirm( + 'No connection to OpenVidu Server. This may be a certificate error at "' + + this.OPENVIDU_SERVER_URL + + // tslint:disable-next-line:max-line-length + '"\n\nClick OK to navigate and accept it. If no certificate warning is shown, then check that your OpenVidu Server' + + 'is up and running at "' + + this.OPENVIDU_SERVER_URL + + '"' + ) + ) { + location.assign( + this.OPENVIDU_SERVER_URL + "/accept-certificate" + ); + } + } + return observableThrowError(error); + }) + ) + .subscribe((response) => { + console.log(response); + resolve(response["id"]); + }); + }); + } + + createToken(sessionId): Promise { + return new Promise((resolve, reject) => { + const body = JSON.stringify({}); + const options = { + headers: new HttpHeaders({ + Authorization: + "Basic " + btoa("OPENVIDUAPP:" + this.OPENVIDU_SERVER_SECRET), + "Content-Type": "application/json", + }), + }; + return this.httpClient + .post( + this.OPENVIDU_SERVER_URL + + "/openvidu/api/sessions/" + + sessionId + + "/connection", + body, + options + ) + .pipe( + catchError((error) => { + reject(error); + return observableThrowError(error); + }) + ) + .subscribe((response) => { + console.log(response); + resolve(response["token"]); + }); + }); + } }