Skip to content

Instantly share code, notes, and snippets.

@titouancreach
Created August 8, 2024 07:20
Show Gist options
  • Save titouancreach/74715506a0e104a49968e84a5eb46ef7 to your computer and use it in GitHub Desktop.
Save titouancreach/74715506a0e104a49968e84a5eb46ef7 to your computer and use it in GitHub Desktop.
type StateMachine = Data.TaggedEnum<{
Recording: {
stream: Stream.Stream<BlobEvent>,
mediaRecorder: MediaRecorder
};
Stoped: {};
}>;
export function TranscribeWhisper({ className }: { className?: string }) {
const { Stoped, Recording, $match, $is } = Data.taggedEnum<StateMachine>();
const [stateMachine, setStateMachine] = useState<StateMachine>(Stoped());
return (
<div className="self-start">
<Button
variant="icon-button"
size="child"
type="button"
className={twMerge(
"rounded-full",
className,
isRecording(stateMachine) && "bg-gray-700 text-white",
)}
onClick={async () => {
return await $match(stateMachine, {
Stoped: async () => {
if (navigator?.mediaDevices?.getUserMedia) {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
})
const mediaRecorder = new MediaRecorder(stream, {
mimeType: "audio/mp4",
});
// start accumulate elements
const dataStream = Stream.fromEventListener(mediaRecorder, "dataavailable") as Stream.Stream<BlobEvent>
mediaRecorder.start();
setStateMachine(Recording({
mediaRecorder,
stream: dataStream
}));
},
Recording: async ({ mediaRecorder, stream }) => {
mediaRecorder.stop();
setStateMachine(Stoped());
// do something with the stream to get all the elements accumulated in it
},
});
}}
>
<Mic className="size-4" />
</Button>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment