discordgo
discordgo copied to clipboard
How to send Opus data correctly
I do see that there's dgVoice
and dca
, but they have been a mess to get working on Windows.
I have now downloaded Opus tools, which include opusenc
, which allows me to convert a .wav
to .opus
. However, I'm not sure how to send the data correctly... here's what I'm currently doing:
package main
import (
"os"
"flag"
"fmt"
// "time"
"bufio"
"github.com/bwmarrin/discordgo"
)
// Variables used for command line parameters
var (
Token string
ChannelID string
GuildID string
)
const (
channels = 2 // --raw-chan 2
frameRate = 48000 // --raw-rate 48000
frameSize = 60 // --framesize 60 (this can't be set to 960 according to opusenc)
maxBytes = frameSize * 2 * 2
)
func init() {
flag.StringVar(&Token, "t", "", "Bot Token")
flag.StringVar(&GuildID, "g", "", "Guild in which voice channel exists")
flag.StringVar(&ChannelID, "c", "", "Voice channel to connect to")
flag.Parse()
}
// Read chunks of the .opus file and send
func play(v *discordgo.VoiceConnection) {
file, err := os.Open("Audiorezout - Anpiel.opus")
if err != nil {
return
}
defer file.Close()
reader := bufio.NewReader(file)
buffer := make([]byte, maxBytes)
v.Speaking(true)
defer v.Speaking(false)
for {
read, err := reader.Read(buffer)
if err != nil {
break
}
if !v.Ready || v.OpusSend == nil {
fmt.Println("Ain't ready")
return
}
// time.Sleep(2000)
v.OpusSend <- buffer[:read]
}
}
func main() {
s, err := discordgo.New("Bot " + Token)
if err != nil {
fmt.Println("error creating Discord session:", err)
return
}
defer s.Close()
s.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsGuildVoiceStates)
err = s.Open()
if err != nil {
fmt.Println("error opening connection:", err)
return
}
v, err := s.ChannelVoiceJoin(GuildID, ChannelID, true, false)
if err != nil {
fmt.Println("failed to join voice channel:", err)
return
}
play(v)
}
So basically I have frameSize * 2 * 2
, which is the amount of bytes I read from "Audiorezout - Anpiel.opus"
and send to the Discord voice channel, without any time out because I'm not sure what it should be.
It does send audio, but not pleasantly at all.
I have attached the music I'm trying to use (from Free Music Archive) Audiorezout - Anpiel.zip
ffmpeg -i "Audiorezout - Anpiel.mp3" "Audiorezout - Anpiel.wav"
opusenc --raw-rate 48000 --raw-chan 2 --framesize 60 "Audiorezout - Anpiel.wav" "Audiorezout - Anpiel.opus"
What about setting the frameSize to 960, have a look here
I do see that there's
dgVoice
anddca
, but they have been a mess to get working on Windows.I have now downloaded Opus tools, which include
opusenc
, which allows me to convert a.wav
to.opus
. However, I'm not sure how to send the data correctly... here's what I'm currently doing:package main import ( "os" "flag" "fmt" // "time" "bufio" "github.com/bwmarrin/discordgo" ) // Variables used for command line parameters var ( Token string ChannelID string GuildID string ) const ( channels = 2 // --raw-chan 2 frameRate = 48000 // --raw-rate 48000 frameSize = 60 // --framesize 60 (this can't be set to 960 according to opusenc) maxBytes = frameSize * 2 * 2 ) func init() { flag.StringVar(&Token, "t", "", "Bot Token") flag.StringVar(&GuildID, "g", "", "Guild in which voice channel exists") flag.StringVar(&ChannelID, "c", "", "Voice channel to connect to") flag.Parse() } // Read chunks of the .opus file and send func play(v *discordgo.VoiceConnection) { file, err := os.Open("Audiorezout - Anpiel.opus") if err != nil { return } defer file.Close() reader := bufio.NewReader(file) buffer := make([]byte, maxBytes) v.Speaking(true) defer v.Speaking(false) for { read, err := reader.Read(buffer) if err != nil { break } if !v.Ready || v.OpusSend == nil { fmt.Println("Ain't ready") return } // time.Sleep(2000) v.OpusSend <- buffer[:read] } } func main() { s, err := discordgo.New("Bot " + Token) if err != nil { fmt.Println("error creating Discord session:", err) return } defer s.Close() s.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsGuildVoiceStates) err = s.Open() if err != nil { fmt.Println("error opening connection:", err) return } v, err := s.ChannelVoiceJoin(GuildID, ChannelID, true, false) if err != nil { fmt.Println("failed to join voice channel:", err) return } play(v) }
So basically I have
frameSize * 2 * 2
, which is the amount of bytes I read from"Audiorezout - Anpiel.opus"
and send to the Discord voice channel, without any time out because I'm not sure what it should be.It does send audio, but not pleasantly at all.
I have attached the music I'm trying to use (from Free Music Archive) Audiorezout - Anpiel.zip
ffmpeg -i "Audiorezout - Anpiel.mp3" "Audiorezout - Anpiel.wav" opusenc --raw-rate 48000 --raw-chan 2 --framesize 60 "Audiorezout - Anpiel.wav" "Audiorezout - Anpiel.opus"
Hey, have you managed to get this kind of thing working ? Also any chance you programatically converted mp3s to opus and then send them to the stream ?
I didn't get it to work.