Fairoj : Video Upload feature implemented

This commit is contained in:
venbatechnologies@gmail.com 2020-11-11 17:44:43 +05:30
parent 31007bd525
commit 1cd45dba06
14 changed files with 284 additions and 7 deletions

View File

@ -132,6 +132,10 @@
<div fxFlex.xs="100" fxFlex.sm="100" fxFlex.md="60" fxFlex.lg="70" fxFlex.xl="70" class="content-data" *ngFor="let master of pdMasterData">
<div fxLayout="row">
<div fxFlex="100" align="right">
<button *ngIf="master.fk_pd_type == '2'" mat-stroked-button class="mr-1 mb-1" color="primary" (click)="uploadRecordedVideo()">
<mat-icon>videocam</mat-icon>&nbsp;
<strong>Upload</strong>
</button>
<span> <button *ngIf="master.fk_pd_type == '2'"
mat-raised-button mat-icon-button class="mr-1 mb-1 hover-icon" type="button" (click)="copyCusURL()"
matTooltip="Copy Customer Image Recapture Link" matTooltipPosition="above" >

View File

@ -22,6 +22,7 @@ import { QcCusImagesComponent } from 'app/quality-check/qc-cus-images/qc-cus-ima
import { PdTrigerService } from 'app/personal-discussion/pd-service/pd-triger.service';
import { VideoPlayerComponent } from 'app/video-chat/video-player/video-player.component';
import { PdVisitTimeComponent } from '../pd-visit-time/pd-visit-time.component';
import { UploadVideoComponent } from 'app/quality-check/upload-video/upload-video.component';
@Component({
selector: 'app-qc-view',
@ -409,6 +410,14 @@ export class QcViewComponent implements OnInit, OnDestroy {
}
})
}
uploadRecordedVideo() {
const dialogRef = this.dialog.open(UploadVideoComponent,{
minWidth:'50vw',
disableClose:true,
data:{pd_id:this.viewID,random_string:this.masterRandomString}
// maxWidth:'75vw'
})
}
// getVideoUrl(pd_id,randomStr){
// let params = {"pd_id":pd_id,"random_string":randomStr}
// this.pdService.getRecordedPlaybackUrl(params).subscribe(result=>{

View File

@ -653,5 +653,10 @@ export class QcService {
getRecordedPlaybackUrl(params){
return this._http.post(this.apiUrl+'getVideoURL',params)
}
uploadVideoFile(params) {
// uploadVideoFile - records -> {"fk_pd_id":"1982","random_string":"s0hbw88AwQMVlbHw"},
// video_file -> exact file
return this._http.post(this.apiUrl+'uploadVideoFile',params)
}
}

View File

