mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-11-09 16:50:01 +00:00
[overlays] Add sounds
overlay as default
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
857835f7c5
commit
9ed76d64ae
2 changed files with 132 additions and 0 deletions
6
internal/apimodules/overlays/default/sounds.html
Normal file
6
internal/apimodules/overlays/default/sounds.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<html>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script src="https://cdn.jsdelivr.net/combine/npm/vue@2/dist/vue.js"></script>
|
||||||
|
<script src="sounds.js" type="module"></script>
|
||||||
|
</html>
|
||||||
|
|
126
internal/apimodules/overlays/default/sounds.js
Normal file
126
internal/apimodules/overlays/default/sounds.js
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/* global Vue */
|
||||||
|
|
||||||
|
import EventClient from './eventclient.mjs'
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
created() {
|
||||||
|
this.createAudioInterface()
|
||||||
|
|
||||||
|
new EventClient({
|
||||||
|
handlers: {
|
||||||
|
custom: (evt, data, time, live) => this.handleCustom(evt, data, time, live),
|
||||||
|
},
|
||||||
|
|
||||||
|
maxReplayAge: 720,
|
||||||
|
replay: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
data: {
|
||||||
|
alerts: [],
|
||||||
|
alertsEnabled: true,
|
||||||
|
sound: null,
|
||||||
|
soundsActive: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
el: '#app',
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
createAudioInterface() {
|
||||||
|
// Create basic audio element to play sound
|
||||||
|
this.sound = new Audio()
|
||||||
|
|
||||||
|
this.sound.addEventListener('load', () => this.sound.play(), true)
|
||||||
|
this.sound.addEventListener('playing', () => {
|
||||||
|
this.soundsActive = true
|
||||||
|
})
|
||||||
|
this.sound.addEventListener('pause', () => {
|
||||||
|
this.soundsActive = false
|
||||||
|
})
|
||||||
|
this.sound.autoplay = true
|
||||||
|
this.sound.crossOrigin = 'anonymous'
|
||||||
|
|
||||||
|
// Create limiter chain and connect audio element to it
|
||||||
|
const audioCtx = new AudioContext()
|
||||||
|
|
||||||
|
const preGainNode = audioCtx.createGain()
|
||||||
|
// preGainNode.gain.setValueAtTime(-0.5, audioCtx.currentTime) // Decibel
|
||||||
|
|
||||||
|
const masterGainNode = audioCtx.createGain()
|
||||||
|
masterGainNode.gain.setValueAtTime(-0.1, audioCtx.currentTime) // Decibel
|
||||||
|
|
||||||
|
const limiterNode = audioCtx.createDynamicsCompressor()
|
||||||
|
limiterNode.threshold.setValueAtTime(-30.0, audioCtx.currentTime) // Decibel
|
||||||
|
limiterNode.knee.setValueAtTime(0, audioCtx.currentTime) // Decibel
|
||||||
|
limiterNode.ratio.setValueAtTime(20.0, audioCtx.currentTime) // Decibel
|
||||||
|
limiterNode.attack.setValueAtTime(0, audioCtx.currentTime) // Seconds
|
||||||
|
limiterNode.release.setValueAtTime(0.1, audioCtx.currentTime) // Seconds
|
||||||
|
|
||||||
|
preGainNode.connect(limiterNode)
|
||||||
|
limiterNode.connect(masterGainNode)
|
||||||
|
masterGainNode.connect(audioCtx.destination)
|
||||||
|
|
||||||
|
const source = audioCtx.createMediaElementSource(this.sound)
|
||||||
|
source.connect(preGainNode)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleCustom(evt, data, time, live) {
|
||||||
|
switch (data.type) {
|
||||||
|
case 'soundalert':
|
||||||
|
if (!live) {
|
||||||
|
// Not a live event, do not issue alerts
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.queueAlert({
|
||||||
|
soundUrl: data.soundUrl,
|
||||||
|
})
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log(`Unhandled custom event ${data.type}`, data)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
playSound(soundUrl) {
|
||||||
|
this.soundsActive = true
|
||||||
|
this.sound.src = soundUrl
|
||||||
|
},
|
||||||
|
|
||||||
|
queueAlert(alertParams) {
|
||||||
|
this.alerts.push(alertParams)
|
||||||
|
},
|
||||||
|
|
||||||
|
triggerAlert() {
|
||||||
|
const alrt = this.alerts.shift()
|
||||||
|
if (!alrt) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.alertsEnabled) {
|
||||||
|
// Alerts are disabled completely or this one is blocked, discard alert
|
||||||
|
return this.triggerAlert()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alrt.soundUrl) {
|
||||||
|
this.playSound(alrt.soundUrl)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
name: 'SoundOverlay',
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
alerts(to) {
|
||||||
|
if (to.length > 0 && !this.alertsRunning) {
|
||||||
|
this.triggerAlert()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
soundsActive(to) {
|
||||||
|
if (!to) {
|
||||||
|
this.triggerAlert()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
Loading…
Reference in a new issue