const AudioContext = window.AudioContext || window.webkitAudioContext
const audioCtx = new AudioContext()
const sourceNode = audioCtx.createMediaStreamSource(stream)
const gainNode = audioCtx.createGain()
const finishNode = audioCtx.destination
sourceNode.connect(gainNode);
gainNode.connect(finishNode)
const AudioContext = window.AudioContext || window.webkitAudioContext
const audioCtx = new AudioContext()
const sourceNode = audioCtx.createMediaStreamSource(stream)
const gainNode = audioCtx.createGain()
const finishNode = audioCtx.destination
sourceNode.connect(gainNode);
gainNode.connect(finishNode)
<input type="file" accept="audio/*;capture=microphone">
<device type="media" onchange="update(this.data)"></device>
<audio></auidio>
<script>
function update(stream) {
document.querySelector('audio').src = stream.url;
}
</script>
async getMedia = () => {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
successCallback(stream)
} catch (err) {
handleError(err)
}
}
async getDevices = () => {
try {
const devices = await navigator.mediaDevices.enumerateDevices()
devices.map(device => { const { label, kind, deviceInfo) = device } // kind === 'audioinput'
} catch (err) {
handleError(err)
}
}
}
MediaStream
ondataavailable
Blob
MediaRecorder
export default {
name: 'MediaRecorderComponent',
data () {
return {
mediaRecorder: null
isAudioAccessReceived: false,
isRecording: false,
chunks: [],
audio: this.$refs.audio
}
},
methods: {
toggleRecord () {
if (!this.isAudioAccessReceived) {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
this.mediaRecorder = new window.MediaRecorder(stream, { type: 'audio/ogg' })
this.mediaRecorder.ondataavailable = () => this.chunks.push(event.data)
mediaRecorder.onstop = (e) => {
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
this.chunks = [];
const audioURL = window.URL.createObjectURL(blob);
audio.src = audioURL;
}
this.isAudioAccessReceived = true
} catch (e) { /* handle error */ }
}
if (!this.isRecording) {
this.mediaRecorder.start()
} else {
this.mediaRecorder.stop()
}
this.isRecording = !this.isRecording
}
}
}
export default {
name: 'MediaRecorderComponent',
data () {
return {
mediaRecorder: null
isAudioAccessReceived: false,
isRecording: false,
chunks: [],
audio: this.$refs.audio
}
},
methods: {
toggleRecord () {
if (!this.isAudioAccessReceived) {
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
this.mediaRecorder = new window.MediaRecorder(stream, { type: 'audio/ogg' })
this.mediaRecorder.ondataavailable = () => this.chunks.push(event.data)
mediaRecorder.onstop = (e) => {
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
this.chunks = [];
const audioURL = window.URL.createObjectURL(blob);
audio.src = audioURL;
}
this.isAudioAccessReceived = true
} catch (e) { /* handle error */ }
}
if (!this.isRecording) {
this.mediaRecorder.start()
} else {
this.mediaRecorder.stop()
}
this.isRecording = !this.isRecording
}
}
}
export default async ({ app, Vue, store }) => {
if (!navigator.mediaDevices) navigator.mediaDevices = {}
if (!navigator.mediaDevices.getUserMedia) {
var getUserMedia = (
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia ||
navigator.getUserMedia
)
if (getUserMedia) {
navigator.mediaDevices.getUserMedia = function (constraints) {
return new Promise(function (resolve, reject) {
getUserMedia(constraints,
function (stream) { resolve(stream) },
function (error) { reject(error) }
)
})
}
} else {
navigator.mediaDevices.getUserMedia = function () {
return new Promise(function (resolve, reject) {
reject('getUserMedia is not supported in this browser.')
})
}
}
}
}
export default {
name: 'AudioRecorder',
data () { return { recorder: null, audioContext: null } },
created () { this.audioContext = new this.AudioContextClass() },
beforeDestroy () { this.audioContext = null },
methods: {
toggleRecord () {
if (this.isRecording) {
this.isRecording = false
setTimeout(() => {
this.recorder.stop()
this.stream.getAudioTracks()[0].stop()
this.recorder.exportWAV(finalUserData => { successCallback(finalUserData) })
}, 700)
} else {
navigator.mediaDevices.getUserMedia({
audio: true
})
.then((stream) => {
this.recorder = new window.Recorder(
this.audioContext.createMediaStreamSource(stream), {
numChannels: 1, type: 'audio/wav'
}
)
this.recorder.record()
this.isRecording = true
})
.catch(err => {
console.error('The following getUserMedia error occured: ' + err)
})
}
},
}
}
let webAudioRecorder = new WebAudioRecorder(source, {
workerDir: 'web_audio_recorder_js/',
encoding: 'mp3',
options: {
encodeAfterRecord: true,
mp3: { bitRate: '320' }
}
});
webAudioRecorder.onComplete = (webAudioRecorder, blob) => {
/* on complete handler */
}
webAudioRecorder.onError = (webAudioRecorder, err) => {
/* on error handler */
}
webAudioRecorder.startRecording();
webAudioRecorder.finishRecording();
const mediaConstraints = {
audio: true
}
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError)
function onMediaSuccess(stream) {
/* media success handler */
}
function onMediaError(e) {
console.error('media error', e)
}
mediaRecorder.stop()
mediaRecorder.start()
mediaRecorder.save()
let stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
let recorder = new RecordRTCPromisesHandler(stream, {
type: 'video'
});
recorder.startRecording();
const sleep = m => new Promise(r => setTimeout(r, m));
await sleep(3000);
await recorder.stopRecording();
let blob = await recorder.getBlob();
invokeSaveAsDialog(blob);
window.MediaRecorder = require('audio-recorder-polyfill')
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
recorder = new MediaRecorder(stream)
recorder.addEventListener('dataavailable', e => {
audio.src = URL.createObjectURL(e.data)
})
recorder.start()
})
/* boot/audioRecorder.js */
import AudioRecorder from 'vue-audio-recorder'
export default ({ Vue }) => {
Vue.use(AudioRecorder)
}
/* MyVueAudioRecorder.vue */
<template>
<audio-recorder
upload-url="some url"
:attempts="3"
:time="2"
:before-recording="callback"
:after-recording="callback"
:before-upload="callback"
:successful-upload="callback"
:failed-upload="callback"></audio-recorder>
</template>
<script>
export default {
name: 'MyVueAudioRecorder',
methods: {
callback (msg) {
console.debug('Event: ', msg)
}
}
}
</script>