def api(self, bestmatch=True):
        """ Use YouTube API to search and return a list of matching videos. """

        query = {"part": "snippet", "maxResults": 50, "type": "video"}

        if const.args.music_videos_only:
            query["videoCategoryId"] = "10"

        if not self.meta_tags:
            song = self.raw_song
            query["q"] = song
        else:
            query["q"] = self.search_query
        log.debug("query: {0}".format(query))

        data = pafy.call_gdata("search", query)
        data["items"] = list(
            filter(lambda x: x["id"].get("videoId") is not None,
                   data["items"]))
        query_results = {
            "part": "contentDetails,snippet,statistics",
            "maxResults": 50,
            "id": ",".join(i["id"]["videoId"] for i in data["items"]),
        }
        log.debug("query_results: {0}".format(query_results))

        vdata = pafy.call_gdata("videos", query_results)

        videos = []
        for x in vdata["items"]:
            duration_s = pafy.playlist.parseISO8591(
                x["contentDetails"]["duration"])
            youtubedetails = {
                "link": x["id"],
                "title": x["snippet"]["title"],
                "videotime": internals.videotime_from_seconds(duration_s),
                "seconds": duration_s,
            }
            if self.meta_tags["name"] in x["snippet"]["title"]:
                videos.append(youtubedetails)

        log.error("I'm hot")
        if bestmatch:
            return self._best_match(videos)

        return videos
    def api(self, bestmatch=True):
        """ Use YouTube API to search and return a list of matching videos. """

        query = {'part': 'snippet', 'maxResults': 50, 'type': 'video'}

        if const.args.music_videos_only:
            query['videoCategoryId'] = '10'

        if not self.meta_tags:
            song = self.raw_song
            query['q'] = song
        else:
            query['q'] = self.search_query
        log.debug('query: {0}'.format(query))

        data = pafy.call_gdata('search', query)
        data['items'] = list(
            filter(lambda x: x['id'].get('videoId') is not None,
                   data['items']))
        query_results = {
            'part': 'contentDetails,snippet,statistics',
            'maxResults': 50,
            'id': ','.join(i['id']['videoId'] for i in data['items'])
        }
        log.debug('query_results: {0}'.format(query_results))

        vdata = pafy.call_gdata('videos', query_results)

        videos = []
        for x in vdata['items']:
            duration_s = pafy.playlist.parseISO8591(
                x['contentDetails']['duration'])
            youtubedetails = {
                'link': x['id'],
                'title': x['snippet']['title'],
                'videotime': internals.videotime_from_seconds(duration_s),
                'seconds': duration_s
            }
            videos.append(youtubedetails)

        if bestmatch:
            return self._best_match(videos)

        return videos
Example #3
0
 def test_from_hours(self):
     expect_duration = "1:16:02"
     duration = internals.videotime_from_seconds(4562)
     assert duration == expect_duration
Example #4
0
 def test_from_minutes(self):
     expect_duration = "2:38"
     duration = internals.videotime_from_seconds(158)
     assert duration == expect_duration
Example #5
0
 def test_from_seconds(self):
     expect_duration = "35"
     duration = internals.videotime_from_seconds(35)
     assert duration == expect_duration
Example #6
0
    def _best_match(self, videos):
        if not videos:
            log.error("No videos found on YouTube for a given search")
            return None
        """ Select the best matching video from a list of videos. """
        if const.args.manual:
            log.info(self.raw_song)
            log.info("0. Skip downloading this song.\n")
            # fetch all video links on first page on YouTube
            for i, v in enumerate(videos):
                log.info(u"{0}. {1} {2} {3}".format(
                    i + 1,
                    v["title"],
                    v["videotime"],
                    "http://youtube.com/watch?v=" + v["link"],
                ))
            # let user select the song to download
            result = internals.input_link(videos)
            if result is None:
                return None
        else:
            if not self.meta_tags:
                # if the metadata could not be acquired, take the first result
                # from Youtube because the proper song length is unknown
                result = videos[0]
                log.debug(
                    "Since no metadata found on Spotify, going with the first result"
                )
            else:
                # filter out videos that do not have a similar length to the Spotify song
                duration_tolerance = 55
                max_duration_tolerance = 60
                possible_videos_by_duration = []

                log.info("Target Duration: " +
                         internals.videotime_from_seconds(
                             self.meta_tags["duration"]))

                # start with a reasonable duration_tolerance, and increment duration_tolerance
                # until one of the Youtube results falls within the correct duration or
                # the duration_tolerance has reached the max_duration_tolerance
                while len(possible_videos_by_duration) == 0:
                    possible_videos_by_duration = list(
                        filter(
                            lambda x: abs(x["seconds"] - self.meta_tags[
                                "duration"]) <= duration_tolerance,
                            videos,
                        ))
                    duration_tolerance += 1
                    if duration_tolerance > max_duration_tolerance:
                        log.error("{0} by {1} was not found.".format(
                            self.meta_tags["name"],
                            self.meta_tags["artists"][0]["name"],
                        ))
                        return None

                result = possible_videos_by_duration[0]

        if result:
            url = "http://youtube.com/watch?v={0}".format(result["link"])
        else:
            url = None

        return url
Example #7
0
def test_video_time_from_seconds(sec_duration, str_duration):
    duration = internals.videotime_from_seconds(sec_duration)
    assert duration == str_duration