From 44e78b16d95c1d67528fd9138ed63f3324ce4f84 Mon Sep 17 00:00:00 2001 From: MarconLP <13001502+MarconLP@users.noreply.github.com> Date: Tue, 18 Apr 2023 23:05:05 +0200 Subject: [PATCH] add microphone recording and allow user to select audio device --- src/components/Recorder.tsx | 61 +++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/components/Recorder.tsx b/src/components/Recorder.tsx index 36e7007..e3b269b 100644 --- a/src/components/Recorder.tsx +++ b/src/components/Recorder.tsx @@ -1,27 +1,21 @@ -import React, { useState, useRef, Fragment } from "react"; +import React, { useState, useRef, Fragment, useEffect } from "react"; import RecordRTC, { invokeSaveAsDialog } from "recordrtc"; import { Listbox, Transition } from "@headlessui/react"; import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/20/solid"; -const people = [ - { name: "Wade Cooper" }, - { name: "Arlene Mccoy" }, - { name: "Devon Webb" }, - { name: "Tom Cook" }, - { name: "Tanya Fox" }, - { name: "Hellen Schmidt" }, -]; - export default function Recorder() { const [steam, setStream] = useState(null); const [blob, setBlob] = useState(null); const refVideo = useRef(null); const recorderRef = useRef(null); const [pause, setPause] = useState(false); - const [selected, setSelected] = useState<{ name: string }>(people[0]); + const [audioDevices, setAudioDevices] = useState([]); + const [selectedDevice, setSelectedDevice] = useState( + null + ); const handleRecording = async () => { - const mediaStream = await navigator.mediaDevices.getDisplayMedia({ + const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: { width: 1920, height: 1080, @@ -34,6 +28,16 @@ export default function Recorder() { }, }); + const micStream = await navigator.mediaDevices.getUserMedia({ + audio: { deviceId: selectedDevice?.deviceId }, + }); + + const mediaStream = new MediaStream(); + micStream.getAudioTracks().forEach((track) => mediaStream.addTrack(track)); + screenStream + .getVideoTracks() + .forEach((track) => mediaStream.addTrack(track)); + setStream(mediaStream); recorderRef.current = new RecordRTC(mediaStream, { type: "video" }); recorderRef.current.startRecording(); @@ -61,6 +65,23 @@ export default function Recorder() { } }; + useEffect(() => { + async function getAudioDevices() { + try { + const devices = await navigator.mediaDevices.enumerateDevices(); + const audioDevices = devices.filter( + (device) => device.kind === "audioinput" + ); + setAudioDevices(audioDevices); + if (audioDevices[0]) setSelectedDevice(audioDevices[0]); + } catch (error) { + console.error(error); + } + } + + void getAudioDevices(); + }, []); + const handleSave = () => { if (blob) { invokeSaveAsDialog(blob); @@ -98,11 +119,13 @@ export default function Recorder() { > save -
- +
+
- {selected.name} + + {selectedDevice?.label ?? "No device selected"} + - {people.map((person, personIdx) => ( + {audioDevices.map((audioDevice, i) => ( `relative cursor-default select-none py-2 pl-10 pr-4 ${ active @@ -127,7 +150,7 @@ export default function Recorder() { : "text-gray-900" }` } - value={person} + value={audioDevice} > {({ selected }) => ( <> @@ -136,7 +159,7 @@ export default function Recorder() { selected ? "font-medium" : "font-normal" }`} > - {person.name} + {audioDevice.label} {selected ? (