forked from bwmarrin/discordgo
/
main.go
99 lines (86 loc) · 2.15 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"flag"
"fmt"
"time"
"github.com/hexnaught/discordgo"
"github.com/pion/rtp"
"github.com/pion/webrtc/v3/pkg/media"
"github.com/pion/webrtc/v3/pkg/media/oggwriter"
)
// Variables used for command line parameters
var (
Token string
ChannelID string
GuildID string
)
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()
}
func createPionRTPPacket(p *discordgo.Packet) *rtp.Packet {
return &rtp.Packet{
Header: rtp.Header{
Version: 2,
// Taken from Discord voice docs
PayloadType: 0x78,
SequenceNumber: p.Sequence,
Timestamp: p.Timestamp,
SSRC: p.SSRC,
},
Payload: p.Opus,
}
}
func handleVoice(c chan *discordgo.Packet) {
files := make(map[uint32]media.Writer)
for p := range c {
file, ok := files[p.SSRC]
if !ok {
var err error
file, err = oggwriter.New(fmt.Sprintf("%d.ogg", p.SSRC), 48000, 2)
if err != nil {
fmt.Printf("failed to create file %d.ogg, giving up on recording: %v\n", p.SSRC, err)
return
}
files[p.SSRC] = file
}
// Construct pion RTP packet from DiscordGo's type.
rtp := createPionRTPPacket(p)
err := file.WriteRTP(rtp)
if err != nil {
fmt.Printf("failed to write to file %d.ogg, giving up on recording: %v\n", p.SSRC, err)
}
}
// Once we made it here, we're done listening for packets. Close all files
for _, f := range files {
f.Close()
}
}
func main() {
s, err := discordgo.New("Bot " + Token)
if err != nil {
fmt.Println("error creating Discord session:", err)
return
}
defer s.Close()
// We only really care about receiving voice state updates.
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
}
go func() {
time.Sleep(10 * time.Second)
close(v.OpusRecv)
v.Close()
}()
handleVoice(v.OpusRecv)
}