Initial commit
This commit is contained in:
113
components/AudioReactiveBar.vue
Normal file
113
components/AudioReactiveBar.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<div class="progress" style="height: 10px; width: 100%;">
|
||||
<div
|
||||
class="progress-bar bar"
|
||||
role="progressbar"
|
||||
aria-label="Basic example"
|
||||
:style="{width:bar_width+'%'}"
|
||||
style="background-color: #e9c046;transition: 0.1s"
|
||||
aria-valuenow="75"
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="false">
|
||||
<h3>Debug Test</h3>
|
||||
<h4>Current Microphone: {{ microphoneLabel }}</h4>
|
||||
<h4>Current Steam ID: {{ deviceId }}</h4>
|
||||
<button @click="updateMicrophone">Change Microphone</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'pinia'
|
||||
import { useMicStore } from '@/stores/microphone'
|
||||
export default {
|
||||
components: {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
t: useI18n,
|
||||
// meter
|
||||
meter: null,
|
||||
bar_width: 0,
|
||||
analyser: null,
|
||||
dataArray: null,
|
||||
bar_val: 25,
|
||||
microphoneLabel: null,
|
||||
microAnalyse: null,
|
||||
deviceId: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useMicStore, 'microphone')
|
||||
},
|
||||
beforeUnmount () {
|
||||
if (this.audioContext) { this.audioContext.close() }
|
||||
this.audioContext = null
|
||||
useMicStore().detachMicrophone()
|
||||
},
|
||||
mounted () {
|
||||
// useNuxtApp().$logger.log('mounted ', this.microphone)
|
||||
useMicStore().getMicrophone().then((mic) => {
|
||||
// useNuxtApp().$logger.log('Microphone ready')
|
||||
const audioCtx = mic.microphoneNode.context
|
||||
useNuxtApp().$logger.log({ mic })
|
||||
this.microphoneLabel = mic.microphoneLabel
|
||||
this.deviceId = mic.deviceId || 'unknown'
|
||||
this.analyser = audioCtx.createAnalyser()
|
||||
mic.microphoneNode.connect(this.analyser)
|
||||
this.analyser.fftSize = 2048
|
||||
const bufferLength = this.analyser.frequencyBinCount
|
||||
this.dataArray = new Uint8Array(bufferLength)
|
||||
this.updateMeter()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
updateMeter () {
|
||||
requestAnimationFrame(this.updateMeter)
|
||||
this.analyser.getByteFrequencyData(this.dataArray)
|
||||
const rms = this.getRMS(this.dataArray)
|
||||
let level = 90 * Math.log10(rms / 128)
|
||||
level = Math.max(0, Math.min(100, level + 100))
|
||||
// bar.style.width = level + '%'
|
||||
this.bar_width = level
|
||||
},
|
||||
getRMS (dataArray) {
|
||||
let rms = 0
|
||||
for (let i = 0; i < dataArray.length; i++) {
|
||||
rms += dataArray[i] * dataArray[i]
|
||||
}
|
||||
rms /= dataArray.length
|
||||
rms = Math.sqrt(rms)
|
||||
return rms
|
||||
},
|
||||
async updateMicrophone () {
|
||||
if (!(this.deviceId instanceof String)) {
|
||||
let devices = useMicStore().availableDevices
|
||||
devices = devices.filter(x => x.label !== this.microphoneLabel)
|
||||
const newDevice = devices.pop()
|
||||
this.microphoneLabel = newDevice.label
|
||||
this.deviceId = newDevice.deviceId
|
||||
await useMicStore().switchMicrophone(this.deviceId)
|
||||
}
|
||||
try {
|
||||
const mic = useMicStore().microphone
|
||||
if (mic && mic.microphoneNode) {
|
||||
const audioCtx = mic.microphoneNode.context
|
||||
this.analyser = audioCtx.createAnalyser()
|
||||
mic.microphoneNode.connect(this.analyser)
|
||||
this.analyser.fftSize = 2048
|
||||
const bufferLength = this.analyser.frequencyBinCount
|
||||
this.dataArray = new Uint8Array(bufferLength)
|
||||
this.updateMeter()
|
||||
}
|
||||
} catch (error) {
|
||||
useNuxtApp().$logger.error('Error updating microphone in AudioReactiveBar:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
Reference in New Issue
Block a user