Fairoj : general form text issue, video player component created, splitted recording is implemented and save api is added

This commit is contained in:
venbatechnologies@gmail.com 2020-06-02 20:23:04 +05:30
parent d7da29993f
commit 6e5966f847
15 changed files with 272 additions and 27 deletions

View File

@ -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",

View File

@ -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",

7
ng6-seed/proxy.conf.json Normal file
View File

@ -0,0 +1,7 @@
{
"/api/": {
"target": "http://localhost/",
"secure": false,
"changeOrigin": true
}
}

View File

@ -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 { }

View File

@ -1,3 +1,4 @@
<!-- <button mat-raised-button (click) ="openPlayer()">player</button> -->
<div class="pad-wrap" [style.minHeight]="'100%'">
<div fxFlex.gt-sm="100" fxFlex.gt-xs="100" fxFlex="100">
<mat-card *ngIf="access; else unauthorized;">

View File

@ -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'
// })
// }
}

View File

@ -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;
}

View File

@ -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%;
// }

View File

@ -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);
}
}

View File

@ -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<VideoChatComponent>,
@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;
// });
// }
}

View File

@ -0,0 +1,22 @@
<div align="end" style="position: absolute;right: 10%;z-index: 999" fxLayoutAlign="flex-end">
<!-- <button mat-raised-button mat-icon-button class="mr-1 mb-1 hover-icon" type="button" matTooltip="reset"
matTooltipPosition="right" (click)="clearRandomString()" *ngIf="!is_video_enable" >
<mat-icon>cached</mat-icon>
</button> -->
<button mat-raised-button mat-icon-button class="mr-1 mb-1 hover-icon" type="button" matTooltip="Close"
matTooltipPosition="right" mat-dialog-close>
<mat-icon>close</mat-icon>
</button>
<!-- <button mat-raised-button mat-icon-button class="mr-1 mb-1 hover-icon" type="button" matTooltip="Close"
matTooltipPosition="right" (click)="stopRecording()">
<mat-icon>stop</mat-icon>
</button> -->
</div>
<!-- <mat-video src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"></mat-video> -->
<mat-video title="My Tutorial Title" [autoplay]="true" [preload]="true" [fullscreen]="true" [download]="false" color="primary" spinner="spin" poster="image.jpg">
<source matVideoSource [src]="videoSrc" type="video/webm">
<!-- <source src="tutorial.webm" type="video/webm"> -->
<!-- <track matVideoTrack src="subtitles_en.vtt" kind="subtitles" srclang="en" label="English"> -->
<!-- <track src="subtitles_no.vtt" kind="subtitles" srclang="no" label="Norwegian"> -->
</mat-video>

View File

@ -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;
}

View File

@ -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<VideoPlayerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ VideoPlayerComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(VideoPlayerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -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);
}
}
}

View File

@ -13,6 +13,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/simple-peer/9.7.0/simplepeer.min.js"></script>
<!-- <script src="node_modules/recordrtc/RecordRTC.js"></script> -->
<script src="https://www.WebRTC-Experiment.com/RecordRTC.js"></script>
<script src="https://www.webrtc-experiment.com/EBML.js"></script>
<!-- <title>Optima - Angular 6 Material Admin Template</title> -->
<title> PD Genie </title>