-
Notifications
You must be signed in to change notification settings - Fork 0
/
queue.go
169 lines (146 loc) · 5.04 KB
/
queue.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package main
import (
"log"
"strconv"
"github.com/bwmarrin/discordgo"
)
// This is the main function that plays the queue
// - It will play the queue until it's empty
// - If the queue is empty, it will leave the voice channel
func playQueue(m *discordgo.MessageCreate, isManual bool) {
// Iterate through the queue, playing each song
for len(queue) > 0 {
if len(queue) != 0 {
v.nowPlaying, queue = queue[0], queue[1:]
} else {
v.nowPlaying = Song{}
break
}
v.stop = false
v.voice.Speaking(true)
// TODO: Consider removing mpeg support
if isManual {
v.DCA(v.nowPlaying.Title, isManual)
} else {
v.DCA(v.nowPlaying.VideoURL, isManual)
}
// Queue not empty, next song isn't empty (incase nil song in queue)
if len(queue) != 0 && queue[0].Title != "" {
s.ChannelMessageSend(m.ChannelID, "**[Muse]** Next! Now playing ["+queue[0].Title+"] :loop:")
}
}
// No more songs in the queue, reset the queue + leave channel
s.ChannelMessageSend(m.ChannelID, "**[Muse]** Nothing left to play, peace! :v:")
v.stop = true
v.nowPlaying = Song{}
queue = []Song{}
v.voice.Disconnect()
// Cleanup the encoder
if v.encoder != nil {
v.encoder.Cleanup()
}
}
// Fetch a single video and place into song queue
// Single video link (not a playlist)
func queueSingleSong(m *discordgo.MessageCreate, link string) {
video, err := client.GetVideo(link)
if err != nil {
log.Println(err)
} else {
// Get formats with audio channels only
format := video.Formats.WithAudioChannels()
// Fill Song Info
song = fillSongInfo(m.ChannelID, m.Author.ID, m.ID, video.ID, video.Title, video.Duration.String())
// Select the correct video format - Check if it's in the song quality list file first
formatList := prepSongFormat(format)
url, err := client.GetStreamURL(video, formatList)
if err != nil {
log.Println(err)
} else {
song.VideoURL = url
queue = append(queue, song)
}
}
}
// Queue the playlist - Gets the playlist ID and searches for all individual videos & queue's them
func queuePlaylist(playlistID string, m *discordgo.MessageCreate) {
nextPageToken := "" // Used to iterate through videos in a playlist
for {
// Retrieve next set of items in the playlist.
var snippet = []string{"snippet"}
playlistResponse := playlistItemsList(service, snippet, playlistID, nextPageToken)
for _, playlistItem := range playlistResponse.Items {
videoId := playlistItem.Snippet.ResourceId.VideoId
content := "https://www.youtube.com/watch?v=" + videoId
// Get Video Data
video, err := client.GetVideo(content)
if err != nil {
log.Println(err)
} else {
format := video.Formats.WithAudioChannels() // Get matches with audio channels only
song = fillSongInfo(m.ChannelID, m.Author.ID, m.ID, video.ID, video.Title, video.Duration.String())
formatList := prepSongFormat(format)
url, err := client.GetStreamURL(video, formatList)
if err != nil {
log.Println(err)
} else {
song.VideoURL = url
queue = append(queue, song)
}
}
}
// Set the token to retrieve the next page of results
nextPageToken = playlistResponse.NextPageToken
// Nothing left, break out
if nextPageToken == "" {
break
}
}
}
// Plays the chosen song from a list provided by the search function
func playFromSearch(input int, m *discordgo.MessageCreate) {
if input <= len(searchQueue) && input > 0 {
queueSingleSong(m, searchQueue[input-1].Id)
} else {
s.ChannelMessageSend(m.ChannelID, "**[Muse]** The value you entered was outside the range of the search...")
}
searchRequested = false
}
// Plays the chosen song from the queue
func playFromQueue(input int, m *discordgo.MessageCreate) {
if input <= len(queue) && input > 0 {
var tmp []Song
for i, value := range queue {
switch i {
case 0:
tmp = append(tmp, queue[input-1])
tmp = append(tmp, value)
case input - 1:
default:
tmp = append(tmp, value)
}
}
s.ChannelMessageSend(m.ChannelID, "**[Muse]** Moved "+queue[input-1].Title+" to the top of the queue")
queue = tmp
prepSkip()
} else {
s.ChannelMessageSend(m.ChannelID, "**[Muse]** Selected input was not in queue range")
}
}
// Prepares queue display
func prepDisplayQueue(commData []string, queueLenBefore int, m *discordgo.MessageCreate) {
// Only display queue if it grew in size...
if queueLenBefore < len(queue) {
displayQueue(m)
} else {
if _, err := strconv.Atoi(commData[1]); err == nil {
return
}
nothingAddedMessage := "**[Muse]** Nothing was added, playlist or song was empty...\n"
nothingAddedMessage = nothingAddedMessage + "Note:\n"
nothingAddedMessage = nothingAddedMessage + "- Playlists should have the following url structure: <https://www.youtube.com/playlist?list=><PLAYLIST IDENTIFIER>\n"
nothingAddedMessage = nothingAddedMessage + "- Videos should have the following url structure: <https://www.youtube.com/watch?v=><VIDEO IDENTIFIER>\n"
nothingAddedMessage = nothingAddedMessage + "- Youtu.be links or links set at a certain time (t=#s) have not been implemented - sorry!"
s.ChannelMessageSend(m.ChannelID, nothingAddedMessage)
}
}