Skip to content

Instantly share code, notes, and snippets.

@ShetlandJ
Last active May 20, 2022 13:32
Show Gist options
  • Save ShetlandJ/9a01601bc59790e23f976b8071c830ba to your computer and use it in GitHub Desktop.
Save ShetlandJ/9a01601bc59790e23f976b8071c830ba to your computer and use it in GitHub Desktop.
Vue 3 - record audio and listen back to it immediately in the browser
export const blobToBase64 = (blob) => {
const reader = new FileReader();
reader.readAsDataURL(blob);
return new Promise(resolve => {
reader.onloadend = () => {
resolve(reader.result);
};
});
};
export const convertDataURIToBinary = (dataURI) => {
const BASE64_MARKER = ';base64,';
const base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
const base64 = dataURI.substring(base64Index);
const raw = window.atob(base64);
const rawLength = raw.length;
const array = new Uint8Array(new ArrayBuffer(rawLength));
for (let i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
return array;
}
export const convertToBlogUri = async (blobject) => {
const dataURI = await blobToBase64(blobject);
const binary = convertDataURIToBinary(dataURI);
const blob = new Blob([binary], { type: 'audio/mp3' });
return URL.createObjectURL(blob);
}
// Here's a base implementation of recording audio and listening back to it instantly without having to save the file somewhere.
<script setup>
import { ref } from "vue";
import { convertToBlogUri } from "@/utils/helpers";
let device = null;
let recorder = null;
let chunks = [];
let recording = ref(false);
let blob = null;
let justRecorded = ref(null);
const recordAudio = () => {
recording.value = true;
justRecorded.value = null;
device = navigator.mediaDevices.getUserMedia({ audio: true })
device.then((stream) => {
recorder = new MediaRecorder(stream);
recorder.ondataavailable = async (e) => {
chunks.push(e.data);
if (recorder.state === "inactive") {
blob = new Blob(chunks, { type: "audio/wav" });
const file = await convertToBlogUri(blob);
justRecorded.value = file;
chunks.value = [];
}
};
recorder.start();
});
};
const stop = () => {
recording.value = false;
recorder.stop();
device = null;
};
</script>
<template>
<div>
<div class="flex justify-between" style="width: 50%">
<div>
{{recording ? "Recording" : "Not Recording"}}
</div>
<button @click="recordAudio" id="record">Record</button>
<button id="stop" @click="stop">Stop</button>
</div>
<div v-if="justRecorded">
Your recording:
<audio controls>
<source :src="justRecorded" type="audio/wav">
</audio>
</div>
</div>
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment