mirror of
https://github.com/kevin-DL/vue-audio-recorder.git
synced 2026-01-15 20:44:43 +00:00
113 lines
2.6 KiB
JavaScript
113 lines
2.6 KiB
JavaScript
import WavEncoder from './wav-encoder'
|
|
import { convertTimeMMSS } from './utils'
|
|
|
|
export default class {
|
|
constructor (options = {}) {
|
|
this.afterStop = options.afterStop
|
|
this.micFailed = options.micFailed
|
|
|
|
this.bufferSize = 4096
|
|
this.records = []
|
|
this.samples = []
|
|
|
|
this.isPause = false
|
|
this.isRecording = false
|
|
|
|
this.duration = 0
|
|
this.volume = 0
|
|
|
|
this._duration = 0
|
|
}
|
|
|
|
start () {
|
|
navigator.mediaDevices.getUserMedia({audio: true})
|
|
.then(this._micCaptured.bind(this))
|
|
.catch(this._micError.bind(this))
|
|
this.isPause = false
|
|
this.isRecording = true
|
|
}
|
|
|
|
stop () {
|
|
this.stream.getTracks().forEach((track) => track.stop())
|
|
this.input.disconnect()
|
|
this.processor.disconnect()
|
|
this.context.close()
|
|
|
|
let encoder = new WavEncoder({
|
|
bufferSize : this.bufferSize,
|
|
sampleRate : this.context.sampleRate,
|
|
samples : this.samples
|
|
})
|
|
|
|
let audioBlob = encoder.getData()
|
|
let audioUrl = URL.createObjectURL(audioBlob)
|
|
|
|
this.samples = []
|
|
|
|
this.records.push({
|
|
id : Date.now(),
|
|
blob : audioBlob,
|
|
duration : convertTimeMMSS(this.duration),
|
|
url : audioUrl
|
|
})
|
|
|
|
this._duration = 0
|
|
this.duration = 0
|
|
|
|
this.isPause = false
|
|
this.isRecording = false
|
|
|
|
if (this.afterStop) {
|
|
this.afterStop()
|
|
}
|
|
}
|
|
|
|
pause () {
|
|
this.stream.getTracks().forEach((track) => track.stop())
|
|
this.input.disconnect()
|
|
this.processor.disconnect()
|
|
this.context.close()
|
|
|
|
this._duration = this.duration
|
|
this.isPause = true
|
|
}
|
|
|
|
recordList () {
|
|
return this.records
|
|
}
|
|
|
|
lastRecord () {
|
|
return this.records.slice(-1)
|
|
}
|
|
|
|
_micCaptured (stream) {
|
|
this.context = new(window.AudioContext || window.webkitAudioContext)()
|
|
this.duration = this._duration
|
|
this.input = this.context.createMediaStreamSource(stream)
|
|
this.processor = this.context.createScriptProcessor(this.bufferSize, 1, 1)
|
|
this.stream = stream
|
|
|
|
this.processor.onaudioprocess = (ev) => {
|
|
let sample = ev.inputBuffer.getChannelData(0)
|
|
let sum = 0.0
|
|
|
|
for (let i = 0; i < sample.length; ++i) {
|
|
sum += sample[i] * sample[i]
|
|
}
|
|
|
|
this.duration = parseFloat(this._duration) + parseFloat(this.context.currentTime.toFixed(2))
|
|
this.volume = Math.sqrt(sum / sample.length).toFixed(2)
|
|
this.samples.push(new Float32Array(sample))
|
|
}
|
|
|
|
this.input.connect(this.processor)
|
|
this.processor.connect(this.context.destination)
|
|
}
|
|
|
|
_micError (error) {
|
|
if (this.micFailed) {
|
|
this.micFailed(error)
|
|
}
|
|
}
|
|
}
|