Skip to content

Instantly share code, notes, and snippets.

@vagnereix
Created February 11, 2024 01:53
Show Gist options
  • Save vagnereix/70c8f17c5de0ad563ab19cefd91f599c to your computer and use it in GitHub Desktop.
Save vagnereix/70c8f17c5de0ad563ab19cefd91f599c to your computer and use it in GitHub Desktop.
wavesurfer.js - recording audio using @wavesurfer/react
// React example
// See https://github.com/katspaugh/wavesurfer-react
import * as React from 'react'
const { useMemo, useState, useCallback, useRef } = React
import { createRoot } from 'react-dom/client'
import { useWavesurfer } from '@wavesurfer/react'
import RecordPlugin from 'wavesurfer.js/dist/plugins/record.esm.js'
const audioUrls = [
'/examples/audio/audio.wav',
'/examples/audio/stereo.mp3',
'/examples/audio/mono.mp3',
'/examples/audio/librivox.mp3',
]
const formatTime = (seconds) => [seconds / 60, seconds % 60].map((v) => `0${Math.floor(v)}`.slice(-2)).join(':')
// A React component that will render wavesurfer
const App = () => {
const containerRef = useRef(null)
const [urlIndex, setUrlIndex] = useState(0)
const [audioUrl, setAudioUrl] = useState('/examples/audio/librivox.mp3')
const { wavesurfer, isPlaying, currentTime, isRecording } = useWavesurfer({
container: containerRef,
height: 100,
waveColor: '#ddd',
progressColor: '#ff006c',
barWidth: 0,
barRadius: 0,
url: audioUrl,
plugins: useMemo(() => [], []),
})
const record = wavesurfer?.registerPlugin(RecordPlugin.create({ scrollingWaveform: false, renderRecordedAudio: false }))
record?.on('record-end', (blob) => {
const recordedUrl = URL.createObjectURL(blob)
console.log('recorded:', recordedUrl)
setAudioUrl(recordedUrl)
})
const onUrlChange = useCallback(() => {
setUrlIndex((index) => (index + 1) % audioUrls.length)
}, [])
const onPlayPause = useCallback(() => {
wavesurfer && wavesurfer.playPause()
}, [wavesurfer])
function startRecord() {
if (record.isRecording() || record.isPaused()) {
console.log('stop recording')
record.stopRecording()
return
}
const deviceId = RecordPlugin.getAvailableAudioDevices().then((devices) => {
return devices[0].deviceId
})
record.startRecording({ deviceId }).then(() => {
console.log('recording')
})
}
return (
<>
<div ref={containerRef} />
<p>Current audio: {audioUrls[urlIndex]}</p>
<p>Current time: {formatTime(currentTime)}</p>
<div style={{ margin: '1em 0', display: 'flex', gap: '1em' }}>
<button onClick={onUrlChange}>Change audio</button>
<button onClick={onPlayPause} style={{ minWidth: '5em' }}>
{isPlaying ? 'Pause' : 'Play'}
</button>
<button onClick={startRecord} style={{ minWidth: '5em' }}>
{isRecording ? 'Stop record' : 'Start record'}
</button>
</div>
</>
)
}
// Create a React root and render the app
const root = createRoot(document.body)
root.render(<App />)
/*
<html>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react",
"react/jsx-runtime": "https://esm.sh/react/jsx-runtime",
"react-dom/client": "https://esm.sh/react-dom/client",
"wavesurfer.js": "../dist/wavesurfer.esm.js",
"wavesurfer.js/dist": "../dist",
"@wavesurfer/react": "https://unpkg.com/@wavesurfer/react"
}
}
</script>
</html>
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment