Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
chamilo-lms/assets/vue/components/AudioRecorder.vue

108 lines
2.7 KiB

<template>
<div v-if="isMicrophoneSupported">
<BaseButton v-if="recorderState.isRecording" :label="t('Stop recording')" icon="stop" type="danger" @click="stop"/>
<BaseButton v-else :label="t('Start recording')" icon="microphone" type="primary" @click="record"/>
<div v-for="(audio, index) in recorderState.audioList" :key="index" class="py-2">
<audio class="max-w-full" controls>
<source :src="window.URL.createObjectURL(audio)"/>
</audio>
<BaseButton
:label="$t('Attach')"
class="my-1"
icon="attachment"
size="small"
type="success"
@click="attachAudio(audio)"
/>
</div>
</div>
<div v-else>
<p>
{{ t('We\'re sorry, your browser does not support using a microphone') }}
</p>
</div>
</template>
<script setup>
import BaseButton from "./basecomponents/BaseButton.vue";
import { computed, reactive } from "vue";
import { RecordRTCPromisesHandler, StereoAudioRecorder } from "recordrtc";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const props = defineProps({
multiple: {
type: Boolean,
required: false,
default: true,
},
});
const emit = defineEmits(["attach-audio"]);
const recorderState = reactive({
isRecording: false,
audioList: [],
});
const isMicrophoneSupported = computed(() => {
let isMediaDevicesSupported = navigator.mediaDevices && navigator.mediaDevices.getUserMedia
if (!isMediaDevicesSupported) {
console.warn('Either your browser does not support microphone or your are serving your site from not secure ' +
'context, check https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia for more information')
}
return isMediaDevicesSupported
})
let recorder = null;
async function record() {
if (!isMicrophoneSupported.value) {
return;
}
let stream = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
recorder = new RecordRTCPromisesHandler(stream, {
recorderType: StereoAudioRecorder,
type: "audio",
mimeType: "audio/wav",
numberOfAudioChannels: 2,
});
recorder.startRecording();
recorderState.isRecording = true;
}
async function stop() {
if (!recorder) {
return;
}
if (false === props.multiple && recorderState.audioList.length > 0) {
recorderState.audioList.shift();
}
await recorder.stopRecording();
const audioBlob = await recorder.getBlob();
recorderState.audioList.push(audioBlob);
recorderState.isRecording = false;
}
function attachAudio(audio) {
emit("attach-audio", audio);
const index = recorderState.audioList.indexOf(audio);
if (index >= 0) {
recorderState.audioList.splice(index, 1);
}
}
</script>