diff --git a/ng6-seed/package-lock.json b/ng6-seed/package-lock.json index f9fa094cd..18695116f 100755 --- a/ng6-seed/package-lock.json +++ b/ng6-seed/package-lock.json @@ -8207,6 +8207,14 @@ "tslib": "^1.9.0" } }, + "mat-video": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/mat-video/-/mat-video-2.7.2.tgz", + "integrity": "sha512-rwZt9+gxhyQeUYkWq+7JPwYdMEDMI4iT9mIdhO00TDnihbdv20WHiMZ4yYLudzFnuJIeXzgDrA9yltGWjG3vMw==", + "requires": { + "tslib": "^1.9.0" + } + }, "math-random": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", diff --git a/ng6-seed/package.json b/ng6-seed/package.json index 8fe569a50..ae9e66556 100755 --- a/ng6-seed/package.json +++ b/ng6-seed/package.json @@ -54,6 +54,7 @@ "karma-jasmine": "^1.1.1", "leaflet": "^1.6.0", "mat-table-exporter": "^1.2.5", + "mat-video": "^2.7.2", "moment": "^2.24.0", "ng-pick-datetime": "^6.0.16", "ng2-charts": "1.6.0", diff --git a/ng6-seed/proxy.conf.json b/ng6-seed/proxy.conf.json new file mode 100644 index 000000000..b9cd9b394 --- /dev/null +++ b/ng6-seed/proxy.conf.json @@ -0,0 +1,7 @@ +{ + "/api/": { + "target": "http://localhost/", + "secure": false, + "changeOrigin": true + } +} \ 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 dfa8c171a..02f149121 100755 --- a/ng6-seed/src/app/app.module.ts +++ b/ng6-seed/src/app/app.module.ts @@ -62,6 +62,8 @@ import {SocketIoConfig, SocketIoModule} from 'ngx-socket-io'; import { IncomingCallComponent } from './video-chat/incoming-call/incoming-call.component'; 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'; export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http); @@ -82,7 +84,7 @@ const socketConfig: SocketIoConfig = { url: environment.socketServerUrl, options AppComponent, AdminLayoutComponent, AuthLayoutComponent, - NewPasswordDialog,ForgotPass,ChangePasswordDialog, RoleMenuItemsPipe, HttpLoaderComponent, IncomingCallComponent, VideoChatComponent + NewPasswordDialog,ForgotPass,ChangePasswordDialog, RoleMenuItemsPipe, HttpLoaderComponent, IncomingCallComponent, VideoChatComponent, VideoPlayerComponent ], imports: [ MatDialogModule, @@ -123,7 +125,8 @@ const socketConfig: SocketIoConfig = { url: environment.socketServerUrl, options AngularFireAuthModule, AngularFireMessagingModule, AngularFireModule.initializeApp(environment.firebase), - SocketIoModule.forRoot(socketConfig) + SocketIoModule.forRoot(socketConfig), + MatVideoModule ], providers: [ { @@ -145,7 +148,7 @@ const socketConfig: SocketIoConfig = { url: environment.socketServerUrl, options }, MessagingService, AsyncPipe,LoaderService ], - entryComponents: [NewPasswordDialog,ForgotPass,ChangePasswordDialog,IncomingCallComponent,VideoChatComponent], + entryComponents: [NewPasswordDialog,ForgotPass,ChangePasswordDialog,IncomingCallComponent,VideoChatComponent,VideoPlayerComponent], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/ng6-seed/src/app/dashboard/dashboard.component.html b/ng6-seed/src/app/dashboard/dashboard.component.html index af0cc1fe0..35cfbad9a 100755 --- a/ng6-seed/src/app/dashboard/dashboard.component.html +++ b/ng6-seed/src/app/dashboard/dashboard.component.html @@ -1,3 +1,4 @@ +
diff --git a/ng6-seed/src/app/dashboard/dashboard.component.ts b/ng6-seed/src/app/dashboard/dashboard.component.ts index 65ea7a4b2..2219794f0 100755 --- a/ng6-seed/src/app/dashboard/dashboard.component.ts +++ b/ng6-seed/src/app/dashboard/dashboard.component.ts @@ -6,7 +6,8 @@ import { MastersService } from '../settings/service/masters/masters.service'; import { DashboardService } from './dashboard.service'; import { NgxDrpOptions, PresetItem, Range } from 'ngx-mat-daterange-picker'; import { BaseChartDirective } from 'ng2-charts/ng2-charts'; - +import { VideoPlayerComponent } from 'app/video-chat/video-player/video-player.component'; +import { MatDialog } from '@angular/material'; @Component({ selector: 'app-dashboard', templateUrl: './dashboard.component.html', @@ -40,7 +41,7 @@ export class DashboardComponent { // }]; - constructor(private _dashboardService: DashboardService) {} + constructor(private _dashboardService: DashboardService,private dialog:MatDialog) {} ngOnInit(){ @@ -360,5 +361,15 @@ getDoughnutChartData(){ }) } +// openPlayer(){ +// let dialogRef = this.dialog.open(VideoPlayerComponent,{ +// maxWidth: '100vw', +// maxHeight: '100vh', +// height: '80%', +// width: '80%', +// disableClose: false, +// panelClass:'video-player' +// }) +// } } \ No newline at end of file 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 f585a48a4..5bb1184c7 100755 --- a/ng6-seed/src/app/layouts/admin/admin-layout.component.ts +++ b/ng6-seed/src/app/layouts/admin/admin-layout.component.ts @@ -354,6 +354,7 @@ export class AdminLayoutComponent implements OnInit, OnDestroy { this.openIncomingDialog(offer,curr_pd_info); } openIncomingDialog(offer?,curr_pd_info?) { + offer.pd_id = curr_pd_info.pd_id if(this.incomingDialogOpened == true) { return; } diff --git a/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/start-pd/forms/general-info/general-info.component.scss b/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/start-pd/forms/general-info/general-info.component.scss index 420e13e5e..4d5f3892e 100755 --- a/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/start-pd/forms/general-info/general-info.component.scss +++ b/ng6-seed/src/app/personal-discussion/manage-pd/list-pd/start-pd/forms/general-info/general-info.component.scss @@ -44,7 +44,10 @@ display:flex; justify-content:flex-end; } - + mat-cell:nth-child(1), + mat-header-cell:nth-child(1) { + flex: 0 0 20%; + } mat-cell:nth-child(5), mat-header-cell:nth-child(5) { flex: 0 0 17%; @@ -52,12 +55,21 @@ mat-cell:nth-child(6), mat-header-cell:nth-child(6) { - flex: 0 0 20%; + flex: 0 0 15%; + } + + mat-cell:nth-child(3), + mat-header-cell:nth-child(3), + mat-cell:nth-child(2), + mat-header-cell:nth-child(2) { + margin-left: 1%; + margin-right: 1%; } mat-cell:nth-child(7), mat-header-cell:nth-child(7) { justify-content: end; + flex: 0 0 19%; } .capitalize{ @@ -172,4 +184,7 @@ $product-bg-color-hover: rgba(103, 58, 183, 0.7); // } } } + // .mat-column-is_applicant { + // width: 12%; + // } \ No newline at end of file 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 dc514ecc6..bb2535fd5 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 @@ -1,7 +1,7 @@ /** Common Import Section */ import { Injectable } from '@angular/core'; import { Observable, of, forkJoin } from 'rxjs'; -import { HttpClient, HttpParams } from '@angular/common/http'; +import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http'; import { catchError, map } from 'rxjs/operators'; /** Imported Service Files Are., */ @@ -889,4 +889,17 @@ export class PdTrigerService { document.execCommand('copy'); document.body.removeChild(selBox); } + // saveVideo(params) { + // const httpOptions = { + // headers: new HttpHeaders({ + // 'Content-Type': 'application/json', + // 'Access-Control-Allow-Origin': '*', + // 'Access-Control-Allow-Credentials': 'true' + // }) + // }; + // return this._http.post('http://localhost/newCode/saveVideo',params,httpOptions); + // } + saveCusVideo(params) { + return this._http.post(this.apiUrl+'saveCusVideo',params); + } } 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 e5f8b1062..999907b5e 100644 --- a/ng6-seed/src/app/video-chat/video-chat.component.ts +++ b/ng6-seed/src/app/video-chat/video-chat.component.ts @@ -3,7 +3,7 @@ import { Observable } from 'rxjs'; 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'; @Component({ selector: 'app-video-chat', templateUrl: './video-chat.component.html', @@ -32,10 +32,11 @@ export class VideoChatComponent implements OnInit { recorder: any; start_btn_enable:boolean = true displayMsg:string = "Note : Make sure the Reciever is waiting for your call before start Calling" + arr_of_blobs: any = []; constructor(private _notificationService:PushNotifyService, private cdRef: ChangeDetectorRef,private socket: Socket, private dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public chat_info:any) { + @Inject(MAT_DIALOG_DATA) public chat_info:any,private pdTriggerService:PdTrigerService) { this._notificationService.requestPermission(); // this.notify('Approval','This is First Alert -- By Debasis Saha') console.log("Version #8") @@ -307,6 +308,8 @@ export class VideoChatComponent implements OnInit { console.log("peervideo check",this.peerVideoEnable,this.peervideo.nativeElement.videoWidth,this.peervideo.nativeElement.videoHeight); this.cdRef.detectChanges(); this.startRecording(stream) + // this.addVideoToRecorder(stream) + // this.addVideoToRecorder(this.MediaStream) } }) .catch(e => { @@ -314,10 +317,13 @@ export class VideoChatComponent implements OnInit { }) } async startRecording(stream) { + // console.log("start",stream,this.peervideo) this.recorder = [] this.recorder = new RecordRTCPromisesHandler(stream, { type: 'video', - mimeType: 'video/webm', // or video/webm\;codecs=h264 or video/webm\;codecs=vp9 + 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 @@ -325,9 +331,9 @@ export class VideoChatComponent implements OnInit { this.recorder.startRecording(); // const sleep = m => new Promise(r => setTimeout(r, m)); // await sleep(3000); -// setTimeout(()=>{ - -// }); +setTimeout(()=>{ +this.stopRecording(true); +},120000); // var file = new File([blob], 'video.mp4', { // type: 'video/mp4' // }); @@ -365,22 +371,87 @@ export class VideoChatComponent implements OnInit { // window.open(fileURL); // invokeSaveAsDialog(blob); } - async stopRecording() { + // sendPartVideo(blob){ + // this.arr_of_blobs.push(blob); + // console.log("Blob",blob,JSON.stringify(blob)); + // var file = new File([blob], 'video.mp4', { + // type: 'video/mp4' + // }); + // console.log(file,JSON.stringify(file)); + // let formData = new FormData(); + // formData.append('video', blob); + // const fileURL1 = window.URL.createObjectURL(blob); + // console.log('video'+this.arr_of_blobs.length+'.mp4',fileURL1); + // formData.append('filename','video'+this.arr_of_blobs.length+'.mp4'); + // formData.append('random_string',this.chat_info.random_string); + // console.log(formData); + // this.pdTriggerService.saveVideo(formData).subscribe(result=>{ + // console.log(result); + // }) + // } + async stopRecording(autostarRec?) { await this.recorder.stopRecording(); - console.log(this.recorder); + // console.log(this.recorder); let blob = await this.recorder.getBlob(); - setTimeout(()=>{ + if(autostarRec) { + await this.startRecording(this.peervideo.nativeElement.srcObject) + } + // setTimeout(()=>{ console.log(typeof(blob),blob); - var file = new File([blob], 'video.mp4', { - type: 'video/mp4' - }); - console.log(file) - const fileURL = window.URL.createObjectURL(file); - alert("saved Recording will be opened in a new window"); - window.open(fileURL); - },3000); - this.recorder.getDataURL().then(dataURL=>{ - console.log("@@@@@",dataURL) + 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) + }) + + // 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) + } + + // 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) { + let formData = new FormData(); + formData.append('video_file', blob); + let params = { + filename:'video'+this.arr_of_blobs.length+'.mp4', + random_string:this.chat_info.random_string, + pd_id:this.chat_info.pd_id + } + formData.append('records',JSON.stringify(params)) + // formData.append('filename','video'+this.arr_of_blobs.length+'.mp4'); + // formData.append('random_string',this.chat_info.random_string); + // formData.append('pd_id',this.chat_info.pd_id); + this.pdTriggerService.saveCusVideo(formData).subscribe(result=>{ + console.log(result); }) } connect() { @@ -410,6 +481,16 @@ export class VideoChatComponent implements OnInit { this.stopRecording().then(res=>{ }) + // 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() @@ -489,5 +570,31 @@ export class VideoChatComponent implements OnInit { 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/app/video-chat/video-player/video-player.component.html b/ng6-seed/src/app/video-chat/video-player/video-player.component.html new file mode 100644 index 000000000..9bad82550 --- /dev/null +++ b/ng6-seed/src/app/video-chat/video-player/video-player.component.html @@ -0,0 +1,22 @@ +
+ + + + +
+ + + + + + + \ No newline at end of file diff --git a/ng6-seed/src/app/video-chat/video-player/video-player.component.scss b/ng6-seed/src/app/video-chat/video-player/video-player.component.scss new file mode 100644 index 000000000..146c20da7 --- /dev/null +++ b/ng6-seed/src/app/video-chat/video-player/video-player.component.scss @@ -0,0 +1,9 @@ +::ng-deep { .video-player > mat-dialog-container { + background: rgba(255, 0, 0, 0.705); + padding: 0; + } +} +.mat-raised-button{ + color: #ffffff; + background: #ffffff5c; +} \ No newline at end of file diff --git a/ng6-seed/src/app/video-chat/video-player/video-player.component.spec.ts b/ng6-seed/src/app/video-chat/video-player/video-player.component.spec.ts new file mode 100644 index 000000000..e4f72b3ae --- /dev/null +++ b/ng6-seed/src/app/video-chat/video-player/video-player.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { VideoPlayerComponent } from './video-player.component'; + +describe('VideoPlayerComponent', () => { + let component: VideoPlayerComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ VideoPlayerComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(VideoPlayerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ng6-seed/src/app/video-chat/video-player/video-player.component.ts b/ng6-seed/src/app/video-chat/video-player/video-player.component.ts new file mode 100644 index 000000000..16b1aa7c9 --- /dev/null +++ b/ng6-seed/src/app/video-chat/video-player/video-player.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-video-player', + templateUrl: './video-player.component.html', + styleUrls: ['./video-player.component.scss'] +}) +export class VideoPlayerComponent implements OnInit { + videoSrc + // = 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4' + constructor() { } + + ngOnInit() { + let video_blob = localStorage.getItem('blob_url'); + if(video_blob) { + this.videoSrc = video_blob; + console.log(this.videoSrc); + } + } + +} diff --git a/ng6-seed/src/index.html b/ng6-seed/src/index.html index c97fe548d..615284e0f 100755 --- a/ng6-seed/src/index.html +++ b/ng6-seed/src/index.html @@ -13,6 +13,7 @@ + PD Genie