我正在尝试使用getDisplayMedia()
捕获屏幕(我想使用外部js来使用getDisplayMedia()
,因为我想角度4不支持它)。第一次单击事件时,它会显示准确的屏幕截图图像,但此后它不会从第二次单击事件开始更新图像。
我尝试过:
src
创建动态元素,但是bypassSecurityTrustUrl()
需要将src
绑定为属性。即[src]
=“屏幕截图”。所以我想我不能在动态元素创建中做到这一点。 src
。
另外请注意,资源链接是基于base64
的URL。app.component.ts
import { Component, HostListener } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { TranslateService } from '@ngx-translate/core';
import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';
import { NotificationService } from './primary/services/notification.service';
import { AppConstants } from './shared/AppConstants';
import { CookieService } from './primary/services/cookie-service';
import {DialogboxService} from './primary/services/dialogbox.service';
//Core javascript classes.
declare var MediaRecorder: any;
declare var getStream: any;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// _navigator:any = null;
displayPopup: boolean = false;
msgs: any;
subscription: Subscription;
flag: any;
stream = null;
shadowRoot = null;
videoplayer = null;
chunks = [];
mediaRecorder = null;
status = 'Inactive';
recording = null;
screenshot = null;
validNavigation = 0;
contx = null;
canvas = null;
constructor(public notifyer: NotificationService, private translate: TranslateService,
public _cookieService:CookieService, private dialogboxService:DialogboxService,
private sanitizer: DomSanitizer) {
AppConstants.LANGUAGE = 'en';
translate.setDefaultLang(AppConstants.LANGUAGE);
translate.use(AppConstants.LANGUAGE);
this.subscription = this.notifyer.notificationChange
.subscribe(msgs => {
this.msgs = msgs;
});
}
ngOnInit(){
this.videoplayer = document.getElementById("invisibleVideo")
this.canvas = document.getElementById("myCanvas");
this.canvas.width = window.innerWidth; //document.width is obsolete
this.canvas.height = window.innerHeight;
}
//to take timeout
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async _takeScreenshot(){
this.stream = await getStream();
this.mediaRecorder = new MediaRecorder(this.stream, {mimeType: 'video/webm'});
this.mediaRecorder.addEventListener('dataavailable', event => {
if (event.data && event.data.size > 0) {
this.chunks.push(event.data);
}
});
this.mediaRecorder.start(100);
await this.sleep(1200);
this.mediaRecorder.stop();
this.mediaRecorder = null;
this.stream.getTracks().forEach(track => track.stop());
this.stream = null;
//allow dynamic source base64 URL
this.recording = this.sanitizer.bypassSecurityTrustUrl(window.URL.createObjectURL(new Blob(this.chunks, {type: 'video/webm'})));
await this.sleep(600);
this.contx = this.canvas.getContext("2d")
this.contx.drawImage(this.videoplayer,0,0)
//allow dynamic source base64 URL
this.screenshot = this.sanitizer.bypassSecurityTrustUrl(this.canvas.toDataURL('image/png'))
this.canvas.width = window.innerWidth; //document.width is obsolete
this.canvas.height = window.innerHeight;
this.displayPopup = true;
}
takeSelfie(){
this._takeScreenshot();
}
}
app.component.html
<script src="../assets/adapter.js"></script>
<style>
video {
--video-width: 100%;
width: var(--video-width);
height: calc(var(--video-width) * (16 / 9));
}
</style>
<p-dialog [positionTop]="40" (onHide)="displayPopup=false" [styleClass]="'popup_width'"
header='Report Bug' [(visible)]="displayPopup" modal="modal" [responsive]="true">
<div id="ssDiv">
<img [src]="screenshot" id="ssImg" class="ssImg">
</div>
<div id="container">
<canvas id="myCanvas"></canvas>
<div id="vDiv">
<video style="display:none" controls="true" id="invisibleVideo" playsinline
autoplay loop muted [src]="recording ? recording : ''"></video>
</div>
</div>
</p-dialog>
<button class="report-bug-button" (click)="takeSelfie()">
<i class="fa fa-camera" aria-hidden="true" style="color:white;font-size: 25px;"></i>
</button>
adapter.js
var getStream = function getStream(){
if (navigator.getDisplayMedia) {
return navigator.getDisplayMedia({video: true});
} else if (navigator.mediaDevices.getDisplayMedia) {
return navigator.mediaDevices.getDisplayMedia({video: true});
} else {
return navigator.mediaDevices.getUserMedia({video: {mediaSource: 'screen'}});
}
}
我希望每次发生单击事件时,图像都应使用新的屏幕截图进行更新,而不是停留在较旧的屏幕截图上。
答案 0 :(得分:0)
新记录的屏幕数据块将附加到数组中。 this.chunks.push(event.data);
每当视频播放器开始播放记录时,它始终以开始时记录的内容开始。因此,屏幕快照总是从初始帧中获取。这是实际的错误。
解决方法是清除_takeScreenshot
内部的块数组。
this.chunks = []