Mercurial > hg > ugly-duckling
changeset 294:ea81b6199eaf
Merge pull request #35 from piper-audio/fix/mic-permission-request-on-record
Request microphone access when trying to record, not on construction.
author | Lucas Thompson <LucasThompson@users.noreply.github.com> |
---|---|
date | Mon, 08 May 2017 17:38:12 +0100 |
parents | 71f9286da66f (current diff) 53aaf72c2fd0 (diff) |
children | f16705a58887 |
files | |
diffstat | 1 files changed, 33 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/src/app/services/audio-recorder/audio-recorder.service.ts Fri May 05 15:02:27 2017 +0100 +++ b/src/app/services/audio-recorder/audio-recorder.service.ts Mon May 08 17:38:12 2017 +0100 @@ -9,7 +9,7 @@ // seems the TypeScript definitions are not up to date, // introduce own types for now -export type AudioInputProvider = () => PromiseLike<MediaStream>; +export type AudioInputProvider = () => Promise<MediaStream>; export interface MediaRecorderOptions { mimeType?: string; @@ -102,12 +102,11 @@ export class AudioRecorderService { private requestProvider: AudioInputProvider; private recorderImpl: MediaRecorderConstructor; - private recorder: MediaRecorder; + private currentRecorder: MediaRecorder; private recordingStateChange: Subject<RecorderServiceStatus>; recordingStateChange$: Observable<RecorderServiceStatus>; private newRecording: Subject<Blob>; newRecording$: Observable<Blob>; - private isRecordingAble: boolean; private isRecording: boolean; private chunks: Blob[]; @@ -122,67 +121,57 @@ this.recordingStateChange$ = this.recordingStateChange.asObservable(); this.newRecording = new Subject<Blob>(); this.newRecording$ = this.newRecording.asObservable(); - this.isRecordingAble = false; this.isRecording = false; this.chunks = []; - this.hasRecordingCapabilities(); } - private hasRecordingCapabilities(): void { - this.requestProvider().then(stream => { - try { - this.recorder = new this.recorderImpl(stream); - - this.recorder.ondataavailable = e => this.chunks.push(e.data); - this.recorder.onstop = () => { - const blob = new Blob(this.chunks, { 'type': this.recorder.mimeType }); - this.chunks.length = 0; - this.ngZone.run(() => { - this.newRecording.next( - blob - ); - }); - }; - this.isRecordingAble = true; - this.recordingStateChange.next('enabled'); - } catch (e) { - this.isRecordingAble = false; - this.recordingStateChange.next('disabled'); // don't really need to do this - console.warn(e); // TODO emit an error message for display? - } - }, rejectMessage => { - this.isRecordingAble = false; - this.recordingStateChange.next('disabled'); // again, probably not needed - console.warn(rejectMessage); // TODO something better + private getRecorderInstance(): Promise<MediaRecorder> { + return this.requestProvider().then(stream => { + const recorder = new this.recorderImpl(stream); + recorder.ondataavailable = e => this.chunks.push(e.data); + recorder.onstop = () => { + const blob = new Blob(this.chunks, {'type': recorder.mimeType}); + this.chunks.length = 0; + this.ngZone.run(() => { + this.newRecording.next( + blob + ); + }); + }; + return recorder; }); } toggleRecording(): void { - if (!this.isRecordingAble) { - return; - } - if (this.isRecording) { this.endRecording(); } else { - this.startRecording(); + this.getRecorderInstance() + .then(recorder => this.startRecording(recorder)) + .catch(e => { + this.recordingStateChange.next('disabled'); // don't really need to do this + console.warn(e); // TODO emit an error message for display? + }); } } - private startRecording(): void { - if (this.recorder) { - this.isRecording = true; - this.recorder.start(); - this.recordingStateChange.next('recording'); - } + private startRecording(recorder: MediaRecorder): void { + this.currentRecorder = recorder; + this.isRecording = true; + recorder.start(); + this.recordingStateChange.next('recording'); } private endRecording(): void { - if (this.recorder) { + if (this.currentRecorder) { this.isRecording = false; - this.recorder.stop(); + this.currentRecorder.stop(); + for (const track of this.currentRecorder.stream.getAudioTracks()) { + track.stop(); + } this.chunks.length = 0; // empty the array this.recordingStateChange.next('enabled'); + this.currentRecorder = null; } } }