Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { useCallback, useRef, useState } from 'react'
- // TODO: Move this to a utils file
- export const MAX_RECORDING_TIME = 120000
- export const useRecordAudio = () => {
- const [audioUrl, setAudioUrl] = useState<string | null>(null)
- const [audioFile, setAudioFile] = useState<File | null>(null)
- const mediaRecorder = useRef<MediaRecorder | null>(null)
- const [isRecording, setIsRecording] = useState(false)
- const [duration, setDuration] = useState(0)
- const tickInterval = useRef<NodeJS.Timer | null>(null)
- const timeout = useRef<NodeJS.Timeout | null>(null)
- const checkForPermissionsAndCreateStream = useCallback(async () => {
- if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
- try {
- const stream = await navigator.mediaDevices.getUserMedia({
- audio: true,
- })
- mediaRecorder.current = new MediaRecorder(stream)
- let audioChunks: Blob[] = []
- mediaRecorder.current.ondataavailable = (event) => {
- audioChunks.push(event.data)
- }
- mediaRecorder.current.onstop = () => {
- const audioBlob = new Blob(audioChunks, {
- type: 'audio/mp3',
- })
- const audioUrlFromRecording = URL.createObjectURL(audioBlob)
- const audioFileFromRecording = new File(
- [audioBlob],
- `recording-${new Date().toLocaleDateString()}.mp3`,
- )
- setAudioUrl(audioUrlFromRecording)
- setAudioFile(audioFileFromRecording)
- // Reset audio chunks
- audioChunks = []
- if (tickInterval.current) {
- clearInterval(tickInterval.current)
- }
- setIsRecording(false)
- stream.getAudioTracks().forEach((track) => track.stop())
- }
- } catch (err) {
- return null
- }
- }
- return null
- }, [])
- const stopRecording = useCallback(() => {
- if (mediaRecorder.current) {
- if (timeout.current) {
- clearTimeout(timeout.current)
- }
- mediaRecorder.current.stop()
- }
- }, [])
- const startRecording = useCallback(async () => {
- await checkForPermissionsAndCreateStream()
- if (mediaRecorder.current) {
- mediaRecorder.current.start()
- tickInterval.current = setInterval(() => {
- setDuration((prev) => prev + 1)
- }, 1000)
- setIsRecording(true)
- timeout.current = setTimeout(() => {
- stopRecording()
- }, MAX_RECORDING_TIME)
- }
- }, [checkForPermissionsAndCreateStream, stopRecording])
- return {
- audioUrl,
- audioFile,
- duration,
- isRecording,
- startRecording,
- stopRecording,
- setDuration,
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement