From 1f9706060af4e4566c241aba8f9dba10f87065a4 Mon Sep 17 00:00:00 2001 From: Mitchell Date: Wed, 30 May 2018 19:27:09 -0500 Subject: [PATCH] wip --- server/bothandlers/sounds.go | 12 ++++++++++- server/rtp/rtp.go | 36 ++++++++++++++++++++++++++++++++ server/rtp/stream.go | 40 ++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 server/rtp/rtp.go create mode 100644 server/rtp/stream.go diff --git a/server/bothandlers/sounds.go b/server/bothandlers/sounds.go index f3d3b71..ed920d0 100644 --- a/server/bothandlers/sounds.go +++ b/server/bothandlers/sounds.go @@ -5,6 +5,7 @@ import ( "bytes" "encoding/binary" "errors" + "fmt" "io" "io/ioutil" "os" @@ -18,6 +19,7 @@ import ( "github.com/bwmarrin/discordgo" "github.com/mgerb/go-discord-bot/server/config" + "github.com/mgerb/go-discord-bot/server/rtp" log "github.com/sirupsen/logrus" ) @@ -25,6 +27,7 @@ const ( channels int = 2 // 1 for mono, 2 for stereo sampleRate int = 48000 // audio sampling rate - apparently a standard for opus frameSize int = 960 // uint16 size of each audio frame + frameSizeMs int = 20 // 20 milliseconds between each frame maxBytes int = (frameSize * 2) * 2 // max size of opus data maxSoundQueue int = 10 // max amount of sounds that can be queued at one time voiceClipQueuePacketSize int = 2000 // this packet size equates to roughly 40 seconds of audio @@ -32,7 +35,6 @@ const ( // store our connection objects in a map tied to a guild id var activeConnections = make(map[string]*AudioConnection) -var speakers = make(map[uint32]*gopus.Decoder) // AudioConnection - type AudioConnection struct { @@ -351,6 +353,9 @@ func (conn *AudioConnection) startAudioListener() { } }() + var speakers = make(map[uint32]*gopus.Decoder) + realTimeAudio := rtp.New() + loop: for { @@ -373,11 +378,16 @@ loop: } opusChannel.PCM, err = speakers[opusChannel.SSRC].Decode(opusChannel.Opus, frameSize, false) + if err != nil { log.Error("Error decoding opus data", err) continue } + realTimeAudio.PushPacket(opusChannel) + + fmt.Println(realTimeAudio.GetStream(opusChannel.SSRC).GetTimeOffset(realTimeAudio.StartTime.Unix())) + // if channel is full trim off from beginning if len(conn.VoiceClipQueue) == cap(conn.VoiceClipQueue) { <-conn.VoiceClipQueue diff --git a/server/rtp/rtp.go b/server/rtp/rtp.go new file mode 100644 index 0000000..f1e4d9b --- /dev/null +++ b/server/rtp/rtp.go @@ -0,0 +1,36 @@ +// rtp packet processing + +package rtp + +import ( + "time" + + "github.com/bwmarrin/discordgo" +) + +// RTP - +type RTP struct { + StartTime time.Time + Streams map[uint32]*Stream +} + +// New - +func New() *RTP { + return &RTP{ + StartTime: time.Now(), + Streams: map[uint32]*Stream{}, + } +} + +// PushPacket - +func (r *RTP) PushPacket(packet *discordgo.Packet) { + if _, ok := r.Streams[packet.SSRC]; !ok { + r.Streams[packet.SSRC] = new(Stream) + } + r.Streams[packet.SSRC].PushPacket(packet) +} + +// GetStream - +func (r *RTP) GetStream(ssrc uint32) *Stream { + return r.Streams[ssrc] +} diff --git a/server/rtp/stream.go b/server/rtp/stream.go new file mode 100644 index 0000000..4c31c0c --- /dev/null +++ b/server/rtp/stream.go @@ -0,0 +1,40 @@ +package rtp + +import ( + "time" + + "github.com/bwmarrin/discordgo" +) + +// Stream - +type Stream struct { + StartTime time.Time + StartingTimestamp uint32 + LatestTimestamp uint32 + Packets []*discordgo.Packet +} + +// GetTimeDiff - +func (s *Stream) GetTimeDiff() uint32 { + return s.LatestTimestamp - s.StartingTimestamp +} + +func (s *Stream) GetTimeOffset(startTime int64) int64 { + return s.StartTime.Unix() - startTime +} + +// PushPacket - +func (s *Stream) PushPacket(packet *discordgo.Packet) { + + if s.StartTime.Unix() == 0 { + s.StartTime = time.Now() + } + + if s.StartingTimestamp == 0 && packet.Timestamp != 0 { + s.StartingTimestamp = packet.Timestamp + } + + s.LatestTimestamp = packet.Timestamp + + s.Packets = append(s.Packets, packet) +}