1
0
mirror of https://github.com/mgerb/go-discord-bot synced 2026-01-09 16:42:48 +00:00

fix(sounds): fixed bug playing multiple sounds at the same time

This commit is contained in:
2018-07-14 22:30:56 -05:00
parent ca2f7252eb
commit f6be25d4ef

View File

@@ -45,7 +45,6 @@ type AudioConnection struct {
VoiceClipQueue chan *discordgo.Packet `json:"-"`
SoundPlayingLock bool `json:"-"`
AudioListenerLock bool `json:"-"`
Disconnect chan bool `json:"_"`
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.
newGuild, err := s.State.Guild(c.GuildID)
if err != nil {
log.Error(err)
return
@@ -84,12 +84,10 @@ func SoundsHandler(s *discordgo.Session, m *discordgo.MessageCreate) {
SoundQueue: make(chan string, maxSoundQueue),
Mutex: &sync.Mutex{},
AudioListenerLock: false,
Disconnect: make(chan bool),
}
}
// start new go routine handling the message
go activeConnections[c.GuildID].handleMessage(m)
activeConnections[c.GuildID].handleMessage(m)
}
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
func (conn *AudioConnection) dismiss() {
if conn.VoiceConnection != nil && !conn.SoundPlayingLock && len(conn.SoundQueue) == 0 {
conn.Disconnect <- true
conn.VoiceConnection.Disconnect()
}
}
@@ -161,11 +158,6 @@ func (conn *AudioConnection) summon(m *discordgo.MessageCreate) {
// set the current channel
conn.CurrentChannel = c
go conn.watchForDisconnect()
// start go routine that plays sounds
go conn.playSounds()
// start listening to audio if not locked
if !conn.AudioListenerLock {
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
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:
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
@@ -386,51 +411,14 @@ loop:
conn.VoiceClipQueue <- opusChannel
// check if voice connection fails then break out of audio listener
case <-conn.Disconnect:
break loop
default:
if !conn.VoiceConnection.Ready {
break loop
}
time.Sleep(time.Second * 1)
}
}
// remove lock upon exit
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()
}