123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- package main
- import (
- "flag"
- "fmt"
- "time"
- "github.com/bwmarrin/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)
- }
|