mirror of
https://github.com/mgerb/go-discord-bot
synced 2026-01-10 09:02:49 +00:00
decode full opus stream at one time - fixes #22
This commit is contained in:
@@ -220,7 +220,7 @@ func (conn *AudioConnection) playSoundsInQueue() {
|
|||||||
conn.toggleSoundPlayingLock(true)
|
conn.toggleSoundPlayingLock(true)
|
||||||
|
|
||||||
// Start speaking.
|
// Start speaking.
|
||||||
_ = conn.VoiceConnection.Speaking(true)
|
conn.VoiceConnection.Speaking(true)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -240,7 +240,7 @@ func (conn *AudioConnection) playSoundsInQueue() {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// Stop speaking
|
// Stop speaking
|
||||||
_ = conn.VoiceConnection.Speaking(false)
|
conn.VoiceConnection.Speaking(false)
|
||||||
conn.toggleSoundPlayingLock(false)
|
conn.toggleSoundPlayingLock(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -293,33 +293,33 @@ func writePacketsToFile(username string, packets chan *discordgo.Packet) {
|
|||||||
os.Mkdir(config.Config.ClipsPath, os.ModePerm)
|
os.Mkdir(config.Config.ClipsPath, os.ModePerm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// grab everything from the voice packet channel and dump it to the file
|
opusData := map[uint32][][]byte{}
|
||||||
// close when there is nothing left
|
|
||||||
// split audio into specific voice streams
|
|
||||||
pcmOut := map[uint32][]int16{}
|
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case p := <-packets:
|
case p := <-packets:
|
||||||
// convert opus to pcm
|
// separate opus data for each channel
|
||||||
pcm, err := util.OpusToPCM(p.Opus, sampleRate, channels)
|
opusData[p.SSRC] = append(opusData[p.SSRC], p.Opus)
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pcmOut[p.SSRC] = append(pcmOut[p.SSRC], pcm...)
|
|
||||||
default:
|
default:
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, pcmData := range pcmOut {
|
for key, opus := range opusData {
|
||||||
|
|
||||||
|
pcmData, err := util.OpusToPCM(opus, sampleRate, channels)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// construct filename
|
// construct filename
|
||||||
timestamp := time.Now().UTC().Format("2006-01-02") + "-" + strconv.Itoa(int(time.Now().Unix()))
|
timestamp := time.Now().UTC().Format("2006-01-02") + "-" + strconv.Itoa(int(time.Now().Unix()))
|
||||||
filename := config.Config.ClipsPath + "/" + timestamp + "-" + strconv.Itoa(int(key)) + "-" + username + ".wav"
|
filename := config.Config.ClipsPath + "/" + timestamp + "-" + strconv.Itoa(int(key)) + "-" + username + ".wav"
|
||||||
|
|
||||||
err := util.SavePCMToWavFile(pcmData, filename, sampleRate, channels)
|
err = util.SavePCMToWavFile(pcmData, filename, sampleRate, channels)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
|||||||
@@ -90,30 +90,26 @@ func GetFileExtension(path, fileName string) (string, error) {
|
|||||||
return "", errors.New("file not found")
|
return "", errors.New("file not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache the opusDecoder so we don't have to make a new one every time
|
|
||||||
// was causing audio issues creating a new instance of this every time
|
|
||||||
var opusDecoder *opus.Decoder
|
|
||||||
|
|
||||||
// OpusToPCM - convert opus to pcm
|
// OpusToPCM - convert opus to pcm
|
||||||
func OpusToPCM(data []byte, sampleRate, channels int) ([]int16, error) {
|
func OpusToPCM(opusData [][]byte, sampleRate, channels int) ([]int16, error) {
|
||||||
if opusDecoder == nil {
|
opusDecoder, err := opus.NewDecoder(sampleRate, channels)
|
||||||
var err error
|
pcm := []int16{}
|
||||||
opusDecoder, err = opus.NewDecoder(sampleRate, channels)
|
|
||||||
if err != nil {
|
|
||||||
return []int16{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create pcm list with more than enough space
|
|
||||||
pcm := make([]int16, 10000)
|
|
||||||
n, err := opusDecoder.Decode(data, pcm)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []int16{}, err
|
return pcm, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim the remaining space
|
for _, o := range opusData {
|
||||||
pcm = pcm[:n*channels]
|
// create pcm slice with more than enough space
|
||||||
|
p := make([]int16, 10000)
|
||||||
|
n, err := opusDecoder.Decode(o, p)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return pcm, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm = append(pcm, p[:n*channels]...)
|
||||||
|
}
|
||||||
|
|
||||||
return pcm, nil
|
return pcm, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user