// NewSong creates a track and adds to the queue func (sc SoundCloud) NewSong(user *gumble.User, trackData *jsonq.JsonQuery, offset int, playlist Playlist) (Song, error) { title, _ := trackData.String("title") id, _ := trackData.Int("id") durationMS, _ := trackData.Int("duration") url, _ := trackData.String("permalink_url") thumbnail, err := trackData.String("artwork_url") if err != nil { // Song has no artwork, using profile avatar instead userObj, _ := trackData.Object("user") thumbnail, _ = jsonq.NewQuery(userObj).String("avatar_url") } song := &AudioTrack{ id: strconv.Itoa(id), title: title, url: url, thumbnail: thumbnail, submitter: user, duration: durationMS / 1000, offset: offset, format: "mp3", playlist: playlist, skippers: make([]string, 0), dontSkip: false, service: sc, } return song, nil }
// NewSong creates a track and adds to the queue func (mc Mixcloud) NewSong(user *gumble.User, trackData *jsonq.JsonQuery, offset int) (Song, error) { title, _ := trackData.String("name") id, _ := trackData.String("slug") duration, _ := trackData.Int("audio_length") url, _ := trackData.String("url") thumbnail, err := trackData.String("pictures", "large") if err != nil { // Song has no artwork, using profile avatar instead userObj, _ := trackData.Object("user") thumbnail, _ = jsonq.NewQuery(userObj).String("pictures", "thumbnail") } song := &AudioTrack{ id: id, title: title, url: url, thumbnail: thumbnail, submitter: user, duration: duration, offset: offset, format: "best", skippers: make([]string, 0), dontSkip: false, service: mc, } return song, nil }
func parse_collection(jq *jsonq.JsonQuery) *Collection { out := new(Collection) out.Count, _ = jq.Int("count") out.Hidden, _ = jq.Bool("hidden") out.Name, _ = jq.String("name") out.ResolveList, _ = jq.ArrayOfStrings("resolve_list") return out }
// NewYouTubePlaylist gathers the metadata for a YouTube playlist and returns it. func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) { var apiResponse *jsonq.JsonQuery var err error // Retrieve title of playlist url := fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlists?part=snippet&id=%s&key=%s", id, os.Getenv("YOUTUBE_API_KEY")) if apiResponse, err = PerformGetRequest(url); err != nil { return nil, err } title, _ := apiResponse.String("items", "0", "snippet", "title") playlist := &YouTubePlaylist{ id: id, title: title, } // Retrieve items in playlist url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=%s&key=%s", id, os.Getenv("YOUTUBE_API_KEY")) if apiResponse, err = PerformGetRequest(url); err != nil { return nil, err } numVideos, _ := apiResponse.Int("pageInfo", "totalResults") if numVideos > 25 { numVideos = 25 } for i := 0; i < numVideos; i++ { index := strconv.Itoa(i) videoTitle, err := apiResponse.String("items", index, "snippet", "title") videoID, _ := apiResponse.String("items", index, "snippet", "resourceId", "videoId") videoThumbnail, _ := apiResponse.String("items", index, "snippet", "thumbnails", "high", "url") // A completely separate API call just to get the duration of a video in a // playlist? WHY GOOGLE, WHY?! var durationResponse *jsonq.JsonQuery url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=%s&key=%s", videoID, os.Getenv("YOUTUBE_API_KEY")) if durationResponse, err = PerformGetRequest(url); err != nil { return nil, err } videoDuration, _ := durationResponse.String("items", "0", "contentDetails", "duration") var days, hours, minutes, seconds int64 timestampExp := regexp.MustCompile(`P(?P<days>\d+D)?T(?P<hours>\d+H)?(?P<minutes>\d+M)?(?P<seconds>\d+S)?`) timestampMatch := timestampExp.FindStringSubmatch(videoDuration) timestampResult := make(map[string]string) for i, name := range timestampExp.SubexpNames() { if i < len(timestampMatch) { timestampResult[name] = timestampMatch[i] } } if timestampResult["days"] != "" { days, _ = strconv.ParseInt(strings.TrimSuffix(timestampResult["days"], "D"), 10, 32) } if timestampResult["hours"] != "" { hours, _ = strconv.ParseInt(strings.TrimSuffix(timestampResult["hours"], "H"), 10, 32) } if timestampResult["minutes"] != "" { minutes, _ = strconv.ParseInt(strings.TrimSuffix(timestampResult["minutes"], "M"), 10, 32) } if timestampResult["seconds"] != "" { seconds, _ = strconv.ParseInt(strings.TrimSuffix(timestampResult["seconds"], "S"), 10, 32) } totalSeconds := int((days * 86400) + (hours * 3600) + (minutes * 60) + seconds) var durationString string if hours != 0 { if days != 0 { durationString = fmt.Sprintf("%d:%02d:%02d:%02d", days, hours, minutes, seconds) } else { durationString = fmt.Sprintf("%d:%02d:%02d", hours, minutes, seconds) } } else { durationString = fmt.Sprintf("%d:%02d", minutes, seconds) } if dj.conf.General.MaxSongDuration == 0 || totalSeconds <= dj.conf.General.MaxSongDuration { playlistSong := &YouTubeSong{ submitter: user, title: videoTitle, id: videoID, filename: videoID + ".m4a", duration: durationString, thumbnail: videoThumbnail, skippers: make([]string, 0), playlist: playlist, dontSkip: false, } dj.queue.AddSong(playlistSong) } } return playlist, nil }