UNPKG

react-voice-decorator

Version:

react voice recorder component using navigator's mediaDevices and MediaRecorder api that provides record/play/pause functionalities for developers using render-props design pattern

93 lines (89 loc) 2.44 kB
import React, { useState, useEffect, useCallback } from 'react'; import PropTypes from 'prop-types'; import useInterval from '@use-it/interval'; import audioRecorder from '../libs/recorder'; function VoiceDecorator({ render, timeout, voiceGetter }) { const [recorder, setRecorder] = useState(null); const [isRecording, setIsRecording] = useState(false); const [recorded, setRecorded] = useState(null); const [isPlaying, setIsPlaying] = useState(false); const [voiceCounter, setVoiceCounter] = useState(null); useEffect(() => { return () => { setVoiceCounter(null); }; }, []); useEffect(() => { voiceGetter(() => ({ audio: recorded?.audio, blob: recorded?.dataBlob })); }, [recorded]); const stopRecord = useCallback(async () => { try { setIsRecording(false); const res = await recorder.stop(); setRecorded(res); } catch (_) {// nth } }, [recorder]); const startRecord = useCallback(async () => { if (isRecording) return; try { const rec = await audioRecorder(); setRecorder(rec); setIsRecording(true); rec.start(); const timeoutId = setTimeout(() => { stopRecord(); clearTimeout(timeoutId); }, timeout); } catch (_) { console.error('Cannot record in your device'); } }, [isRecording, timeout, stopRecord]); const stopPlay = useCallback(() => { setIsPlaying(false); setVoiceCounter(null); recorded.pause(); }, [recorded]); const startPlay = useCallback(() => { if (!recorded) { console.error('There is not any recorded voice to play'); return; } setIsPlaying(true); setVoiceCounter(1000); recorded.play(); }, [recorded]); useInterval(() => { try { if (recorded && recorded.isPaused()) { setVoiceCounter(null); setIsPlaying(false); } } catch (_) {// nth } }, voiceCounter); const props = { toggleRecord: () => isRecording ? stopRecord() : startRecord(), togglePlay: () => isPlaying ? stopPlay() : startPlay(), isPlaying, isRecording }; return /*#__PURE__*/React.createElement(React.Fragment, null, render(props)); } VoiceDecorator.propTypes = { render: PropTypes.func.isRequired, timeout: PropTypes.number, voiceGetter: PropTypes.func }; VoiceDecorator.defaultProps = { timeout: 120000, voiceGetter: () => {} }; export default VoiceDecorator;