Search code examples
javascripttypescriptconstructorangular6mediastream

MediaStreamRecorder is not a constructor


I'm new to Angular6 and I'm trying to use MediaStreamRecorder. I'm definitely doing something wrong when defining MediaStreamRecorder because I keep getting the error TypeError: msr__WEBPACK_IMPORTED_MODULE_4__.MediaStreamRecorder is not a constructor. Not sure how or where should I declare and define MediaStreamRecorder. Can you help me with this, please?

I have installed msr module, and my code looks like this:

import { Component,ViewChild, OnInit, Inject } from '@angular/core';
import { LinksService } from 'demo/_services/links.service';
import { Http,Response,Headers } from '@angular/http';
import { MediaStreamRecorder} from 'msr';
import { RecordRTC } from 'recordrtc';

@Component({
  selector: 'demo-ceva',
  templateUrl: './ceva.component.html',
  styleUrls: ['./ceva.component.css'],
  providers: [
    {
      provide: SpeechRecognitionLang,
      useValue: 'en-US',
    },    
    SpeechRecognitionService,
  ],
})
export class CevaComponent { 
  public navigator: any;      
  public MediaStreamRecorder: any;    
  constructor( private http: Http, private service: SpeechRecognitionService, private links: LinksService ) { 
this.record = () => {       
    var browser = <any>navigator;  
    var obj = { audio: true, video:false };
    browser.getUserMedia = (browser.getUserMedia || browser.webkitGetUserMedia || browser.mozGetUserMedia || browser.msGetUserMedia);     
    browser.mediaDevices.getUserMedia(obj).then(stream => {  
        var source = window.URL.createObjectURL(stream);      
        var config= { ... }  
        var recorder = new MediaStreamRecorder(stream, config);
        recorder.record();
        recorder.stop(function(blob) {     
            var blob = recorder.blob;
            console.log(blob);           
        });
   });
});

Solution

  • As the answer to this post suggested, the solution to me was that in typings.d.ts file to add the following declarations:

    declare interface MediaRecorderErrorEvent extends Event {
      name: string;
    }
    
    declare interface MediaRecorderDataAvailableEvent extends Event {
      data : any;
    }
    
    interface MediaRecorderEventMap {
      'dataavailable': MediaRecorderDataAvailableEvent;
      'error': MediaRecorderErrorEvent ;
      'pause': Event;
      'resume': Event;
      'start': Event;
      'stop': Event;
      'warning': MediaRecorderErrorEvent ;
    }
    
    
    declare class MediaRecorder extends EventTarget {
    
      readonly mimeType: string;
      // readonly MimeType: 'audio/wav';
      readonly state: 'inactive' | 'recording' | 'paused';
      readonly stream: MediaStream;
      ignoreMutedMedia: boolean;
      videoBitsPerSecond: number;
      audioBitsPerSecond: number;
    
      ondataavailable: (event : MediaRecorderDataAvailableEvent) => void;
      onerror: (event: MediaRecorderErrorEvent) => void;
      onpause: () => void;
      onresume: () => void;
      onstart: () => void;
      onstop: () => void;
    
      constructor(stream: MediaStream);
    
      start();
    
      stop();
    
      resume();
    
      pause();
    
      isTypeSupported(type: string): boolean;
    
      requestData();
    
    
      addEventListener<K extends keyof MediaRecorderEventMap>(type: K, listener: (this: MediaStream, ev: MediaRecorderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
    
      addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
    
      removeEventListener<K extends keyof MediaRecorderEventMap>(type: K, listener: (this: MediaStream, ev: MediaRecorderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
    
      removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
    

    And in my component, I was able to use var mediaRecorder = new MediaRecorder(stream); without any other declarations. Thank you, @firegloves , for the link to this post and thank you, @Tiberiu C. for the answer! It was really helpful.