apphouse
Version:
Component library for React that uses observable state management and theme-able components.
91 lines (82 loc) • 2.48 kB
text/typescript
import { observable, action, makeObservable, computed } from "mobx";
import { audioLog } from "./AudioLog";
export class Recorder {
onRecordingComplete: (data: Blob) => void;
chunks: Blob[];
mediaRecorder: MediaRecorder | undefined;
// observables
recording: boolean;
stream: MediaStream | undefined;
constructor(onRecordingComplete: (data: Blob) => void) {
this.onRecordingComplete = onRecordingComplete;
this.recording = false;
this.mediaRecorder = undefined;
this.chunks = [];
makeObservable(this, {
isRecording: computed,
recording: observable,
stop: action,
start: action,
init: action,
});
}
get isRecording() {
return this.recording;
}
init = (stream: MediaStream | undefined) => {
console.log(
MediaRecorder.isTypeSupported("audio/wav;codecs=MS_PCM"),
);
audioLog.logRecorder("Initializing recorder with stream", stream);
if (stream) {
this.mediaRecorder = new MediaRecorder(stream, {
mimeType: "audio/webm;codecs=pcm",
});
this.mediaRecorder.ondataavailable = this.onDataAvailable;
this.mediaRecorder.onstop = this.onStop;
} else {
this.mediaRecorder = undefined;
console.warn("No media stream when initializing the recorder");
}
};
/**
*
* @param timeslice The number of milliseconds to record into each Blob. If this
* parameter isn't included, the entire media duration is recorded into a single
* Blob unless the requestData() method is called to obtain the Blob and trigger
* the creation of a new Blob into which the media continues to be recorded.
*/
start = (timeslice?: number) => {
this.chunks = [];
if (this.mediaRecorder) {
this.mediaRecorder.start(timeslice);
this.recording = true;
audioLog.recordingStart();
}
};
stop = () => {
if (!this.recording) {
return;
}
if (this.mediaRecorder) {
this.mediaRecorder.stop();
this.recording = false;
audioLog.recordingStop();
}
};
onDataAvailable = (event: BlobEvent) => {
this.chunks.push(event.data);
};
onStop = () => {
// prepare audio for playback/upload
if (typeof window != "undefined") {
console.log("chuncks:", this.chunks);
const data = new Blob(this.chunks, {});
audioLog.logRecorder(
"Prepare audio for playback [create blob]",
data,
);
this.onRecordingComplete(data);
}
};
}