mirror of
https://github.com/mgerb/go-discord-bot
synced 2026-01-11 01:22:48 +00:00
fix(sounds): fixed bug playing multiple sounds at the same time
This commit is contained in:
@@ -45,7 +45,6 @@ type AudioConnection struct {
|
|||||||
VoiceClipQueue chan *discordgo.Packet `json:"-"`
|
VoiceClipQueue chan *discordgo.Packet `json:"-"`
|
||||||
SoundPlayingLock bool `json:"-"`
|
SoundPlayingLock bool `json:"-"`
|
||||||
AudioListenerLock bool `json:"-"`
|
AudioListenerLock bool `json:"-"`
|
||||||
Disconnect chan bool `json:"_"`
|
|
||||||
Mutex *sync.Mutex `json:"-"` // mutex for single audio connection
|
Mutex *sync.Mutex `json:"-"` // mutex for single audio connection
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +70,7 @@ func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||||||
|
|
||||||
// Find the guild for that channel.
|
// Find the guild for that channel.
|
||||||
newGuild, err := s.State.Guild(c.GuildID)
|
newGuild, err := s.State.Guild(c.GuildID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
return
|
return
|
||||||
@@ -84,12 +84,10 @@ func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||||||
SoundQueue: make(chan string, maxSoundQueue),
|
SoundQueue: make(chan string, maxSoundQueue),
|
||||||
Mutex: &sync.Mutex{},
|
Mutex: &sync.Mutex{},
|
||||||
AudioListenerLock: false,
|
AudioListenerLock: false,
|
||||||
Disconnect: make(chan bool),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start new go routine handling the message
|
activeConnections[c.GuildID].handleMessage(m)
|
||||||
go activeConnections[c.GuildID].handleMessage(m)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conn *AudioConnection) handleMessage(m *discordgo.MessageCreate) {
|
func (conn *AudioConnection) handleMessage(m *discordgo.MessageCreate) {
|
||||||
@@ -119,7 +117,6 @@ func (conn *AudioConnection) handleMessage(m *discordgo.MessageCreate) {
|
|||||||
// dismiss bot from currnet channel if it's in one
|
// dismiss bot from currnet channel if it's in one
|
||||||
func (conn *AudioConnection) dismiss() {
|
func (conn *AudioConnection) dismiss() {
|
||||||
if conn.VoiceConnection != nil && !conn.SoundPlayingLock && len(conn.SoundQueue) == 0 {
|
if conn.VoiceConnection != nil && !conn.SoundPlayingLock && len(conn.SoundQueue) == 0 {
|
||||||
conn.Disconnect <- true
|
|
||||||
conn.VoiceConnection.Disconnect()
|
conn.VoiceConnection.Disconnect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,11 +158,6 @@ func (conn *AudioConnection) summon(m *discordgo.MessageCreate) {
|
|||||||
// set the current channel
|
// set the current channel
|
||||||
conn.CurrentChannel = c
|
conn.CurrentChannel = c
|
||||||
|
|
||||||
go conn.watchForDisconnect()
|
|
||||||
|
|
||||||
// start go routine that plays sounds
|
|
||||||
go conn.playSounds()
|
|
||||||
|
|
||||||
// start listening to audio if not locked
|
// start listening to audio if not locked
|
||||||
if !conn.AudioListenerLock {
|
if !conn.AudioListenerLock {
|
||||||
go conn.startAudioListener()
|
go conn.startAudioListener()
|
||||||
@@ -176,17 +168,6 @@ func (conn *AudioConnection) summon(m *discordgo.MessageCreate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update disconnect channel when voice connection becomes unready
|
|
||||||
func (conn *AudioConnection) watchForDisconnect() {
|
|
||||||
for {
|
|
||||||
if !conn.VoiceConnection.Ready {
|
|
||||||
conn.Disconnect <- true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// play audio in channel that user is in
|
// play audio in channel that user is in
|
||||||
func (conn *AudioConnection) playAudio(soundName string, m *discordgo.MessageCreate) {
|
func (conn *AudioConnection) playAudio(soundName string, m *discordgo.MessageCreate) {
|
||||||
|
|
||||||
@@ -209,9 +190,53 @@ func (conn *AudioConnection) playAudio(soundName string, m *discordgo.MessageCre
|
|||||||
case conn.SoundQueue <- soundName:
|
case conn.SoundQueue <- soundName:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start playing sounds in queue if not already playing
|
||||||
|
if !conn.SoundPlayingLock {
|
||||||
|
conn.playSoundsInQueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// playSoundsInQueue - play sounds until audio queue is empty
|
||||||
|
func (conn *AudioConnection) playSoundsInQueue() {
|
||||||
|
conn.toggleSoundPlayingLock(true)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case newSoundName := <-conn.SoundQueue:
|
||||||
|
|
||||||
|
if !conn.VoiceConnection.Ready {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start speaking.
|
||||||
|
_ = conn.VoiceConnection.Speaking(true)
|
||||||
|
|
||||||
|
// Send the buffer data.
|
||||||
|
for _, buff := range conn.Sounds[newSoundName].Content {
|
||||||
|
conn.VoiceConnection.OpusSend <- buff
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop speaking
|
||||||
|
_ = conn.VoiceConnection.Speaking(false)
|
||||||
|
|
||||||
|
// Sleep for a specificed amount of time before ending.
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
|
default:
|
||||||
|
conn.toggleSoundPlayingLock(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conn *AudioConnection) toggleSoundPlayingLock(playing bool) {
|
||||||
|
conn.Mutex.Lock()
|
||||||
|
conn.SoundPlayingLock = playing
|
||||||
|
conn.Mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// load audio file into memory
|
// load audio file into memory
|
||||||
@@ -386,51 +411,14 @@ loop:
|
|||||||
conn.VoiceClipQueue <- opusChannel
|
conn.VoiceClipQueue <- opusChannel
|
||||||
|
|
||||||
// check if voice connection fails then break out of audio listener
|
// check if voice connection fails then break out of audio listener
|
||||||
case <-conn.Disconnect:
|
default:
|
||||||
break loop
|
if !conn.VoiceConnection.Ready {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second * 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove lock upon exit
|
// remove lock upon exit
|
||||||
conn.AudioListenerLock = false
|
conn.AudioListenerLock = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// playSounds - plays the current buffer to the provided channel.
|
|
||||||
func (conn *AudioConnection) playSounds() (err error) {
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case newSoundName := <-conn.SoundQueue:
|
|
||||||
conn.toggleSoundPlayingLock(true)
|
|
||||||
|
|
||||||
if !conn.VoiceConnection.Ready {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start speaking.
|
|
||||||
_ = conn.VoiceConnection.Speaking(true)
|
|
||||||
|
|
||||||
// Send the buffer data.
|
|
||||||
for _, buff := range conn.Sounds[newSoundName].Content {
|
|
||||||
conn.VoiceConnection.OpusSend <- buff
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop speaking
|
|
||||||
_ = conn.VoiceConnection.Speaking(false)
|
|
||||||
|
|
||||||
// Sleep for a specificed amount of time before ending.
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
|
|
||||||
conn.toggleSoundPlayingLock(false)
|
|
||||||
|
|
||||||
case <-conn.Disconnect:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (conn *AudioConnection) toggleSoundPlayingLock(playing bool) {
|
|
||||||
conn.Mutex.Lock()
|
|
||||||
conn.SoundPlayingLock = playing
|
|
||||||
conn.Mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user