Files
website/radio/playlist.go
2025-05-22 18:08:15 +02:00

131 lines
3.2 KiB
Go

package radio
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
type YoutubeChannel struct {
Id string
Name string
}
type PlaylistItem struct {
Etag string
Id string
PublishedAt time.Time
Channel YoutubeChannel
VideoId string
Title string
Description string
ThumbnailUrl string
Position int
}
type PlaylistResponseSnippet struct {
PublishedAt string `json:"publishedAt"`
VideoOwnerChannelId string `json:"videoOwnerChannelId"`
VideoOwnerChannelTitle string `json:"videoOwnerChannelTitle"`
ResourceId PlaylistResponseResourceId `json:"resourceId"`
Title string `json:"title"`
Description string `json:"description"`
Position int `json:"position"`
}
type PlaylistResponseItem struct {
Etag string `json:"etag"`
Id string `json:"id"`
Snippet PlaylistResponseSnippet `json:"snippet"`
}
type PlaylistResponseResourceId struct {
VideoId string `json:"videoId"`
}
type PlaylistResponse struct {
Items []PlaylistResponseItem `json:"items"`
NextPageToken string `json:"nextPageToken"`
}
func requestYouTubePlaylist(playlistId string, pageToken string) ([]PlaylistItem, string) {
apiUrl, err := url.Parse("https://www.googleapis.com/youtube/v3/playlistItems")
if err != nil {
panic(err)
}
q := apiUrl.Query()
q.Add("key", os.Getenv("GOOGLE_API_KEY"))
q.Add("playlistId", playlistId)
q.Add("part", "id,snippet,contentDetails,status")
q.Add("maxResults", "50")
if pageToken != "" {
q.Add("pageToken", pageToken)
}
apiUrl.RawQuery = q.Encode()
response, err := http.Get(apiUrl.String())
if err != nil {
return nil, ""
}
body, err := io.ReadAll(response.Body)
if err != nil {
return nil, ""
}
//type playlistResponse PlaylistResponse
var playlistItems PlaylistResponse
err = json.Unmarshal(body, &playlistItems)
if err != nil {
return nil, ""
}
var items []PlaylistItem
for _, item := range playlistItems.Items {
publishedAt, err := time.Parse(time.RFC3339, item.Snippet.PublishedAt)
if err != nil {
panic(err)
}
items = append(items, PlaylistItem{
Etag: item.Etag,
Id: item.Id,
PublishedAt: publishedAt,
VideoId: item.Snippet.ResourceId.VideoId,
Title: item.Snippet.Title,
Description: item.Snippet.Description,
ThumbnailUrl: fmt.Sprint("https://youtubethumbnails.prettysunflower.moe/", item.Snippet.ResourceId.VideoId),
Position: item.Snippet.Position,
Channel: YoutubeChannel{
Id: item.Snippet.VideoOwnerChannelId,
Name: item.Snippet.VideoOwnerChannelTitle,
},
})
}
return items, playlistItems.NextPageToken
}
func getPlaylistOfVideos(playlistId string) []PlaylistItem {
var playlistItems []PlaylistItem
nextPageToken := ""
for {
newItems, newNextPageToken := requestYouTubePlaylist(playlistId, nextPageToken)
playlistItems = append(playlistItems, newItems...)
if newNextPageToken == "" {
return playlistItems
}
nextPageToken = newNextPageToken
}
}