Skip to content

Commit

Permalink
Resolves #536 microPhone audio visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
saltykheera committed Oct 6, 2024
1 parent 183c7ff commit f52b703
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/components/atoms/AudioRecorder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export default {
props: {
testId: String,
taskIndex: Number,
showVisualizer:{
type:Boolean,
default:false,
},
},
data() {
return {
Expand All @@ -64,6 +68,7 @@ export default {
async startAudioRecording() {
this.recordingAudio = true
this.$emit('recordingStarted',true)
try {
this.audioStream = await navigator.mediaDevices.getUserMedia({
audio: true,
Expand Down Expand Up @@ -110,6 +115,7 @@ export default {
this.audioStream.getTracks().forEach((track) => track.stop())
this.audioStream = null
this.recordingAudio = false
this.$emit('recordingStarted',false)
this.$emit('stopShowLoading')
this.$toast.success('Audio record saved!')
Expand Down
80 changes: 80 additions & 0 deletions src/components/atoms/AudioVisualizer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template>
<v-container>
<v-row >
<v-col >
<div>
<div>
<v-row no-gutters>
<v-col v-for="index in 5" :key="index" cols="auto" class="mx-1">
<v-sheet
:color="index <= activeBars ? 'green' : 'grey lighten-1'"
height="21"
width="8"
rounded="pill"
></v-sheet>
</v-col>
</v-row>
</div>
</div>
</v-col>
</v-row>
</v-container>
</template>

<script>
export default {
data() {
return {
audioContext: null,
analyser: null,
dataArray: null,
activeBars: 0,
animationId: null,
}
},
mounted() {
this.initAudio()
},
beforeDestroy() {
this.cleanup()
},
methods: {
async initAudio() {
const AudioContext = window.AudioContext || window.webkitAudioContext
this.audioContext = new AudioContext()
this.analyser = this.audioContext.createAnalyser()
this.analyser.fftSize = 32
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
})
const source = this.audioContext.createMediaStreamSource(stream)
source.connect(this.analyser)
this.dataArray = new Uint8Array(this.analyser.frequencyBinCount)
this.animate()
} catch (error) {
console.error('Error accessing the microphone', error)
}
},
animate() {
this.analyser.getByteFrequencyData(this.dataArray)
const sum = this.dataArray.reduce((a, b) => a + b, 0)
const average = sum / this.dataArray.length
this.activeBars = Math.min(Math.floor(average / 20), 15) // Adjust sensitivity here
this.animationId = requestAnimationFrame(this.animate)
},
cleanup() {
if (this.audioContext) {
this.audioContext.close()
}
if (this.animationId) {
cancelAnimationFrame(this.animationId)
}
},
},
}
</script>

11 changes: 11 additions & 0 deletions src/views/public/UserTestView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,7 @@
:task="test.testStructure.userTasks[taskIndex]"
/>
</v-col>

<v-col
cols="1"
v-if="
Expand All @@ -583,10 +584,15 @@
<AudioRecorder
@showLoading="isLoading = true"
@stopShowLoading="isLoading = false"
@recordingStarted="isVisualizerVisible = $event"
:testId="testId"
:taskIndex="taskIndex"
></AudioRecorder>
</v-col>

<v-col cols="1" v-if="isVisualizerVisible" >
<AudioVisualizer/>
</v-col>
<v-col
cols="1"
v-if="
Expand Down Expand Up @@ -837,9 +843,11 @@ import Snackbar from '@/components/atoms/Snackbar'
import TipButton from '@/components/atoms/TipButton'
import Timer from '@/components/atoms/Timer'
import AudioRecorder from '@/components/atoms/AudioRecorder'
import AudioVisualizer from '@/components/atoms/AudioVisualizer'
import VideoRecorder from '@/components/atoms/VideoRecorder.vue'
import ScreenRecorder from '@/components/atoms/ScreenRecorder.vue'
export default {
components: {
VideoRecorder,
Expand All @@ -849,7 +857,9 @@ export default {
TipButton,
Timer,
AudioRecorder,
AudioVisualizer,
ScreenRecorder,
},
data: () => ({
videoUrl: '',
Expand All @@ -868,6 +878,7 @@ export default {
dialog: false,
allTasksCompleted: false,
isLoading: false,
isVisualizerVisible:false,
}),
computed: {
test() {
Expand Down

0 comments on commit f52b703

Please sign in to comment.