angular - 为什么即使使用属性绑定 [src],图像 src 也不会更新?
问题描述
我正在尝试使用捕获屏幕getDisplayMedia()
(我使用了外部 js,getDisplayMedia()
因为我猜 angular 4 不支持它)。在第一次点击事件时,它会显示准确的截图图像,但之后它不会从第二次点击事件开始更新图像。
我试过:
- 使用 update 创建动态元素
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>
适配器.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 = []
推荐阅读
- sql - 按列分组确切的词或相同的前两个词或相同的前三个词
- json - JSON中的“\”是什么?
- angular - 使用spring security angular和rest API重新加载页面给我错误401
- android - Android apk 在 AppGallery 上的新华为设备上不可见
- powershell - Powershell 复杂复制并创建包含父级名称的目录
- python - 如何从子目录中的 .py 文件导入类?
- sql - 在免费产品上使用 sql case 计算金额
- javascript - react js中动态生成的切换(开关)不起作用
- mysql - 归类电影最多的公司
- r - 在 R 中使用带有 dbplyr 的 pl/sql trunc 函数