@peterkhang wrote:
I am using kurento-magic-mirror client sources to connect to kurento server.
I have migrated this source to ionic
import { Component, OnInit,ViewChild,ElementRef, HostListener, NgZone } from '@angular/core' import { AuthServiceProvider } from 'src/app/providers/auth-service/auth-service' import { v4 as uuidv4 } from 'uuid' import { environment } from 'src/environments/environment' import { WebRtcPeer, KurentoClient } from 'kurento-utils' import { QueueingSubject } from 'queueing-subject' import { Subscription, Observable, timer } from 'rxjs' import { Timer } from 'interval-timer' import { share, switchMap, retryWhen, delay, map } from 'rxjs/operators' import { PushEvent, Status } from 'src/app/providers/common/common' import { AndroidPermissions } from '@ionic-native/android-permissions/ngx'; import makeWebSocketObservalbe, { normalClosureMessage, WebSocketOptions, GetWebSocketResponses, } from 'rxjs-websockets' //https://github.com/webhacking/WebRTC-Example-With-Typescript/blob/master/src/main.ts @Component({ selector: 'app-webrtc', templateUrl: './webrtc.page.html', styleUrls: ['./webrtc.page.scss'], }) export class WebrtcPage implements OnInit { isRecording = false @ViewChild('videoInput',{read: ElementRef,static: true}) videoInput: ElementRef<HTMLElement> @ViewChild('videoOutput',{read: ElementRef,static: true}) videoOutput: ElementRef<HTMLElement> webRtcPeer: WebRtcPeer = null input: QueueingSubject<string> = null websocket: Observable<GetWebSocketResponses<string>> = null messages: Observable<string | ArrayBuffer | Blob> = null messagesSubscription: Subscription = null isSubscribed: boolean = false status: Status = Status.I_CAN_START loading = null I_CAN_START = 0 I_CAN_STOP = 1 I_AM_STARTING = 2 constructor(public auth: AuthServiceProvider, public androidPermissions: AndroidPermissions) { } ngOnInit() { } IonViewDidEnter() { } IonViewWillLeave() { if( this.webRtcPeer ) { this.stop() } if( this.isConnected() ) { this.close() } } isConnected(): boolean { return this.messagesSubscription && !this.messagesSubscription.closed } send(message: any): void { try { this.input.next(JSON.stringify(message)) } catch(e) { console.log('socket send error : ' + JSON.stringify(e)) this.closeWebsocket() } } closeWebsocket() { try { this.messagesSubscription.unsubscribe() } catch(e) {} this.messagesSubscription = null this.messages = null this.websocket = null try { this.input.unsubscribe() } catch(e) {} this.input = null this.isSubscribed = false } startResponse(message) { this.status = Status.I_CAN_STOP console.log("SDP answer received from server. Processing ..."); this.webRtcPeer.processAnswer(message.sdpAnswer, function(error) { if (error) return console.error(error); }); } connect() { if( this.isConnected() ) { this.closeWebsocket() } this.isSubscribed = false // this.eventList = [] // this.eventList.unshift({path: 'SEND', message: PushEvent.CONNECT}) this.input = new QueueingSubject<string>() this.websocket = makeWebSocketObservalbe(environment.wsHostUrl) this.messages = this.websocket.pipe( switchMap((getResponses: GetWebSocketResponses) => { console.log('websocket opened') return getResponses(this.input) }), retryWhen((errors) => { errors.subscribe(sourceError => { console.log(JSON.stringify(sourceError)) }) return Observable.create(obs => obs.eror(PushEvent.DISCONNECTED)) }), share(), ) this.messagesSubscription = this.messages.subscribe( (message: string | ArrayBuffer | Blob ) => { try { let received: any = null if( message instanceof ArrayBuffer ) { received = JSON.parse(String.fromCharCode.apply(null, new Uint16Array(message))) } else if( message instanceof Blob ) { throw new Error('Blob message is not allowed') } else { console.log('received message:', message) received = JSON.parse(message) } var parsedMessage = received.data console.info('Received message: ' + parsedMessage) switch (parsedMessage.id) { case 'startResponse': this.startResponse(parsedMessage); break; case 'error': if (this.status === Status.I_AM_STARTING) { this.status = Status.I_CAN_START } console.log("Error message from server: " + parsedMessage.message); break; case 'iceCandidate': this.webRtcPeer.addIceCandidate(parsedMessage.candidate, function (error) { if (error) { console.error("Error adding candidate: " + error); return; } }); break; default: if (this.status === Status.I_AM_STARTING) { this.status = Status.I_CAN_START } console.log('Unrecognized message', parsedMessage); } } catch(e) { console.log(JSON.stringify(e)) } }, (error: Error) => { const { message } = error if (message === normalClosureMessage) { // this.eventList.unshift({path: 'RECV', message: PushEvent.UNSUBSCRBE}) this.closeWebsocket() } else { // this.eventList.unshift({path: 'RECV', message: PushEvent.UNSUBSCRBE}) console.log('socket was disconnected due to error: ', message) this.closeWebsocket() } }, () => { console.log('the connection was closed in response to the user') // this.eventList.unshift({path: 'RECV', message: PushEvent.CLOSED}) this.closeWebsocket() } ) } close() { try { if( this.isSubscribed ) { //this.unsubscribe() } const localTimer = new Timer({ startTime: 300, endTime: null, updateFrequency: null, selfAdjust: true, countdown: false, animationFrame: false }) localTimer.on('start', () => { // this.eventList.unshift({path: 'RECV', message: PushEvent.CLOSED}) this.closeWebsocket() }) localTimer.start() } catch(e) {} } onOffer(offerSdp) { console.info('Invoking SDP offer callback function ' + location.host); var message = { id : 'start', sdpOffer : offerSdp } this.send(message); } onIceCandidate(candidate) { console.log("Local candidate" + JSON.stringify(candidate)); var message = { id: 'onIceCandidate', candidate: candidate }; this.send(message); } async startAfterCheckPermission() { var list = [ this.androidPermissions.PERMISSION.CAMERA, this.androidPermissions.PERMISSION.MODIFY_AUDIO_SETTINGS, this.androidPermissions.PERMISSION.RECORD_AUDIO, this.androidPermissions.PERMISSION.INTERNET, this.androidPermissions.PERMISSION.WRITE_EXTERNAL_STORAGE, ] this.androidPermissions.requestPermissions(list).then( result => { if( result.hasPermission ) this.start() else this.auth.presentAlert('Media Device Permission Not Granted') }, err => { this.auth.showError(err) }) } async start() { console.log("Starting video call ...") this.status = Status.I_AM_STARTING this.loading = await this.auth.showLoading() console.log("Creating WebRtcPeer and generating local sdp offer ..."); var constraints = { audio: true, video: { width: 640, framerate: 15 } } var options = { audio: true, localVideo: this.videoInput, remoteVideo: this.videoOutput, onicecandidate: this.onIceCandidate, mediaConstraints: constraints, } this.webRtcPeer = new WebRtcPeer.WebRtcPeerSendrecv(options, function (error) { if (error) { return console.error(error); } this.webRtcPeer.generateOffer(this.onOffer); }); if( ! this.websocket ) { this.auth.presentAlert('Cannot create webRtc adapter') this.loading.dismiss() } else { if( !this.isConnected() ) { this.connect() } } } stop() { console.log("Stopping video call ..."); this.status = Status.I_CAN_START if (this.webRtcPeer) { this.webRtcPeer.dispose(); this.webRtcPeer = null; var message = { id : 'stop' } this.send(message); } this.loading.dismiss() } }
But this.webRtcPeer = new WebRtcPeer.WebRtcPeerSendrecv() returns null: So I have got error as followings .
2020-04-26 15:46:28.777 10434-10716/io.bory.speechmate E/cr_VideoCapture: CameraDevice.StateCallback onOpened 2020-04-26 15:46:28.778 10434-10716/io.bory.speechmate V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0 2020-04-26 15:46:28.782 10434-10716/io.bory.speechmate I/CameraManager: getCameraCharacteristics : cameraId = 1 2020-04-26 15:46:28.785 10434-10716/io.bory.speechmate I/CameraManager: getCameraCharacteristics : cameraId = 1 2020-04-26 15:46:28.821 3647-3788/? D/MdnieScenarioControlService: packageName : io.bory.speechmate className : io.bory.speechmate.MainActivity 2020-04-26 15:46:28.887 10434-10434/io.bory.speechmate E/chromium: [ERROR:web_contents_delegate.cc(218)] WebContentsDelegate::CheckMediaAccessPermission: Not supported. 2020-04-26 15:46:28.905 10434-10434/io.bory.speechmate E/Capacitor/Console: File: http://localhost/93-es2015.7ef3d9410b63064250ff.js - Line 1 - Msg: TypeError: Cannot read property 'generateOffer' of undefined
Posts: 1
Participants: 1