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