From eb49caebed7e9da0498b2f3ba1e0f497d79f40fb Mon Sep 17 00:00:00 2001 From: Bharat Kalluri Date: Sun, 1 Aug 2021 23:02:57 +0530 Subject: [PATCH] change search query to use all artist names and fetch song according to duration --- src/start.go | 9 +++++++-- src/youtube.go | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/start.go b/src/start.go index c75f288..51e49fd 100644 --- a/src/start.go +++ b/src/start.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "os" + "strings" "github.com/zmb3/spotify" ) @@ -87,8 +88,12 @@ func DownloadTrackList(cli UserData) { fmt.Println("Found", len(cli.TrackList), "tracks") fmt.Println("Searching and downloading tracks") for _, val := range cli.TrackList { - searchTerm := val.Name + " " + val.Artists[0].Name - youtubeID, err := GetYoutubeId(searchTerm) + var artistNames []string + for _, artistInfo := range val.Artists { + artistNames = append(artistNames, artistInfo.Name) + } + searchTerm := strings.Join(artistNames, " ") + " " + val.Name + youtubeID, err := GetYoutubeId(searchTerm, val.Duration/1000) if err != nil { log.Printf("Error occured for %s error: %s", val.Name, err) continue diff --git a/src/youtube.go b/src/youtube.go index 18a1700..3f937ca 100644 --- a/src/youtube.go +++ b/src/youtube.go @@ -8,10 +8,12 @@ import ( "io/ioutil" "net/http" "net/url" + "strconv" "strings" ) var httpClient = &http.Client{} +var durationMatchThreshold = 5 type SearchResult struct { Title, Uploader, URL, Duration, ID string @@ -20,9 +22,28 @@ type SearchResult struct { Extra []string } +func convertStringDurationToSeconds(durationStr string) int { + splitEntities := strings.Split(durationStr, ":") + if len(splitEntities) == 1 { + seconds, _ := strconv.Atoi(splitEntities[0]) + return seconds + } else if len(splitEntities) == 2 { + seconds, _ := strconv.Atoi(splitEntities[1]) + minutes, _ := strconv.Atoi(splitEntities[0]) + return (minutes * 60) + seconds + } else if len(splitEntities) == 3 { + seconds, _ := strconv.Atoi(splitEntities[2]) + minutes, _ := strconv.Atoi(splitEntities[1]) + hours, _ := strconv.Atoi(splitEntities[0]) + return ((hours * 60) * 60) + (minutes * 60) + seconds + } else { + return 0 + } +} + // GetYoutubeId takes the query as string and returns the search results video ID's -func GetYoutubeId(searchQuery string) (string, error) { - searchResults, err := ytSearch(searchQuery, 1) +func GetYoutubeId(searchQuery string, songDurationInSeconds int) (string, error) { + searchResults, err := ytSearch(searchQuery, 10) if err != nil { return "", err } @@ -30,6 +51,16 @@ func GetYoutubeId(searchQuery string) (string, error) { errorMessage := fmt.Sprintf("no songs found for %s", searchQuery) return "", errors.New(errorMessage) } + // Try for the closest match timestamp wise + for _, result := range searchResults { + allowedDurationRangeStart := songDurationInSeconds - durationMatchThreshold + allowedDurationRangeEnd := songDurationInSeconds + durationMatchThreshold + resultSongDuration := convertStringDurationToSeconds(result.Duration) + if resultSongDuration >= allowedDurationRangeStart && resultSongDuration <= allowedDurationRangeEnd { + return result.ID, nil + } + } + // Else return the first result if nothing is found return searchResults[0].ID, nil }