Advertisement
metalni

Untitled

Feb 2nd, 2024
1,017
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { useCallback, useRef, useState } from 'react'
  2.  
  3. // TODO: Move this to a utils file
  4. export const MAX_RECORDING_TIME = 120000
  5.  
  6. export const useRecordAudio = () => {
  7.   const [audioUrl, setAudioUrl] = useState<string | null>(null)
  8.   const [audioFile, setAudioFile] = useState<File | null>(null)
  9.   const mediaRecorder = useRef<MediaRecorder | null>(null)
  10.   const [isRecording, setIsRecording] = useState(false)
  11.   const [duration, setDuration] = useState(0)
  12.   const tickInterval = useRef<NodeJS.Timer | null>(null)
  13.   const timeout = useRef<NodeJS.Timeout | null>(null)
  14.  
  15.   const checkForPermissionsAndCreateStream = useCallback(async () => {
  16.     if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
  17.       try {
  18.         const stream = await navigator.mediaDevices.getUserMedia({
  19.           audio: true,
  20.         })
  21.  
  22.         mediaRecorder.current = new MediaRecorder(stream)
  23.  
  24.         let audioChunks: Blob[] = []
  25.  
  26.         mediaRecorder.current.ondataavailable = (event) => {
  27.           audioChunks.push(event.data)
  28.         }
  29.  
  30.         mediaRecorder.current.onstop = () => {
  31.           const audioBlob = new Blob(audioChunks, {
  32.             type: 'audio/mp3',
  33.           })
  34.  
  35.           const audioUrlFromRecording = URL.createObjectURL(audioBlob)
  36.           const audioFileFromRecording = new File(
  37.             [audioBlob],
  38.             `recording-${new Date().toLocaleDateString()}.mp3`,
  39.           )
  40.           setAudioUrl(audioUrlFromRecording)
  41.           setAudioFile(audioFileFromRecording)
  42.  
  43.           // Reset audio chunks
  44.           audioChunks = []
  45.  
  46.           if (tickInterval.current) {
  47.             clearInterval(tickInterval.current)
  48.           }
  49.  
  50.           setIsRecording(false)
  51.           stream.getAudioTracks().forEach((track) => track.stop())
  52.         }
  53.       } catch (err) {
  54.         return null
  55.       }
  56.     }
  57.  
  58.     return null
  59.   }, [])
  60.  
  61.   const stopRecording = useCallback(() => {
  62.     if (mediaRecorder.current) {
  63.       if (timeout.current) {
  64.         clearTimeout(timeout.current)
  65.       }
  66.  
  67.       mediaRecorder.current.stop()
  68.     }
  69.   }, [])
  70.  
  71.   const startRecording = useCallback(async () => {
  72.     await checkForPermissionsAndCreateStream()
  73.     if (mediaRecorder.current) {
  74.       mediaRecorder.current.start()
  75.       tickInterval.current = setInterval(() => {
  76.         setDuration((prev) => prev + 1)
  77.       }, 1000)
  78.  
  79.       setIsRecording(true)
  80.  
  81.       timeout.current = setTimeout(() => {
  82.         stopRecording()
  83.       }, MAX_RECORDING_TIME)
  84.     }
  85.   }, [checkForPermissionsAndCreateStream, stopRecording])
  86.  
  87.   return {
  88.     audioUrl,
  89.     audioFile,
  90.     duration,
  91.     isRecording,
  92.     startRecording,
  93.     stopRecording,
  94.     setDuration,
  95.   }
  96. }
  97.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement