为什么即使使用属性绑定 [src],图像 src 也不会更新?



我正在尝试使用getDisplayMedia()捕获屏幕(我使用外部js使用getDisplayMedia(),因为我想角度4不支持它)。在第一次点击事件中,它显示准确的屏幕截图图像,但之后它不会从第二次点击事件开始更新图像。

我试过:

  • 要使用更新src创建动态元素,但bypassSecurityTrustUrl()需要src绑定为属性。 即[src]="屏幕截图"。所以我想我不能在动态元素创建中做到这一点。
  • 清除画布和图像src最初每当发生单击事件时。 另请注意,资源链接是基于base64URL。

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>

适配器.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'}});
}
}

我希望每次发生点击事件时,图像都应该使用新的屏幕截图进行更新,而不是停留在旧的屏幕截图上。

新记录的屏幕数据块被附加到数组中。this.chunks.push(event.data);

每当视频播放器开始播放录制时,它总是从开始时录制的内容开始。因此,屏幕截图始终取自初始帧。这是实际的错误。 解决方案是清除_takeScreenshot内部的块数组。

this.chunks = []

最新更新