Socket
Socket
Sign inDemoInstall

@nolanholden/use-media-recorder

Package Overview
Dependencies
3
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    @nolanholden/use-media-recorder

Headless React hooks for the MediaStream Recording API for audio, video, and screen recording.


Version published
Weekly downloads
4
increased by100%
Maintainers
1
Created
Weekly downloads
 

Readme

Source

use-media-recorder

Headless React hooks for the MediaStream Recording API for audio, video, and screen recording.

Features

  • Simple API, minimal abstraction, no loss of configurability.
  • Muting/unmuting of audio streams
  • By default, auto-acquireß and auto-releases MediaStreams for ease-of-use
  • Permits manual acquiring/releasing MediaStreams to reduce start/stop latency
  • Use custom MediaStreams as input.
  • Headless

Installation

  • bun add @nolanholden/use-media-recorder
  • pnpm add @nolanholden/use-media-recorder
  • npm install @nolanholden/use-media-recorder
  • yarn add @nolanholden/use-media-recorder

Example

export default function Page() {
  const [audioURL, setAudioURL] = useState("");
  const [transcription, setTranscription] = useState("");

  const {
    browserSupportError,
    error,
    // <idle|acquiring_media|ready|recording|paused|stopping|stopped|failed>
    status,
    isAudioMuted,
    startRecording,
    pauseRecording,
    resumeRecording,
    stopRecording,
    mediaBlob,
    clearMediaBlob,
    muteAudio,
    unmuteAudio,
    liveStream,

    // internals:
    activeMediaRecorder,
    acquireMediaStream,
    releaseMediaStream,
  } = useMediaRecorder({
    mediaStreamConstraints: {
      audio: true,
      video: false,
    },
    onStop: (audioBlob) => {
      if (!audioBlob) throw new Error("No audio to transcribe.");
      const blob = audioBlob;

      async function stop() {
        setAudioURL(URL.createObjectURL(blob));

        const formData = new FormData();
        formData.append("audio", blob, "my-audio-file");

        const res = await fetch("/api/transcribe", {
          method: "POST",
          body: formData,
        });
        if (!res.ok)
          throw new Error(`Error transcribing the audio: ${res.statusText}`);
        const data = (await res.json()) as unknown as {
          dictation_text: string;
        };
        if (typeof data.dictation_text !== "string")
          throw new Error(`Error parsing response: ${JSON.stringify(data)}`);
        return data.dictation_text;
      }

      stop()
        .then((text) => {
          setTranscription(text);
          copyToClipboard(text);
        })
        .catch((err: Error) => {
          console.error(err);
          alert("Error transcribing audio: " + err.message);
        });
    },
  });

  useEffect(() => {
    if (browserSupportError) {
      console.error(browserSupportError);
      alert(browserSupportError);
    }
  }, [browserSupportError]);


  const isRecording = status === "recording";

  const toggleRecording = () => {
    if (isRecording) {
      stopRecording();
    } else {
      startRecording().catch((err) => {
        console.error(err);
      });
    }
  };

  return (
    <div className="flex flex-col items-center justify-center gap-4">
      <button
        disabled={!!error}
        onClick={toggleRecording}
        className="rounded-lg bg-blue-500 px-6 py-3 font-bold text-white hover:bg-blue-700"
      >
        {isRecording ? "Stop Recording" : "Start Recording"}
      </button>

      <p>{audioURL || "(blob url)"}</p>

      {audioURL && (
        <div className="flex justify-center">
        <audio src={audioURL} controls />
        </div>
      )}

      {transcription && (
        <div className="mt-3 flex flex-col items-center justify-center gap-2 pt-2">
          <p className="text-lg font-bold">Transcription:</p>
      
          <p className="pb-1 text-center text-sm text-slate-400">
            <em>(copied to clipboard)</em>
          </p>
      
          <div className="border-slate/20 w-full rounded-[8px] border p-2 text-sm">
            <p>{transcription}</p>
          </div>
        </div>
      )}
    </div>
  )
}

Keywords

FAQs

Last updated on 02 Oct 2023

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc