dndmusicbot/youtube.go

120 lines
2.3 KiB
Go

package main
import (
"context"
"crypto/rand"
"encoding/binary"
"fmt"
"io"
"log"
"math/big"
"time"
mrand "math/rand"
"github.com/faiface/beep"
"google.golang.org/api/option"
"google.golang.org/api/youtube/v3"
)
var (
// apikey = "AIzaSyCWO1F6n6UAtOm3L_K-kzF-4UQoS_DmJW0"
yt_url = "https://www.youtube.com/watch?v=%s"
)
func init() {
log.Println("youtube.go loading..")
var err error
apikey := config.GetString("youtube.apikey")
app.youtube, err = youtube.NewService(context.Background(), option.WithAPIKey(apikey))
if err != nil {
log.Fatal(err)
}
log.Println("youtube.go done.")
}
type YT struct {
dst io.WriteCloser
pcm io.ReadCloser
dur time.Duration
pos time.Duration
f beep.Format
}
func ShufflePlaylist(list []string) ([]string, error) {
seedb := make([]byte, 32)
_, err := rand.Read(seedb)
if err != nil {
return nil, err
}
seed := binary.BigEndian.Uint64(seedb)
mrand.Seed(int64(seed))
mrand.Shuffle(len(list), func(i, j int) { list[i], list[j] = list[j], list[i] })
return list, nil
}
func (app *App) GetSong(list []string) string {
return fmt.Sprintf(yt_url, list[app.plidx])
}
func (app *App) GetNextSong(list []string) string {
app.plidx++
if app.plidx >= len(app.active) {
app.plidx = 0
}
return fmt.Sprintf(yt_url, list[app.plidx])
}
func (app *App) GetPrevSong(list []string) string {
app.plidx--
if app.plidx < 0 {
app.plidx = len(list)
}
return fmt.Sprintf(yt_url, list[app.plidx])
}
func GetRandomSong(list []string) string {
if !(len(list) > 0) {
return ""
}
idx, err := rand.Int(rand.Reader, big.NewInt(int64(len(list)-1)))
if err != nil {
log.Println("Failed to get random int, ", err)
return ""
}
return fmt.Sprintf(yt_url, list[idx.Int64()])
}
func (app App) Playlist(playlist string) ([]string, error) {
call := app.youtube.PlaylistItems.List([]string{"contentDetails"})
pageToken := ""
call = call.MaxResults(50)
call = call.PlaylistId(playlist)
if pageToken != "" {
call = call.PageToken(pageToken)
}
var list []string
for {
response, err := call.Do()
if err != nil {
return nil, err
}
for _, item := range response.Items {
list = append(list, item.ContentDetails.VideoId)
}
pageToken = response.NextPageToken
if pageToken == "" {
break
}
}
return list, nil
//return fmt.Sprintf(yt_url, list[rand.Intn(len(list))])
}