114 lines
3.4 KiB
Vue
114 lines
3.4 KiB
Vue
<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>
|