reliability improvements

die on mumble disconnect
drop packets if channel is full
This commit is contained in:
Tyler Stiene 2020-11-04 01:12:43 -05:00
parent 8d9df9e95b
commit 33e3ea70a4
6 changed files with 84 additions and 57 deletions

View File

@ -4,7 +4,7 @@ mumble-discord-bridge: $(GOFILES)
go build -o $@ $(GOFILES)
docker-latest:
docker build .
docker build -t stieneee/mumble-discord-bridge:latest .
docker push stieneee/mumble-bridge-latest
clean:

View File

@ -2,7 +2,7 @@ package main
import (
"fmt"
"os"
"log"
"sync"
"time"
@ -28,9 +28,9 @@ var OnError = func(str string, err error) {
prefix := "dgVoice: " + str
if err != nil {
os.Stderr.WriteString(prefix + ": " + err.Error())
log.Println(prefix + ": " + err.Error())
} else {
os.Stderr.WriteString(prefix)
log.Println(prefix)
}
}
@ -47,7 +47,7 @@ func discordSendPCM(v *discordgo.VoiceConnection, pcm <-chan []int16) {
opusEncoder, err := gopus.NewEncoder(frameRate, channels, gopus.Audio)
if err != nil {
OnError("NewEncoder Error", err)
return
panic(err)
}
ticker := time.NewTicker(20 * time.Millisecond)
@ -68,12 +68,12 @@ func discordSendPCM(v *discordgo.VoiceConnection, pcm <-chan []int16) {
opus, err := opusEncoder.Encode(append(r1, r2...), frameSize, maxBytes)
if err != nil {
OnError("Encoding Error", err)
return
continue
}
if v.Ready == false || v.OpusSend == nil {
OnError(fmt.Sprintf("Discordgo not ready for opus packets. %+v : %+v", v.Ready, v.OpusSend), nil)
return
continue
}
v.OpusSend <- opus
@ -94,13 +94,13 @@ func discordReceivePCM(v *discordgo.VoiceConnection) {
for {
if v.Ready == false || v.OpusRecv == nil {
OnError(fmt.Sprintf("Discordgo not to receive opus packets. %+v : %+v", v.Ready, v.OpusSend), nil)
return
continue
}
p, ok := <-v.OpusRecv
if !ok {
fmt.Println("Opus not ok")
return
log.Println("Opus not ok")
continue
}
discordMutex.Lock()
@ -178,7 +178,12 @@ func fromDiscordMixer(toMumble chan<- gumble.AudioBuffer) {
}
if sendAudio {
toMumble <- outBuf
select {
case toMumble <- outBuf:
default:
log.Println("toMumble buffer full. Dropping packet")
}
}
}
}

View File

@ -0,0 +1,13 @@
version: "3"
services:
mumble-discord-bridge:
image: stieneee/mumble-discord-bridge
restart: unless-stopped
environment:
- MUMBLE_ADDRESS=example.com"
- MUMBLE_USERNAME=discord-bridge
- MUMBLE_PASSWORD=password
- DISCORD_TOKEN=token
- DISCORD_GID=gid
- DISCORD_CID=cid

View File

@ -1,13 +0,0 @@
version: "3.8"
services:
mumble-discord-bridge:
image: stieneee/mumble-discord-bridge
restart: always
environment:
- MUMBLE_ADDRESS=
- MUMBLE_USERNAME=
- MUMBLE_PASSWORD=
- DISCORD_TOKEN=
- DISCORD_GID=
- DISCORD_CID=

82
main.go
View File

@ -86,6 +86,35 @@ func main() {
log.Fatalln("missing discord cid")
}
// DISCORD Setup
discord, err := discordgo.New("Bot " + *discordToken)
if err != nil {
log.Println(err)
return
}
// Open Websocket
discord.LogLevel = 2
err = discord.Open()
if err != nil {
log.Println(err)
return
}
defer discord.Close()
log.Println("Discord Bot Connected")
dgv, err := discord.ChannelVoiceJoin(*discordGID, *discordCID, false, false)
if err != nil {
log.Println(err)
return
}
defer dgv.Speaking(false)
defer dgv.Close()
discord.ShouldReconnectOnError = true
// MUMBLE Setup
config := gumble.NewConfig()
@ -100,41 +129,21 @@ func main() {
log.Println(err)
return
}
defer mumble.Disconnect()
// Shared Channels
// Shared channels pass PCM information in 10ms chunks [480]int16
var toMumble = mumble.AudioOutgoing()
var toDiscord = make(chan []int16, 100)
go m.fromMumbleMixer(toDiscord)
config.AudioListeners.Attach(m)
var die = make(chan bool)
log.Println("Mumble Connected")
// DISCORD Setup
discord, err := discordgo.New("Bot " + *discordToken)
if err != nil {
log.Println(err)
return
}
// Open Websocket
err = discord.Open()
if err != nil {
log.Println(err)
return
}
log.Println("Discord Bot Connected")
dgv, err := discord.ChannelVoiceJoin(*discordGID, *discordCID, false, false)
if err != nil {
log.Println(err)
return
}
// Start Passing Between
// Mumble
go m.fromMumbleMixer(toDiscord)
config.AudioListeners.Attach(m)
//Discord
go discordReceivePCM(dgv)
go fromDiscordMixer(toMumble)
go discordSendPCM(dgv, toDiscord)
@ -143,12 +152,21 @@ func main() {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt)
go func() {
ticker := time.NewTicker(500 * time.Millisecond)
for {
<-ticker.C
if mumble.State() != 2 {
log.Println("Lost mumble connection " + strconv.Itoa(int(mumble.State())))
die <- true
}
}
}()
select {
case sig := <-c:
log.Printf("\nGot %s signal. Ending Mumble-Bridge\n", sig)
mumble.Disconnect()
dgv.Speaking(false)
dgv.Close()
discord.Close()
log.Printf("\nGot %s signal. Terminating Mumble-Bridge\n", sig)
case <-die:
log.Println("\nGot internal die request. Terminating Mumble-Bridge")
}
}

View File

@ -86,7 +86,11 @@ func (m MumbleDuplex) fromMumbleMixer(toDiscord chan []int16) {
}
if sendAudio {
toDiscord <- outBuf
select {
case toDiscord <- outBuf:
default:
log.Println("toDiscord buffer full. Dropping packet")
}
}
}
}