Mercurial > hg > ugly-duckling
changeset 445:a9fb6590a3dc
Implement a MediaRecorder backed by RecordRTC. Definitely not spec compliant but is at least interface compatible with the methods used in the app.
author | Lucas Thompson <dev@lucas.im> |
---|---|
date | Mon, 26 Jun 2017 16:16:19 +0100 |
parents | 72d9303a1513 |
children | be88a0e965d7 |
files | src/app/services/audio-recorder/RecordRtcMediaRecorder.ts |
diffstat | 1 files changed, 85 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/app/services/audio-recorder/RecordRtcMediaRecorder.ts Mon Jun 26 16:16:19 2017 +0100 @@ -0,0 +1,85 @@ +/** + * Created by lucast on 26/06/2017. + */ +import { + BlobEvent as IBlobEvent, + MediaRecorder, + MediaRecorderErrorEvent, + RecordingState +} from './audio-recorder.service'; +import * as RecordRtc from 'recordrtc'; + +// safari doesn't implement BlobEvent... this should do +class BlobEvent extends Event implements IBlobEvent { + data: Blob; + + constructor(data: Blob) { + super('blob'); + this.data = data; + } +} + +export class RecordRtcMediaRecorder implements MediaRecorder { + mimeType: string; + state: RecordingState; + stream: MediaStream; + ignoreMutedMedia: boolean; + videoBitsPerSecond: number; + audioBitsPerSecond: number; + onstart: (evt: Event) => void; + onstop: (evt: Event) => void; + ondataavailable: (evt: BlobEvent) => void; + onpause: (evt: Event) => void; + onresume: (evt: Event) => void; + onerror: (evt: MediaRecorderErrorEvent) => void; + + private recorder: any; // TODO RecordRTC typings? + + static isTypeSupported(mimeType: string): boolean { + return mimeType === 'audio/wav'; + } + + constructor(stream: MediaStream) { + this.state = 'inactive'; + this.stream = stream; + this.recorder = RecordRtc(stream, { + type: 'audio', + recorderType: RecordRtc.StereoAudioRecorder + }); + } + + + pause(): void { + this.state = 'paused'; + this.recorder.pauseRecording(); + } + + requestData(): void { + // could probably implement this, but it isn't actually used in the app + throw new Error('Not implemented'); + } + + resume(): void { + this.state = 'recording'; + this.recorder.resumeRecording(); + } + + start(timeslice?: number): void { + this.state = 'recording'; + this.recorder.startRecording(); + } + + stop(): void { + this.state = 'inactive'; + this.recorder.stopRecording(() => { + if (this.ondataavailable) { + const blob = this.recorder.getBlob(); + this.mimeType = blob.type; + this.ondataavailable(new BlobEvent(blob)); + } + if (this.onstop) { + this.onstop(new Event('stop')); + } + }); + } +}