将Angular2方法分配给JS MediaRecorder事件ondataavailable丢失了Angular2组件变量的范围

时间:2016-06-23 22:00:41

标签: javascript angular

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

它包含一个简单的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对象而不是我的组件,这就是我必须检查undefined并初始化它的原因。那么我在这里错过了什么。

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

任何有关其他尝试的想法都会受到赞赏....

凯文

1 个答案:

答案 0 :(得分:1)

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

所以它是一个&#34;范围&#34;问题,当mediaRecord事件被触发并且我的本地分配了Angular&#34; handleDataAvailable&#34;方法被称为&#34;这个&#34;变量已更改为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属性,并且它具有在事件处理程序中分配的数据。

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

凯文