all repos — disgord @ main

A simple Discord bot in Go.

src/music/audio.go (view raw)

 1package music
 2
 3import (
 4	"github.com/ClintonCollins/dca"
 5	"github.com/bwmarrin/discordgo"
 6)
 7
 8type Audio struct {
 9	session  *dca.EncodeSession
10	stream   *dca.StreamingSession
11	Done     chan error
12	onFinish func()
13	paused   bool
14}
15
16var audioEncodeOptions = &dca.EncodeOptions{
17	Channels:         2,
18	FrameRate:        48000,
19	FrameDuration:    20,
20	Bitrate:          96,
21	Application:      dca.AudioApplicationLowDelay,
22	CompressionLevel: 10,
23	PacketLoss:       1,
24	BufferedFrames:   100,
25	VBR:              true,
26	StartTime:        0,
27	VolumeFloat:      1,
28	RawOutput:        true,
29}
30
31func NewAudio(url string, vc *discordgo.VoiceConnection) (as *Audio, err error) {
32	as = &Audio{
33		session: nil,
34		stream:  nil,
35		paused:  false,
36		Done:    make(chan error),
37	}
38
39	as.session, err = dca.EncodeFile(url, audioEncodeOptions)
40	if err != nil {
41		return
42	}
43
44	as.stream = dca.NewStream(as.session, vc, as.Done)
45	return
46}
47
48func (a *Audio) Pause() {
49	if a.stream == nil || a.paused {
50		return
51	}
52
53	a.stream.SetPaused(true)
54	a.paused = true
55}
56
57func (a *Audio) Resume() {
58	if a.stream == nil || !a.paused {
59		return
60	}
61
62	a.stream.SetPaused(false)
63	a.paused = false
64}
65
66func (a *Audio) Stop() {
67	if a.stream == nil {
68		return
69	}
70
71	a.session.Stop()
72	a.session.Cleanup()
73	a.stream = nil
74	a.session = nil
75}
76
77func (a *Audio) Finished() (bool, error) {
78	return a.stream.Finished()
79}
80
81func (a *Audio) Monitor(onFinish func()) {
82	go func() {
83		for err := range a.Done {
84			if err != nil {
85				logger.Errorf("Playback error: %v", err)
86				break
87			}
88		}
89
90		a.Stop()
91
92		if onFinish != nil {
93			onFinish()
94		}
95	}()
96}