【问题标题】:Assigning Angular2 method to JS MediaRecorder event ondataavailable loses scope of Angular2 component variables将 Angular2 方法分配给 JS MediaRecorder ondataavailable 事件会失去 Angular2 组件变量的范围
【发布时间】:2017-06-13 00:49:25
【问题描述】:

我正在尝试转换此 webRTC 示例 https://webrtc.github.io/samples/src/content/getusermedia/record/ 在我的 Angular2 应用程序中运行。源代码也在 github 上 https://github.com/webrtc/samples/tree/gh-pages/src/content/getusermedia/record

它由 1 个简单的 html 页面和 1 个包含所有代码的 vanilla main.JS 文件组成。我尝试创建一个 plnkr 演示,但它不支持 navigator.GetUserMedia 调用,所以我会尽力在下面解释:

因此,我尝试将其转换为 Angular2 组件。我有以下内容:

import {Component, OnInit} from "@angular/core"

@Component({
    selector: "my-web-rtc-recording",
    templateUrl: 'app/test.web.rtc.recording.component.html'
})
export class TestWebRtcRecordingComponent implements OnInit {

    // -- private variables --
    startStop: string = "Start";
    mediaSource: MediaSource = new MediaSource();
    mediaRecorder: MediaRecorder;
    recordedBlobs: Blob[];  **// <<== This is the variable in question**
    sourceBuffer: any;

    gumVideo: HTMLVideoElement;
    recordedVideo: HTMLVideoElement;
    recordButton: HTMLButtonElement;
    playButton: HTMLButtonElement;
    downloadButton: HTMLButtonElement;

注意私有变量recordedBlobs。这将在我必须订阅的MediaRecorder 事件ondataavailable 事件中设置。问题出在哪里,我可以订阅事件但我的组件私有变量超出范围?

获取视频流后,我会执行以下操作:

this.recordedBlobs = [];
this.mediaRecorder = new MediaRecorder(window.stream);

然后我为事件分配一个 Angular 方法。

this.mediaRecorder.ondataavailable = this.handleDataAvailable;

我不确定这是正确的语法,但事件确实会触发并且数据已正确发送。

    handleDataAvailable(event) {
    // debugger;

    if (event.data && event.data.size > 0) {
        // Note: It is undefined here because it is a different scope?
        // I'm trying to figure this out why these are 2 sep variables
        // My hunch is they are being updated in different processes
        if (this.recordedBlobs == undefined)
        {
            console.log('this.recordedBlobs is undefined');
            this.recordedBlobs = [];
        }
        // Add each recorded data event to our array of blobs    
        if (event.data != undefined)
            this.recordedBlobs.push(event.data);
        console.log('Recorded Blob Count = ', this.recordedBlobs.length);
    }
}

所以问题是我对this.recordedBlobs 的引用不再是对我的组件私有变量的引用。

事实上,这引用了mediaRecorder 对象而不是我的组件,这就是为什么我必须检查未定义并初始化它的原因。那么我在这里缺少什么。

这是在不同的区域或线程中触发并且我无法访问我的 Angular2 组件范围变量吗?我必须能够设置一个变量,以便在录制完成后我可以参考recordedBlobs。由于这不是像 onclick() 这样的预定义 DOM 事件,我是否需要为 Angular 做一些额外的事情来处理它?

任何关于其他尝试的想法将不胜感激......

凯文

【问题讨论】:

  • 如何将 MediaRecorder 添加到 angular2?请帮帮我

标签: javascript angular


【解决方案1】:

我终于解决了它...经过几天的文档挖掘并查看了多个示例项目...当我看到一个示例时,我正在着手编写一个围绕 MediaRecorder 对象的 JS 包装器以尝试公开一个属性即时添加了一个 JS 属性,我突然想到,这可能会做到!

所以这是一个“范围”问题,当触发 mediaRecord 事件并且调用我本地分配的 Angular“handleDataAvailable”方法时,“this”变量的范围已更改为 MediaRecorder 对象并且不再引用 Angular零件。因此,组件变量超出范围。我仍然觉得奇怪的是,Angular 没有提供一种方法来访问事件处理程序代码中的私有组件变量,因为它是在组件中定义的。

但事实证明,修复很简单,我可以在 MediaRecord 对象中即时添加一个属性,然后在两个地方都引用它。

this.mediaRecorder = new MediaRecorder(window.stream);
this.mediaRecord.blobs = []; <== This adds a new .blobs property on-the-fly

然后我在事件处理程序代码中引用了这个新的 mediaRecorder.blobs 属性。

// Add each recorded data event to our array of blobs    
if (event.data != undefined)
    this.blobs.push(event.data); <== Now referencing the new .blobs property I added.

当我从处理程序返回时,我可以引用this.mediaRecorder.blobs 属性,它具有在事件处理程序中分配的数据。

所以现在我在组件和事件处理程序的范围内都有一个属性,这正是我所需要的。问题解决了,迎接下一个挑战!

凯文

【讨论】:

  • 您的最终代码是否托管在任何我可以查看的地方?我试图弄清楚如何连接来自ondataavailable 的所有 blob,并正在寻找一个示例。
  • 您可以将 blobChunks 数组转换为新的 Blob,并使用它来重播视频或将其保存到文件中。所以要重播它,我这样做: var blob = new Blob(blobChunks, {type: 'video/webm'}); this.recordedVideo.src = window.URL.createObjectURL(blob)
  • 我很幸运地在更新部分添加了:this.zone.run(() => { ...}。这是构造函数中的 NgZone
猜你喜欢
  • 2020-07-13
  • 2016-05-26
  • 1970-01-01
  • 2017-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-27
相关资源
最近更新 更多