From 8f9bdfaac2799b28b0f65f7fb212d3495c26e0b3 Mon Sep 17 00:00:00 2001 From: "venbatechnologies@gmail.com" Date: Fri, 18 Sep 2020 14:35:32 +0530 Subject: [PATCH] New token interceptor handling token refresh,schedule date picker issue, video chat and recording changes --- ng6-seed/src/app/AwsService/aws.service.ts | 5 + .../src/app/AwsService/cognito.service.ts | 17 +- ng6-seed/src/app/_guard/auth.guard.ts | 2 +- .../src/app/_guard/req-token.interceptor.ts | 260 +++++++++ ng6-seed/src/app/app.module.ts | 3 +- .../layouts/admin/admin-layout.component.ts | 2 +- .../list-pd/all-pd/all-pd.component.html | 2 +- .../schedule-pd/schedule-pd.component.ts | 19 +- .../pd-service/pd-triger.service.ts | 5 + .../qc-list/qc-view/qc-view.component.ts | 44 +- .../quality-check/qc-service/qc.service.ts | 4 + .../app/video-chat/video-chat.component.html | 8 +- .../app/video-chat/video-chat.component.scss | 12 + .../app/video-chat/video-chat.component.ts | 497 +++++++++++------- ng6-seed/src/index.html | 3 +- ng6-seed/src/typings.d.ts | 5 +- 16 files changed, 664 insertions(+), 224 deletions(-) create mode 100644 ng6-seed/src/app/_guard/req-token.interceptor.ts diff --git a/ng6-seed/src/app/AwsService/aws.service.ts b/ng6-seed/src/app/AwsService/aws.service.ts index 2ece5b1d7..615bc3e1a 100755 --- a/ng6-seed/src/app/AwsService/aws.service.ts +++ b/ng6-seed/src/app/AwsService/aws.service.ts @@ -544,7 +544,12 @@ export class AwsService { getlocale(){ let session:any = this.shared.getAccessToken() || ""; + if(session && session != "") { return session.idToken.payload.locale; + } + else{ + return session + } } adminchangeData(userData,changeusers){ diff --git a/ng6-seed/src/app/AwsService/cognito.service.ts b/ng6-seed/src/app/AwsService/cognito.service.ts index 4d4f66e37..b34a39d85 100755 --- a/ng6-seed/src/app/AwsService/cognito.service.ts +++ b/ng6-seed/src/app/AwsService/cognito.service.ts @@ -129,26 +129,33 @@ isloggin:boolean = false; // } refresh() { let tokenexp:boolean; - this.getCurrentUser().getSession(function (err, session) { + return Observable.create(observer=>{ + console.log("Current user check in token refresh fun",this.getCurrentUser()) + return this.getCurrentUser().getSession(function (err, session) { if (err) { + console.log("Error Refreshing token",err); } else { if (session.isValid()) { tokenexp = session.isValid(); of(tokenexp) - + console.log("CognitoUtil: refreshed successfully"); } else { - tokenexp = session.isValid(); + tokenexp = session.isValid(); + console.log("CognitoUtil: refreshed but session is still not valid"); } } - return tokenexp; + observer.next(tokenexp) + observer.complete() }); +}); } getAccessToken(){ - this.refresh(); + // console.log("Starting Token Refresh in getAccessToken") + this.refresh() let jwttoken = ''; if (this.getCurrentUser() != null) { //console.log(JSON.stringify(this.getCurrentUser())); diff --git a/ng6-seed/src/app/_guard/auth.guard.ts b/ng6-seed/src/app/_guard/auth.guard.ts index 8b7e970b3..babbb94ab 100755 --- a/ng6-seed/src/app/_guard/auth.guard.ts +++ b/ng6-seed/src/app/_guard/auth.guard.ts @@ -21,7 +21,7 @@ export class AuthGuard implements CanActivate, CanActivateChild { canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { - if (this.shared.getToken()) { + if (this.shared.getCurrentUser() != null && this.shared.getToken()) { // alert("if"); return true; diff --git a/ng6-seed/src/app/_guard/req-token.interceptor.ts b/ng6-seed/src/app/_guard/req-token.interceptor.ts new file mode 100644 index 000000000..efc34e00f --- /dev/null +++ b/ng6-seed/src/app/_guard/req-token.interceptor.ts @@ -0,0 +1,260 @@ +import { Injectable, Injector } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpInterceptor, + HttpSentEvent, + HttpHeaderResponse, + HttpProgressEvent, + HttpResponse, + HttpUserEvent, + HttpEvent +} from '@angular/common/http'; +// import { AuthGuard } from './auth.guard'; +import { Observable, of, BehaviorSubject, throwError} from 'rxjs'; + +// import { Router } from '@angular/router'; + +import { switchMap, tap, catchError, finalize } from 'rxjs/operators'; +import { HttpErrorResponse } from "@angular/common/http"; +import { Router } from '@angular/router'; +import { CognitoService } from 'app/AwsService/cognito.service'; +import { LoaderService } from 'app/shared/loaderService/loader.service'; +import { environment } from '../../environments/environment'; +import { AwsService } from 'app/AwsService/aws.service'; + + + +@Injectable({ + providedIn: 'root' +}) +export class ReqTokenInterceptor implements HttpInterceptor{ + + constructor( private router: Router,public shared:CognitoService,private loaderService:LoaderService,private awsService:AwsService) { + + } + isRefreshingToken: boolean = false; + tokenSubject: BehaviorSubject = new BehaviorSubject(null); + + addToken(req: HttpRequest, token: string): HttpRequest { + + return req.clone({ + setHeaders: { + 'Authorization': environment.authorization, + 'Token': token + } + }) + } +// addToken1(req: HttpRequest, token: string): HttpRequest { + +// console.log("Token 1",token,req); +// return req.clone({ setHeaders: {'Authorization': environment.authorization, +// 'Token':token, +// // 'From':'2', +// }}) +// } +intercept(req: HttpRequest, next: HttpHandler): Observable | HttpUserEvent> { + + let token:any = this.shared.getAccessToken() ||""; + // console.log("Token From Interceptor >>",cognitoService.getToken()) + if(token!=''){ + token=token.getIdToken().getJwtToken() + } + this.showLoader(); + // return next.handle(this.addToken(req, token)).pipe( + // catchError(error => { + // this.onEnd(); + // console.log("Initial Error",error); + // if (error instanceof HttpErrorResponse) { + // if((error).status) { + // return this.handle401Error(req,next,error) + // } + // else{ + // return this.handle401Error(req,next,error) + // } + // } else { + // console.log("observable error") + // return Observable.throw(error); + // } + // })); + return next.handle(this.addToken(req, token)).pipe( + catchError(error => { + console.log("Initial Error",error); + if (error instanceof HttpErrorResponse) { + if((error).status) { + return this.handle401Error(req,next,error) + } + else{ + return this.handle401Error(req,next,error) + } + } else { + console.log("observable error") + return Observable.throw(error); + } + }), + finalize(()=>{ + this.onEnd() + }) + ) + } + + handle401Error(req: HttpRequest, next: HttpHandler,err) { + console.log("err",err) + console.log("entered",this.isRefreshingToken,this.tokenSubject); + + if (err instanceof HttpErrorResponse) { + + if(err.status == 401 && err.error.error.toLowerCase() == 'invalid token!'){ + console.log("Refreshing Token",err.status) + if (!this.isRefreshingToken) { + this.isRefreshingToken = true; + + // Reset here so that the following requests wait until the token + // comes back from the refreshToken call. + this.tokenSubject.next(null); + console.log("STARTING TOKEN REFRESH") + // return this.shared.refresh() + // .subscribe((newToken: string) => { + // console.log("new",newToken) + // if (newToken) { + // let token:any = this.shared.getAccessToken() ||""; + // this.tokenSubject.next( token.getIdToken().getJwtToken()); + // console.log(this.tokenSubject); + // return next.handle(this.addToken1(req, token.getIdToken().getJwtToken())) + // // .pipe(tap((event:HttpEvent)=>{ + // // if (event instanceof HttpResponse) { + // // this.onEnd(); + // // } + // // }, + // // (err: any) => { + // // this.handleError('role',err); + // // console.log("Error on Refresh token",err) + // // this.onEnd(); + // // })); + // } + + // // If we don't get a new token, we are in trouble so logout. + // return this.awsService.logout(); + // },err=>console.log("Error refresh",err)) + return this.shared.refresh().pipe( + switchMap((newToken: string) =>{ + console.log("New Token",newToken) + if(newToken){ + this.isRefreshingToken=false + this.tokenSubject.next(newToken); + let token:any = this.shared.getAccessToken() ||""; + this.showLoader(); + return next.handle(this.addToken(req, token.getIdToken().getJwtToken())).pipe(tap((event:HttpEvent)=>{ + if (event instanceof HttpResponse) { + this.onEnd(); + } + }, + (err: any) => { + this.handleError('role',err); + console.log("Error on Refresh token",err) + this.onEnd(); + })); + } + + return this.awsService.logout(); + }) + ) + + // .catch(error => { + // // If there is an exception calling 'refreshToken', bad news so logout. + // return this.logoutUser(); + // }) + // .finally(() => { + // this.isRefreshingToken = false; + // }); + } else { + console.log("Else Part 1201") + // return this.tokenSubject + // // .filter(token => token != null) + // .take(1) + // .switchMap(token => { + let token:any = this.shared.getAccessToken() ||""; + this.showLoader(); + return next.handle(this.addToken(req,token.getIdToken().getJwtToken())).pipe(tap((event:HttpEvent)=>{ + if (event instanceof HttpResponse) { + this.onEnd(); + } + }, + (err: any) => { + this.handleError('role',err); + console.log("Error on Refresh token",err) + this.onEnd(); + })); + // }); + } + } + else{ + // return Observable.throw("Observable throw",err); + return this.handleError('',err) + } +} + else{ + return Observable.throw("Observable throw",err); + } +} + + +private handleError (operation = 'operation', error?: T) { + // return (error: any): Observable => { + console.log("d",error) + if(error instanceof HttpErrorResponse){ + // this.onEnd(); + console.log("Error from interceptor >>>",error) + console.error("Error: " + error.status); + if(error.status == 401){ + localStorage.clear(); + this.router.navigate(['/authentication/login']); + } + else if(error.status == 404){ + this.router.navigate(['/error/404']); + } + else if(error.status == 503){ + this.router.navigate(['/error/503']); + } + else if(error.status == 0){ + console.log("NO Internet") + this.router.navigate(['/error/404']); + } + else{ + // alert("Please Check your Internet connection"); + let errorMessage = ''; + let type : number; + if (error.error instanceof ErrorEvent) { + // client-side error + errorMessage = `Error: ${error.error.message}`; + type = 1; + } else { + // server-side error + errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`; + type = 2; + } + + return throwError({error_status :type == 2 ? error.status : '', + error_message:error.message, + error_text :type == 2 ? error.statusText : '', + html_format :errorMessage, + error_type :type, + }); + } + return throwError(error); + } + // }; +} + // }; + // } + + private onEnd(): void { + this.hideLoader(); + } + private showLoader(): void { + this.loaderService.show(); + } + private hideLoader(): void { + this.loaderService.hide(); + } +} \ No newline at end of file diff --git a/ng6-seed/src/app/app.module.ts b/ng6-seed/src/app/app.module.ts index 02f149121..989ef549f 100755 --- a/ng6-seed/src/app/app.module.ts +++ b/ng6-seed/src/app/app.module.ts @@ -64,6 +64,7 @@ import { VideoChatComponent } from './video-chat/video-chat.component' import { PushNotifyService } from './shared/push-notify.service'; import { MatVideoModule } from 'mat-video'; import { VideoPlayerComponent } from './video-chat/video-player/video-player.component'; +import { ReqTokenInterceptor } from './_guard/req-token.interceptor'; export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http); @@ -143,7 +144,7 @@ const socketConfig: SocketIoConfig = { url: environment.socketServerUrl, options // }, { provide:HTTP_INTERCEPTORS, - useClass: TokenInterceptor, + useClass: ReqTokenInterceptor, multi: true }, MessagingService, AsyncPipe,LoaderService diff --git a/ng6-seed/src/app/layouts/admin/admin-layout.component.ts b/ng6-seed/src/app/layouts/admin/admin-layout.component.ts index 416ffd1de..807e64ee7 100755 --- a/ng6-seed/src/app/layouts/admin/admin-layout.component.ts +++ b/ng6-seed/src/app/layouts/admin/admin-layout.component.ts @@ -340,7 +340,7 @@ export class AdminLayoutComponent implements OnInit, OnDestroy { if(res && res.hasOwnProperty('random_string') && res.random_string && res.hasOwnProperty('user_type') && res.user_type != 'officer'){ if(pd_short_info.filter(val=>val.random_string == res.random_string).length > 0){ let curr_pd_info= pd_short_info.filter(val=>val.random_string == res.random_string)[0] - if(curr_pd_info && curr_pd_info.pd_type == '3') { + if(curr_pd_info && (curr_pd_info.pd_type == '3' || curr_pd_info.pd_type == '2')) { this.connectPeer(res,curr_pd_info); } } diff --git a/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/all-pd/all-pd.component.html b/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/all-pd/all-pd.component.html index 9fce4cc0c..5fd0d1a95 100755 --- a/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/all-pd/all-pd.component.html +++ b/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/all-pd/all-pd.component.html @@ -78,7 +78,7 @@ -

Showing data for last {{common}}. To see older records, please use advanced filter

+

Showing data for last {{common}}. To see older records, please use advanced filter

diff --git a/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/schedule-pd/schedule-pd.component.ts b/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/schedule-pd/schedule-pd.component.ts index 40e5b61a4..c6e10379a 100755 --- a/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/schedule-pd/schedule-pd.component.ts +++ b/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/schedule-pd/schedule-pd.component.ts @@ -64,15 +64,16 @@ export class SchedulePdComponent implements OnInit, OnDestroy { } ngOnInit() { - this.validateTime = setInterval(() => { - let currentTime:any = new Date(); - currentTime = currentTime.getFullYear()+'-'+currentTime.getMonth()+'-'+currentTime.getDay()+'-'+currentTime.getHours()+'-'+currentTime.getMinutes(); - let existTime:any = this.selectedMoment.getFullYear()+'-'+this.selectedMoment.getMonth()+'-'+this.selectedMoment.getDay() +'-'+this.selectedMoment.getHours()+'-'+this.selectedMoment.getMinutes(); - if(existTime < currentTime) { - this.selectedMoment = new Date(); - this.min = new Date(); - } - },1000); + // this.validateTime = setInterval(() => { + // let currentTime:any = new Date(); + // currentTime = currentTime.getFullYear()+'-'+currentTime.getMonth()+'-'+currentTime.getDate()+'-'+currentTime.getHours()+'-'+currentTime.getMinutes(); + // let existTime:any = this.selectedMoment.getFullYear()+'-'+this.selectedMoment.getMonth()+'-'+this.selectedMoment.getDate() +'-'+this.selectedMoment.getHours()+'-'+this.selectedMoment.getMinutes(); + // console.log(existTime,currentTime,existTime < currentTime,this.selectedMoment) + // if(existTime < currentTime) { + // this.selectedMoment = new Date(); + // this.min = new Date(); + // } + // },1000); } // close pd schedule pop up diff --git a/ng6-seed/src/app/personal-discussion/pd-service/pd-triger.service.ts b/ng6-seed/src/app/personal-discussion/pd-service/pd-triger.service.ts index ecbba0a72..59177c988 100755 --- a/ng6-seed/src/app/personal-discussion/pd-service/pd-triger.service.ts +++ b/ng6-seed/src/app/personal-discussion/pd-service/pd-triger.service.ts @@ -947,9 +947,14 @@ export class PdTrigerService { // }; // return this._http.post('http://localhost/newCode/saveVideo',params,httpOptions); // } + /**VIDEO CALL RELATED */ saveCusVideo(params) { return this._http.post(this.apiUrl+'saveCusVideo',params); } + getIceServers() { + return this._http.get(this.apiUrl+'getServerInfo') + } + // END OF VIDEO CALL getRecordedPlaybackUrl(params){ return this._http.post(this.apiUrl+'getVideoURL',params) } diff --git a/ng6-seed/src/app/quality-check/qc-list/qc-view/qc-view.component.ts b/ng6-seed/src/app/quality-check/qc-list/qc-view/qc-view.component.ts index de939a125..87feb7959 100755 --- a/ng6-seed/src/app/quality-check/qc-list/qc-view/qc-view.component.ts +++ b/ng6-seed/src/app/quality-check/qc-list/qc-view/qc-view.component.ts @@ -61,7 +61,7 @@ export class QcViewComponent implements OnInit, OnDestroy { public _EditPDtriggerForm:FormGroup; pdCollectedDocument:any=[]; pd_QC_Rating: Number; - videoplayback: any = {enableBtn:false,url:null}; + videoplayback: any = {enableBtn:true,url:null}; constructor(notifier:NotifierService,private dialog: MatDialog,private _fb: FormBuilder, private _qc: QcService,private route: ActivatedRoute,private router: Router, private QcListComponent: QcListComponent,private pdService:PdTrigerService) { this.notifier=notifier @@ -84,10 +84,10 @@ export class QcViewComponent implements OnInit, OnDestroy { if (data.status == 200) { let masterData: any = data.records.pd_master_details; this.pdMasterData.push(masterData[0]); - if((this.pdMasterData[0].fk_pd_type == '3' || this.pdMasterData[0].fk_pd_type == '2') && (this.pdMasterData[0].pd_status == 'COMPLETED' || this.pdMasterData[0].pd_status == 'QC_COMPLETED')) { - this.getVideoUrl(this.viewID,this.masterRandomString) - this.videoplayback.enableBtn = true; - } + // if((this.pdMasterData[0].fk_pd_type == '3' || this.pdMasterData[0].fk_pd_type == '2') && (this.pdMasterData[0].pd_status == 'COMPLETED' || this.pdMasterData[0].pd_status == 'QC_COMPLETED')) { + // this.getVideoUrl(this.viewID,this.masterRandomString) + // this.videoplayback.enableBtn = true; + // } this.reportRandomString = btoa(masterData[0].random_string); let parent_pd_id=masterData[0].parent_pd_id localStorage.setItem('parent_pd_id_for_Genie',parent_pd_id); @@ -361,26 +361,34 @@ export class QcViewComponent implements OnInit, OnDestroy { }) } openPlayer(){ - if(this.videoplayback.url == null) { - this.notifier.notify('info',"No Videos Found"); - return; - } + // if(this.videoplayback.url == null) { + // this.notifier.notify('info',"No Videos Found"); + // return; + // } + let params = {"pd_id":this.viewID,"random_string":this.masterRandomString} + this._qc.getRecordedPlaybackUrl(params).subscribe(result=>{ + if(result && result['dataStatus'] && result['records'] && result['records'].length > 0) { let dialogRef = this.dialog.open(VideoPlayerComponent,{ - data:{videoUrl:this.videoplayback.url}, + data:{videoUrl:result['records']}, maxWidth: '100vw', maxHeight: '100vh', - height: '80%', - width: '80%', + height: '90%', + width: '70%', disableClose: false, panelClass:'video-player' }) } - getVideoUrl(pd_id,randomStr){ - let params = {"pd_id":pd_id,"random_string":randomStr} - this.pdService.getRecordedPlaybackUrl(params).subscribe(result=>{ - this.videoplayback.url=result['url']; - }) - } + else { + this.notifier.notify('info',"No Videos Found"); + } +}) + } + // getVideoUrl(pd_id,randomStr){ + // let params = {"pd_id":pd_id,"random_string":randomStr} + // this.pdService.getRecordedPlaybackUrl(params).subscribe(result=>{ + // this.videoplayback.url=result['url']; + // }) + // } ngOnDestroy(): void { if(this.destroyType==1){ this.QcListComponent.pdListLoad(true); diff --git a/ng6-seed/src/app/quality-check/qc-service/qc.service.ts b/ng6-seed/src/app/quality-check/qc-service/qc.service.ts index a85b700f7..af71a32a9 100755 --- a/ng6-seed/src/app/quality-check/qc-service/qc.service.ts +++ b/ng6-seed/src/app/quality-check/qc-service/qc.service.ts @@ -650,4 +650,8 @@ export class QcService { auditSmartPDImages(params):Observable { return this._http.post(this.apiUrl+'auditSmartPDImages',params); } + getRecordedPlaybackUrl(params){ + return this._http.post(this.apiUrl+'getVideoURL',params) + } + } diff --git a/ng6-seed/src/app/video-chat/video-chat.component.html b/ng6-seed/src/app/video-chat/video-chat.component.html index 9539d6f88..52eaf292b 100755 --- a/ng6-seed/src/app/video-chat/video-chat.component.html +++ b/ng6-seed/src/app/video-chat/video-chat.component.html @@ -63,15 +63,19 @@
-
+
+ +

{{displayMsg}}

+
diff --git a/ng6-seed/src/app/video-chat/video-chat.component.scss b/ng6-seed/src/app/video-chat/video-chat.component.scss index b26518120..3e263535c 100755 --- a/ng6-seed/src/app/video-chat/video-chat.component.scss +++ b/ng6-seed/src/app/video-chat/video-chat.component.scss @@ -77,3 +77,15 @@ video#peervideo { body{ margin:10px !important; } +.wrapper { + display: flex; + justify-content: center; + align-items: center; + // height: calc(100vh - 20px); + // background: red; + } + .inner { + // background: green; + color: white; + padding: 12px; + } diff --git a/ng6-seed/src/app/video-chat/video-chat.component.ts b/ng6-seed/src/app/video-chat/video-chat.component.ts index 7b4e194d8..be4141ba1 100755 --- a/ng6-seed/src/app/video-chat/video-chat.component.ts +++ b/ng6-seed/src/app/video-chat/video-chat.component.ts @@ -4,11 +4,16 @@ import { PushNotifyService } from 'app/shared/push-notify.service'; import { Socket } from 'ngx-socket-io'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; import { PdTrigerService } from 'app/personal-discussion/pd-service/pd-triger.service'; +import * as RecordRTC from 'recordrtc' +import * as RecordRTCPromisesHandler from 'recordrtc'; +// import {RecordRTCPromisesHandler} from 'recordrtc' + @Component({ selector: 'app-video-chat', templateUrl: './video-chat.component.html', styleUrls: ['./video-chat.component.scss'] }) + export class VideoChatComponent implements OnInit { MediaStream title = 'simple-peer-video-chat'; @@ -36,6 +41,8 @@ export class VideoChatComponent implements OnInit { unique_video_key: string = ''; callDisconnectTimer:any + my_ice_servers: any = []; + is_spinner:boolean = true constructor(private _notificationService:PushNotifyService, private cdRef: ChangeDetectorRef,private socket: Socket, private dialogRef: MatDialogRef, @@ -85,31 +92,105 @@ export class VideoChatComponent implements OnInit { ngOnInit() { console.log(this.chat_info); if(this.chat_info) { + this.pdTriggerService.getIceServers().subscribe(rr=>{ + if(rr['dataStatus'] && rr['records']) { + this.displayMsg = "Note : Make sure the Reciever is waiting for your call before start Calling" + let temp_ice_servers = JSON.parse(rr['records']); + if(temp_ice_servers) { + this.my_ice_servers = temp_ice_servers.ice_servers + } if(this.chat_info.type == 'offer' && this.chat_info.hasOwnProperty('JSON_to_connect') && this.chat_info.JSON_to_connect) { this.is_video_enable = true; this.start_Calling('receive') } + else { + this.start_Calling('init') + } + } + else { + this.displayMsg = "Something went wrong!!" + alert("Something went wrong!!") + this.dialogRef.close(); + } + this.is_spinner = false + }, + err=>{ + console.log("Error getting ICE Servers",err) + this.displayMsg = "Network Error!!" + this.is_spinner = false + alert("Network Error!!") + this.dialogRef.close(); +}) } + // this.start_Calling('receive') } start_Calling(option) { + let ice_servers = [ + { + "url": "stun:global.stun.twilio.com:3478?transport=udp", + "urls": "stun:global.stun.twilio.com:3478?transport=udp" + }, + { + "url": "turn:global.turn.twilio.com:3478?transport=udp", + "username": "47c1931de3421448cd86145f6ffc90f5124a4ce792511463c820164512a55cd2", + "urls": "turn:global.turn.twilio.com:3478?transport=udp", + "credential": "8g3b5XV7S\/zeqP284yi3oTxwChri+YPXCD6PsIRU+yM=" + }, + { + "url": "turn:global.turn.twilio.com:3478?transport=tcp", + "username": "47c1931de3421448cd86145f6ffc90f5124a4ce792511463c820164512a55cd2", + "urls": "turn:global.turn.twilio.com:3478?transport=tcp", + "credential": "8g3b5XV7S\/zeqP284yi3oTxwChri+YPXCD6PsIRU+yM=" + }, + { + "url": "turn:global.turn.twilio.com:443?transport=tcp", + "username": "47c1931de3421448cd86145f6ffc90f5124a4ce792511463c820164512a55cd2", + "urls": "turn:global.turn.twilio.com:443?transport=tcp", + "credential": "8g3b5XV7S\/zeqP284yi3oTxwChri+YPXCD6PsIRU+yM=" + } + ] + // [ + // { + // url:'stun:global.stun.twilio.com:3478?transport=udp', + // urls:'stun:global.stun.twilio.com:3478?transport=udp' + // }, + // { + // url:'turn:global.turn.twilio.com:3478?transport=udp', + // urls:'turn:global.turn.twilio.com:3478?transport=udp', + // username:'dec47b985225dc1585fb52082ce77d16ce5e3f4c6ba967f68a072c94983bfa72', + // credential:'T9RKwBTjH1cBI5f+DzFcUHPiw3LkfjWkADAvnBSp7a0=' + // }, + // { + // url:'turn:global.turn.twilio.com:3478?transport=tcp', + // urls:'turn:global.turn.twilio.com:3478?transport=tcp', + // username:'dec47b985225dc1585fb52082ce77d16ce5e3f4c6ba967f68a072c94983bfa72', + // credential:'T9RKwBTjH1cBI5f+DzFcUHPiw3LkfjWkADAvnBSp7a0=' + // }, + // { + // url:'turn:global.turn.twilio.com:443?transport=tcp', + // urls:'turn:global.turn.twilio.com:443?transport=tcp', + // username:'dec47b985225dc1585fb52082ce77d16ce5e3f4c6ba967f68a072c94983bfa72', + // credential:'T9RKwBTjH1cBI5f+DzFcUHPiw3LkfjWkADAvnBSp7a0=' + // } + // ] this.user_msg ="Establishing Connection..." this.userCallType = option // let texk=this.textCopyElement.nativeElement let video = this.myVideo.nativeElement; let peerVideo = this.peervideo.nativeElement - let peerx: any; - let copyMessageText + // let peerx: any; + // let copyMessageText this.n.getUserMedia = (this.n.getUserMedia || this.n.webkitGetUserMedia || this.n.mozGetUserMedia || this.n.msGetUserMedia); if(this.n.getUserMedia == undefined || this.n.getUserMedia == null, this.n.getUserMedia == ''){ alert("unable to get the camera access. please close the browser and come back again") } console.log(this.n) - let defaultsOpts = { audio: true, video: { + let defaultsOpts = { audio: true, video: { width: 1280, height: 720, facingMode: this.shouldFaceUser ? 'user' : 'environment' } } - this.n.getUserMedia(defaultsOpts).then(stream=> { + navigator.mediaDevices.getUserMedia(defaultsOpts).then(stream=> { this.socket.emit('NewClient') video.load(); video.muted = true; @@ -125,30 +206,31 @@ export class VideoChatComponent implements OnInit { } console.log("entered",stream); - peerx = new SimplePeer ({ + this.peer = new SimplePeer ({ initiator: option === 'init', stream: stream, reconnectTimer: 1000, iceTransportPolicy: 'relay', trickle: false, config: { - iceServers: [ - { - "urls": "stun:numb.viagenie.ca", - "username": 'fairoj@venbainfotech.com', - "credential": '0987123400' - }, - { - "urls": "turn:numb.viagenie.ca", - "username": "fairoj@venbainfotech.com", - "credential": "0987123400" - } - ] + iceServers: this.my_ice_servers + // [ + // { + // "urls": "stun:numb.viagenie.ca", + // "username": 'fairoj@venbainfotech.com', + // "credential": '0987123400' + // }, + // { + // "urls": "turn:numb.viagenie.ca", + // "username": "fairoj@venbainfotech.com", + // "credential": "0987123400" + // } + // ] } }) // function InitPeer(type) { - peerx.on('signal',(data)=> { + this.peer.on('signal',(data)=> { console.log(JSON.stringify(data)); if(data.hasOwnProperty('type') && data.type == 'offer'){ @@ -167,27 +249,27 @@ export class VideoChatComponent implements OnInit { this.socket.emit('Answer', event_data) } // copyMessage(JSON.stringify(data)) - copyMessageText = JSON.stringify(data); + // copyMessageText = JSON.stringify(data); // update() // this.copyMessage(copyMessageText,data.type) // this.targetpeer = data; }) // } - peerx.on('data', function(data) { + this.peer.on('data', function(data) { console.log('Recieved message:' + data); }) - peerx.on('close', (data) => { + this.peer.on('close', (data) => { console.log("Peer Connection is closed ",data); this.disconnect(); // alert("Peer Connection is closed " +JSON.stringify(data)) this.notify("Connection Closed",'Peer Connection Closed') }) - peerx.on('error', (err) => { + this.peer.on('error', (err) => { console.log("Fatal Error ",err); this.disconnect(); // alert("Fatal Error" +JSON.stringify(err)) }) - peerx.on('stream', (stream)=> { + this.peer.on('stream', (stream)=> { console.log("@##################33",stream) if ('srcObject' in peerVideo) { peerVideo.srcObject = stream @@ -231,13 +313,8 @@ export class VideoChatComponent implements OnInit { // video.play() // //wait for 1 sec // } - function connectPeer(answer) { - console.log("$$$$$$$$$$$$$$44"); - console.log(answer); - setTimeout(()=>{ - peerx.signal(answer.JSON_to_connect); - },1000) - } + // let peerVideoEnable = this.peerVideoEnable + // function getPeer(){ // return JSON.stringify(copyMessageText) // } @@ -247,12 +324,24 @@ export class VideoChatComponent implements OnInit { // this.socket.on('BackOffer', getPeer) // },2000) // } - if(this.chat_info.type == 'offer' && this.chat_info.JSON_to_connect && this.chat_info.JSON_to_connect != undefined) { - connectPeer(this.chat_info) + + if(this.chat_info.type == 'offer' && this.chat_info.JSON_to_connect && this.chat_info.JSON_to_connect != undefined && !this.peerVideoEnable) { + this.connectPeer(this.chat_info) } // let tt = this.socket.on('BackOffer', connectPeer) // console.log(tt); - this.socket.on('BackAnswer', connectPeer) + // this.socket.on('BackAnswer', connectPeer) + this.socket.fromEvent('BackAnswer').subscribe((res:any)=>{ + console.log("back answer",this.peer,this.peerVideoEnable); + let pd_short_info:any = localStorage.getItem('pd_short_info') + pd_short_info = JSON.parse(pd_short_info); + if(this.peer && !this.peerVideoEnable && pd_short_info && pd_short_info.length > 0 && pd_short_info.filter(val=>val.random_string == res.random_string).length > 0) { + if(this.callDisconnectTimer != undefined && this.callDisconnectTimer) { + clearTimeout(this.callDisconnectTimer) + } + this.connectPeer(res); + } + }) }, err=>{ console.log('Failed to get stream', err); alert('Failed to get stream '+err); @@ -269,20 +358,30 @@ export class VideoChatComponent implements OnInit { // // texk.value = copyMessageText // },2000) // } - setTimeout(() => { - this.peer = peerx; + // setTimeout(() => { + // this.peer = this.peer; - // this.copyMessage(JSON.stringify(this.targetpeer)) - console.log(this.peer); - // console.log(copyMessageText) - // this.targetpeer = copyMessageText - // this.textToCopy = copyMessageText - // this.copyMessage(copyMessageText) - }, 5000); + // // this.copyMessage(JSON.stringify(this.targetpeer)) + // console.log(this.peer); + // // console.log(copyMessageText) + // // this.targetpeer = copyMessageText + // // this.textToCopy = copyMessageText + // // this.copyMessage(copyMessageText) + // }, 3000); // socket.on('SessionActive', SessionActive) // socket.on('CreatePeer', MakePeer) // socket.on('Disconnect', RemovePeer) + } + connectPeer(answer) { + console.log("$$$$$$$$$$$$$$44"); + console.log(answer); + + setTimeout(()=>{ + if(this.peer) { + this.peer.signal(answer.JSON_to_connect); + } + },1000) } updateTheMsg(msg_obj) { console.log("CallstatusMsg",msg_obj,this.chat_info) @@ -290,6 +389,7 @@ export class VideoChatComponent implements OnInit { console.log("entered"); this.start_btn_enable = false this.displayMsg = msg_obj.msg + this.notify("Alert",msg_obj.msg) // this.cdRef.detectChanges(); this.disconnect(); @@ -297,6 +397,7 @@ export class VideoChatComponent implements OnInit { } fetchVideoAndPlay(stream,videotype,enablePeerVideo?) { console.log("12@@@@@@@@@2",enablePeerVideo) + console.log("Add video to record",stream,RecordRTC) fetch('') .then(response => response.blob()) @@ -311,78 +412,77 @@ export class VideoChatComponent implements OnInit { this.peervideo.nativeElement.style.marginTop = '0px' } this.peerVideoEnable = enablePeerVideo - if(this.callDisconnectTimer != undefined && this.callDisconnectTimer) { - clearTimeout(this.callDisconnectTimer) - } + if(this.peer && this.peerVideoEnable) { this.socket.emit('callStatus',{random_string:this.chat_info.random_string,status:'connected',status_code:1}) + } // this.camereSwitchBtn.nativeElement.disabled = true; console.log("peervideo check",this.peerVideoEnable,this.peervideo.nativeElement.videoWidth,this.peervideo.nativeElement.videoHeight); this.cdRef.detectChanges(); this.unique_video_key =this.randomStringGenerator(8) - this.startRecording(stream) - // this.addVideoToRecorder(stream) - // this.addVideoToRecorder(this.MediaStream) + // this.startRecording(stream) + this.addVideoToRecorder(stream) + this.addVideoToRecorder(this.MediaStream) } }) .catch(e => { // Video playback failed ;( }) } - async startRecording(stream) { - // console.log("start",stream,this.peervideo) - this.recorder = [] - this.recorder = new RecordRTCPromisesHandler(stream, { - type: 'video', - mimeType: 'video/webm\;codecs=vp9', // or video/webm\;codecs=h264 or video/webm\;codecs=vp9 - // timeSlice: 10000, - // ondataavailable: (blob=> { this.sendPartVideo(blob) }), - audioBitsPerSecond: 128000, - videoBitsPerSecond: 128000, - bitsPerSecond: 128000 // if this line is provided, skip above - }); - this.recorder.startRecording(); - // const sleep = m => new Promise(r => setTimeout(r, m)); - // await sleep(3000); -setTimeout(()=>{ -this.stopRecording(true); -},120000); -// var file = new File([blob], 'video.mp4', { -// type: 'video/mp4' -// }); -// console.log(file) -// const fileURL = window.URL.createObjectURL(file); -// window.open(fileURL); -// videotype.srcObject = null; -// videotype.muted = false; -// videotype.volume = 1; -// videotype.srcObject = file; +// async startRecording(stream) { +// // console.log("start",stream,this.peervideo) +// this.recorder = [] +// this.recorder = new RecordRTCPromisesHandler(stream, { +// type: 'video', +// mimeType: 'video/webm\;codecs=vp9', // or video/webm\;codecs=h264 or video/webm\;codecs=vp9 +// // timeSlice: 10000, +// // ondataavailable: (blob=> { this.sendPartVideo(blob) }), +// audioBitsPerSecond: 128000, +// videoBitsPerSecond: 128000, +// bitsPerSecond: 128000 // if this line is provided, skip above +// }); +// this.recorder.startRecording(); +// // const sleep = m => new Promise(r => setTimeout(r, m)); +// // await sleep(3000); +// setTimeout(()=>{ +// this.stopRecording(true); +// },120000); +// // var file = new File([blob], 'video.mp4', { +// // type: 'video/mp4' +// // }); +// // console.log(file) +// // const fileURL = window.URL.createObjectURL(file); +// // window.open(fileURL); +// // videotype.srcObject = null; +// // videotype.muted = false; +// // videotype.volume = 1; +// // videotype.srcObject = file; - // recorder.camera.stop(); - // recorder.destroy(); - // recorder = null; -// let recorder = RecordRTC(stream, { -// type: 'video' -// }); -// recorder.startRecording(); +// // recorder.camera.stop(); +// // recorder.destroy(); +// // recorder = null; +// // let recorder = RecordRTC(stream, { +// // type: 'video' +// // }); +// // recorder.startRecording(); -// const sleep = m => new Promise(r => setTimeout(r, m)); -// sleep(10000); +// // const sleep = m => new Promise(r => setTimeout(r, m)); +// // sleep(10000); -// recorder.stopRecording(function() { -// let blob = recorder.getBlob(); -// // invokeSaveAsDialog(blob); -// console.log(blob); -// }); +// // recorder.stopRecording(function() { +// // let blob = recorder.getBlob(); +// // // invokeSaveAsDialog(blob); +// // console.log(blob); +// // }); -// blob.then(resul=>{ -// console.log(resul); -// }) -// const fileURL = window.URL.createObjectURL(blob); -// console.log(fileURL); -// window.open(fileURL); -// invokeSaveAsDialog(blob); - } +// // blob.then(resul=>{ +// // console.log(resul); +// // }) +// // const fileURL = window.URL.createObjectURL(blob); +// // console.log(fileURL); +// // window.open(fileURL); +// // invokeSaveAsDialog(blob); +// } // sendPartVideo(blob){ // this.arr_of_blobs.push(blob); // console.log("Blob",blob,JSON.stringify(blob)); @@ -401,55 +501,57 @@ this.stopRecording(true); // console.log(result); // }) // } - async stopRecording(autostarRec?) { - await this.recorder.stopRecording(); - // console.log(this.recorder); - let blob = await this.recorder.getBlob(); - if(autostarRec) { - await this.startRecording(this.peervideo.nativeElement.srcObject) - } - // setTimeout(()=>{ - console.log(typeof(blob),blob); - console.log(RecordRTC,RecordRTCPromisesHandler) - await RecordRTC.getSeekableBlob(blob, seekableBlob=> { - console.log(seekableBlob) - const fileURL = window.URL.createObjectURL(seekableBlob); - console.log("seekable file",fileURL) - this.arr_of_blobs.push(seekableBlob) - console.log("----------------------------") - console.log("video "+this.arr_of_blobs.length, fileURL) - console.log("----------------------------") - this.sendVideoToServer(seekableBlob,autostarRec) - }) +// async stopRecording(autostarRec?) { +// await this.recorder.stopRecording(); +// // console.log(this.recorder); +// let blob = await this.recorder.getBlob(); +// if(autostarRec) { +// await this.startRecording(this.peervideo.nativeElement.srcObject) +// } +// // setTimeout(()=>{ +// console.log(typeof(blob),blob); +// console.log(RecordRTC,RecordRTCPromisesHandler) +// await RecordRTC.getSeekableBlob(blob, seekableBlob=> { +// console.log(seekableBlob) +// const fileURL = window.URL.createObjectURL(seekableBlob); +// console.log("seekable file",fileURL) +// this.arr_of_blobs.push(seekableBlob) +// console.log("----------------------------") +// console.log("video "+this.arr_of_blobs.length, fileURL) +// console.log("----------------------------") +// // this.sendVideoToServer(seekableBlob,autostarRec) +// }) - // var file = new File([blob], 'video.mp4', { - // type: 'video/mp4' - // }); - // const fileURL = window.URL.createObjectURL(blob); - // this.arr_of_blobs.push(blob) - // console.log("----------------------------") - // console.log("video "+this.arr_of_blobs.length, fileURL) - // console.log("----------------------------") - if(!autostarRec) { - let mergedVideos=this.arr_of_blobs.reduce((a, b)=> new Blob([a, b], {type: "video/webm"})); - console.log("merged",mergedVideos,this.arr_of_blobs); - const fileURL1 = window.URL.createObjectURL(mergedVideos); - // localStorage.setItem('blob_url',fileURL1) - console.log("File url 11111",fileURL1) - // window.open(fileURL1) - } +// // var file = new File([blob], 'video.mp4', { +// // type: 'video/mp4' +// // }); +// // const fileURL = window.URL.createObjectURL(blob); +// // this.arr_of_blobs.push(blob) +// // console.log("----------------------------") +// // console.log("video "+this.arr_of_blobs.length, fileURL) +// // console.log("----------------------------") +// if(!autostarRec) { +// if(this.arr_of_blobs.length > 0) { +// let mergedVideos=this.arr_of_blobs.reduce((a, b)=> new Blob([a, b], {type: "video/webm"})); +// console.log("merged",mergedVideos,this.arr_of_blobs); +// const fileURL1 = window.URL.createObjectURL(mergedVideos); +// // localStorage.setItem('blob_url',fileURL1) +// console.log("File url 11111",fileURL1) +// } +// // window.open(fileURL1) +// } - // let formData= new FormData(); - // formData.append('videoFile',file); - // console.log(formData); - // alert("saved Recording will be opened in a new window"); - // window.open(fileURL); - // },3000); - // this.recorder.getDataURL().then(dataURL=>{ - // console.log("@@@@@",dataURL) +// // let formData= new FormData(); +// // formData.append('videoFile',file); +// // console.log(formData); +// // alert("saved Recording will be opened in a new window"); +// // window.open(fileURL); +// // },3000); +// // this.recorder.getDataURL().then(dataURL=>{ +// // console.log("@@@@@",dataURL) - // }) -} +// // }) +// } sendVideoToServer(blob,is_auto_start) { let formData = new FormData(); formData.append('video_file', blob); @@ -486,9 +588,9 @@ sendVideoToServer(blob,is_auto_start) { console.log("onDisconnect",this.peer,this.peerVideoEnable) if(this.peer) { if(this.peerVideoEnable) { - this.stopRecording().then(res=>{ - - }) + // this.stopRecording().then(res=>{ + this.stopRecordingMultiStream() + // }) } if(this.callDisconnectTimer != undefined && this.callDisconnectTimer) { clearTimeout(this.callDisconnectTimer) @@ -501,16 +603,7 @@ sendVideoToServer(blob,is_auto_start) { this.socket.emit('callStatus',{random_string:this.chat_info.random_string,status:'disconnected',status_code:0}) this.peervideo.nativeElement.pause(); - // this.stopAndGetSingleBlob(function(blob) { - // var url = URL.createObjectURL(blob); - // // previewVideo.src = url; - // console.log(blob,url); - // // or - // window.open(url); - - // // or - // // invokeSaveAsDialog(blob); - // }); + } console.log(this.MediaStream.getTracks()) // this.MediaStream.stop() @@ -527,6 +620,39 @@ sendVideoToServer(blob,is_auto_start) { this.is_video_enable = false this.cdRef.detectChanges(); console.log(this.peer) + // if(go_back) { + setTimeout(()=>{ + // this.navCtrl.pop(); + this.dialogRef.close() + },2000) + // } + } + stopRecordingMultiStream(autostarRec?) { + let arr_of_blobs = this.arr_of_blobs + this.stopAndGetSingleBlob(blob=> { + RecordRTCPromisesHandler.getSeekableBlob(blob, seekableBlob=> { + console.log(seekableBlob) + const fileURL = window.URL.createObjectURL(seekableBlob); + console.log("seekable file",fileURL) + arr_of_blobs.push(seekableBlob) + console.log("----------------------------") + console.log("video "+arr_of_blobs.length, fileURL) + console.log("----------------------------") + this.sendVideoToServer(seekableBlob,autostarRec) + if(autostarRec) { + this.addVideoToRecorder(this.peervideo.nativeElement.srcObject) + this.addVideoToRecorder(this.myVideo.nativeElement.srcObject) + } + }) + var url = URL.createObjectURL(blob); + // previewVideo.src = url; + console.log(blob,url); + // or + // window.open(url); + + // or + // invokeSaveAsDialog(blob); + }); } copyMessage(val: string,message?){ const selBox = document.createElement('textarea'); @@ -599,6 +725,36 @@ sendVideoToServer(blob,is_auto_start) { return result; } + // RECORDING MULTIPLE VIDEOS + + addVideoToRecorder(stream) { + // var stream = stream.captureStream(); + console.log("Add video to record",stream,RecordRTC) + if (!this.recorder) { + this.recorder = RecordRTC([stream], { + // type: 'video' + }); + this.recorder.startRecording(); + setTimeout(()=>{ + this.stopRecordingMultiStream(true); + },30000); + } else { + this.recorder.getInternalRecorder().addStreams([stream]); + } +} + + async stopAndGetSingleBlob(callback) { + if (!this.recorder) return; + await this.recorder.stopRecording(()=> { + // setTimeout(()=>{ + callback(this.recorder.getBlob()); + // setTimeout(()=>{ + // console.log(this.recorder.getBlob()); + // },3000) + // }) + this.recorder = null; + }); +} @HostListener('window:beforeunload', ['$event']) unloadHandler(event) { @@ -607,31 +763,6 @@ sendVideoToServer(blob,is_auto_start) { this.disconnect(); } } - // RECORDING MULTIPLE VIDEOS + -// addVideoToRecorder(stream) { -// // var stream = video.captureStream(); - -// if (!this.recorder) { -// this.recorder = RecordRTC([stream], { -// type: 'video' -// }); -// this.recorder.startRecording(); -// } else { -// this.recorder.getInternalRecorder().addStreams([stream]); -// } -// } - -// async stopAndGetSingleBlob(callback) { -// if (!this.recorder) return; -// await this.recorder.stopRecording(()=> { -// // setTimeout(()=>{ -// callback(this.recorder.getBlob()); -// setTimeout(()=>{ -// console.log(this.recorder.getBlob()); -// },3000) -// // }) -// this.recorder = null; -// }); -// } } diff --git a/ng6-seed/src/index.html b/ng6-seed/src/index.html index 615284e0f..d061ab772 100755 --- a/ng6-seed/src/index.html +++ b/ng6-seed/src/index.html @@ -12,7 +12,8 @@ - + PD Genie diff --git a/ng6-seed/src/typings.d.ts b/ng6-seed/src/typings.d.ts index 2c420c444..40769c05f 100755 --- a/ng6-seed/src/typings.d.ts +++ b/ng6-seed/src/typings.d.ts @@ -7,6 +7,7 @@ declare module 'quill'; declare module 'leaflet'; declare module 'perfect-scrollbar'; declare module 'screenfull'; +declare module 'recordrtc' declare var SimplePeer: any; -declare var RecordRTCPromisesHandler:any; -declare var RecordRTC:any; \ No newline at end of file +// declare var RecordRTCPromisesHandler:any; +// declare var RecordRTC:any; \ No newline at end of file