@ -106,7 +106,9 @@ import { QcNewComponent } from './qc-list/qc-pd-report/qc-new/qc-new.component';
import {AngularSplitModule} from 'angular-split';
import { QcCusImagesComponent } from './qc-cus-images/qc-cus-images.component';
import { PdVisitTimeComponent } from './qc-list/pd-visit-time/pd-visit-time.component'
import { PdVisitTimeComponent } from './qc-list/pd-visit-time/pd-visit-time.component';
import { UploadVideoComponent } from './upload-video/upload-video.component'
import { MatVideoModule } from 'mat-video';
// import { PdfViewerModule } from 'ng2-pdf-viewer';
@ -180,9 +182,9 @@ const customNotifierOptions: NotifierOptions = {
PdfViewerModule,
ManagePdModule,
AngularSplitModule.forRoot(),
MatVideoModule
],
declarations: [QualityCheckComponent,QcListComponent, QcViewComponent, QcStartComponent, QcPdReportComponent,DialogChangeCurrentVenrsion, QcReviewComponent, ModelEditPdReportComponent, NumberToWordsPipe, QcNewComponent, QcCusImagesComponent, PdVisitTimeComponent],
declarations: [QualityCheckComponent,QcListComponent, QcViewComponent, QcStartComponent, QcPdReportComponent,DialogChangeCurrentVenrsion, QcReviewComponent, ModelEditPdReportComponent, NumberToWordsPipe, QcNewComponent, QcCusImagesComponent, PdVisitTimeComponent, UploadVideoComponent],
entryComponents: [PdVisitTimeComponent,PdAllocationComponent, SmartPdAllocationComponent, SchedulePdComponent, EditPdApplicantComponent, EditPdMasterComponent,DialogChangeCurrentVenrsion, QcReviewComponent, ModelEditPdReportComponent, InitiateAdditionalPdComponent,QcNewComponent,
BusinessAssetsInfoComponent,
ClientInfoComponent,
@ -219,7 +221,8 @@ const customNotifierOptions: NotifierOptions = {
ManageDailyPurchaseComponent,
ManageRentalVerificationComponent,
FuturePlansAndBusinessEnvironmentComponent,
QcCusImagesComponent],
QcCusImagesComponent,
UploadVideoComponent],
providers : [QcService,{provide: MAT_DATE_LOCALE, useValue: 'en-GB'},
{provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
{provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS},PdLocatedMapViewDirective],

View File

@ -0,0 +1,30 @@
<div style="float: right;">
<button mat-icon-button aria-label="Close" mat-dialog-close>
<mat-icon>close</mat-icon>
</button>
</div>
<div fxLayout="row" fxLayoutAlign="center">
<p style="color: red;margin: 0;">Allowed Format .mp4, .mkv, .avi, .webm, .mov</p>
</div>
<div fxLayout="row">
<label class="custom-file-upload">
<input type="file" id='excel-upload' accept=".mp4, .mkv, .avi, .webm, .mov" multiple="false"
(change)="inputExcelOnClick($event)" />
Choose Video File
</label>
</div>
<div style="height: 45vh !important;width:45vw !important;justify-content: center; margin-top: 3%;" *ngIf="videoSrc" [ngStyle.xs]="{'width':'auto'}">
<mat-video #myVideo [title]="file_attributes.name" [autoplay]="true" [preload]="true" [fullscreen]="true" color="primary" spinner="spin" poster="../../assets/images/img/video-icon.png">
<source matVideoSource [src]="videoSrc" type="video/webm">
</mat-video>
</div>
<div fxLayout="row" *ngIf="file_attributes.name">
<p style="font-size: 17px;font-weight: bold;white-space: pre-wrap;
overflow: hidden;
word-break: break-all;">{{file_attributes.name}} | <span style="color: gray;">{{(file_attributes.size/ (1024*1024)).toFixed(2)}} MB</span></p>
</div>
<div align="end" style="margin-top: 10px;">
<button [disabled]="!file_attributes || !uploadedVideo" mat-raised-button color="primary" (click)="uploadVideo()">Upload</button>
</div>
<notifier-container></notifier-container>

View File

@ -0,0 +1,13 @@
input[type="file"] {
display: none;
}
.custom-file-upload {
border: 1px solid red;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
}
.custom-file-upload :hover{
background-color: rgba(255, 0, 0, 0.317);
color: rgba(255, 0, 0, 0.317);
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { UploadVideoComponent } from './upload-video.component';
describe('UploadVideoComponent', () => {
let component: UploadVideoComponent;
let fixture: ComponentFixture<UploadVideoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ UploadVideoComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UploadVideoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,113 @@
import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { DomSanitizer } from '@angular/platform-browser';
import { NotifierService } from 'angular-notifier';
import { LoaderService } from 'app/shared/loaderService/loader.service';
import { QcService } from '../qc-service/qc.service';
@Component({
selector: 'app-upload-video',
templateUrl: './upload-video.component.html',
styleUrls: ['./upload-video.component.scss']
})
export class UploadVideoComponent implements OnInit {
file_attributes: any = {};
notifier: NotifierService;
uploadedVideo: any;
videoSrc: any;
@ViewChild('myVideo') myVideo: any;
constructor(notifier:NotifierService,private dialogRef:MatDialogRef<UploadVideoComponent>,private loaderService:LoaderService,private qcService:QcService
,@Inject(MAT_DIALOG_DATA)private pd_details:any) {
this.notifier=notifier
}
ngOnInit() {
}
inputExcelOnClick(evt) {
const target: HTMLInputElement = evt.target;
if (target.files.length === 0) {
this.notifier.notify('info',"No files Choosen")
this.file_attributes = {}
this.videoSrc = ''
this.uploadedVideo = ''
throw new Error('未上傳');
}
if (target.files.length > 1) {
this.notifier.notify('info',"Please Upload Single Video File")
this.file_attributes = {}
this.videoSrc = ''
this.uploadedVideo = ''
throw new Error('Cannot use multiple files');
}
let is_video = this.checkFileExtension(evt.target.files.item(0).name)
if(!is_video) {
this.notifier.notify("info","Please Upload the file with allowed video format")
this.file_attributes = {}
this.videoSrc = ''
this.uploadedVideo = ''
return
}
this.file_attributes = evt.target.files.item(0);
const reader: FileReader = new FileReader();
// this.readerExcel(reader);
reader.readAsArrayBuffer(target.files[0]);
this.uploadedVideo = target.files[0];
console.log(this.file_attributes,this.uploadedVideo)
let url= URL.createObjectURL(this.uploadedVideo);
if(url) {
console.log("First",url)
// this.videoSrc = this.domSanitizer.bypassSecurityTrustResourceUrl(url)
this.videoSrc = url
console.log("second",this.videoSrc)
}
// this.isEmptyDrop = false;
// this.isExcelDrop = true;
}
checkFileExtension(uploadpath) {
var fileExtension = uploadpath.substring(uploadpath.lastIndexOf(".") + 1, uploadpath.length);
if (fileExtension == "mp4" || fileExtension == "mkv" || fileExtension == "avi" || fileExtension == "webm" || fileExtension == "mov") {
//write code for success
return true;
}
else {
//error code - select only excel files
return false;
}
}
uploadVideo() {
console.log("clicked")
if(!this.uploadedVideo || !this.file_attributes) {
this.notifier.notify('info',"File is missing please choose the file again")
return;
}
console.log(this.myVideo)
if(this.myVideo && this.myVideo.video && this.myVideo.video.nativeElement) {
this.myVideo.video.nativeElement.pause();
}
this.loaderService.showMatSpinnerDialog("Upload is in progress.. Please wait..")
let records = {"fk_pd_id":this.pd_details.pd_id,"random_string":this.pd_details.random_string}
let formData= new FormData()
formData.append("video_file",this.uploadedVideo)
formData.append("records",JSON.stringify(records))
this.qcService.uploadVideoFile(formData).subscribe(res=>{
if(res['dataStatus']) {
this.notifier.notify("success","Video Uploaded successfully")
this.dialogRef.close(res)
}
else{
this.notifier.notify('warning',"Something went wrong")
}
this.loaderService.closeMatSpinnerDialog()
},err=>{
this.loaderService.closeMatSpinnerDialog()
console.log(err)
this.notifier.notify('warning',"Network Error")
})
}
}

View File

@ -1,5 +1,7 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material';
import { Subject } from 'rxjs';
import { ProgressSpineerDialogComponent } from '../progress-spineer-dialog/progress-spineer-dialog.component';
export interface LoaderState {
show: boolean;
}
@ -9,11 +11,26 @@ export interface LoaderState {
export class LoaderService {
private loaderSubject = new Subject<LoaderState>();
loaderState = this.loaderSubject.asObservable();
constructor() { }
spinnerdialogRef: any;
constructor(private dialog:MatDialog) { }
show() {
this.loaderSubject.next(<LoaderState>{ show: true });
}
hide() {
this.loaderSubject.next(<LoaderState>{ show: false });
}
showMatSpinnerDialog(message :String = '') {
this.spinnerdialogRef = this.dialog.open(ProgressSpineerDialogComponent, {
data:message,
panelClass: 'transparent',
// minHeight:'20%',
minWidth:'20%',
disableClose: true
});
}
closeMatSpinnerDialog() {
if(this.spinnerdialogRef) {
this.spinnerdialogRef.close();
}
}
}

View File

@ -0,0 +1,4 @@
<div fxLayout="column" fxLayoutAlign="center">
<mat-spinner style="text-align: center;margin-left: 85px;" fxLayoutAlign="center"></mat-spinner>
<p style="font-weight: bold;color: white;text-align: center;"> {{spinnerMsg}}</p>
</div>

View File

@ -0,0 +1,5 @@
::ng-deep {.transparent > .mat-dialog-container {
box-shadow: none;
background: rgba(0, 0, 0, 0.0);
}
}

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ProgressSpineerDialogComponent } from './progress-spineer-dialog.component';
describe('ProgressSpineerDialogComponent', () => {
let component: ProgressSpineerDialogComponent;
let fixture: ComponentFixture<ProgressSpineerDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProgressSpineerDialogComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProgressSpineerDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,18 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material';
@Component({
selector: 'app-progress-spineer-dialog',
templateUrl: './progress-spineer-dialog.component.html',
styleUrls: ['./progress-spineer-dialog.component.scss']
})
export class ProgressSpineerDialogComponent implements OnInit {
spinnerMsg:String=''
constructor(@Inject(MAT_DIALOG_DATA)private data:any) {
this.spinnerMsg= this.data
}
ngOnInit() {
}
}

View File

@ -7,8 +7,11 @@ import { ToggleFullscreenDirective } from './fullscreen/toggle-fullscreen.direct
import { RatingComponent} from './rating/rating.component';
import { NumbersOnlyDirective } from './numbers-only/numbers-only.directive';
import { ForMobileNumbersDirective } from './for-mobile-numbers/for-mobile-numbers.directive';
import { ProgressSpineerDialogComponent } from './progress-spineer-dialog/progress-spineer-dialog.component';
import { MatProgressSpinnerModule } from '@angular/material';
@NgModule({
entryComponents:[ProgressSpineerDialogComponent],
declarations: [
AccordionAnchorDirective,
AccordionLinkDirective,
@ -16,8 +19,10 @@ import { ForMobileNumbersDirective } from './for-mobile-numbers/for-mobile-numbe
ToggleFullscreenDirective,
RatingComponent,
NumbersOnlyDirective,
ForMobileNumbersDirective
ForMobileNumbersDirective,
ProgressSpineerDialogComponent
],
imports:[MatProgressSpinnerModule],
exports: [
AccordionAnchorDirective,
AccordionLinkDirective,
@ -25,7 +30,8 @@ import { ForMobileNumbersDirective } from './for-mobile-numbers/for-mobile-numbe
ToggleFullscreenDirective,
RatingComponent,
NumbersOnlyDirective,
ForMobileNumbersDirective
ForMobileNumbersDirective,
ProgressSpineerDialogComponent
],
providers: [ MenuItems, HorizontalMenuItems ]
})