Skip to content
Snippets Groups Projects
SaveMyPlaylist.py 3.48 KiB
Newer Older
  • Learn to ignore specific revisions
  • from __future__ import unicode_literals
    
    import os
    
    import googleapiclient.discovery
    import googleapiclient.errors
    import youtube_dl
    
    
    class MyLogger(object):
        def debug(self, msg):
            pass
    
        def warning(self, msg):
            pass
    
        def error(self, msg):
            print(msg)
    
    
    def my_hook(d):
        if d['status'] == 'finished':
            print('Download finished!')
    
    
    class SaveMyPlaylist:
        SCOPES = ['https://www.googleapis.com/auth/youtube.readonly']
        API_NAME = 'youtube'
        API_VERSION = 'v3'
    
        CHANNEL = 0
        TITLE = 1
        VIDEO_ID = 2
    
    
        ILLEGAL_CHARS = ['NUL', '\',''//', ':', '*', '"', '<', '>', '|']
    
        def __init__(self, apiKey, playlistId):
            self.__apiKey = apiKey
            self.__playlistId = playlistId
            self.__items = self.__fetch_playlist_items()
    
        def __fetch_playlist_items(self):
            youtube = googleapiclient.discovery.build(self.API_NAME, self.API_VERSION, developerKey=self.__apiKey)
            request = youtube.playlistItems().list(
                part='snippet',
                playlistId=self.__playlistId,
                maxResults=50,
            )
    
            response = request.execute()
    
            items = []
    
            for item in response['items']:
                snippet = item['snippet']
                title = snippet['title']
                channel = snippet['channelTitle']
                videoId = snippet['resourceId']['videoId']
                items.append((channel, title, videoId))
                print('{} - {} ({})'.format(channel, title, videoId))
    
            print('\n>>> Found {} items\n'.format(len(items)))
            return items
    
        def download_items(self, destinationFolder, debug=False):
            print('>>> Scanning destination folder...')
            downloadedVideos = [f for f in os.listdir(destinationFolder) if
                                os.path.isfile(os.path.join(destinationFolder, f))]
    
            print('>>> Found {} already downloaded videos'.format(len(downloadedVideos)))
    
            print('\n>>> Started Downloading...')
            newVideos = []
            for idx, item in enumerate(self.__items):
                fileName = '{} - {}.mp4'.format(item[self.TITLE], item[self.CHANNEL])
                fileName = self.__escape_file_name(fileName)
                if fileName in downloadedVideos:
                    print('Skipping {}/{}: "{}" as it already exists'.format(idx + 1, len(self.__items), fileName))
                    continue
    
                print('Downloading {}/{}: "{}"'.format(idx + 1, len(self.__items), fileName))
                newVideos.append(item)
    
                ydl_opts = {
                    'format': 'bestaudio/best',
                    'merge_output_format': 'mp4',
                    'outtmpl': os.path.join(destinationFolder, fileName),
                    'logger': MyLogger(),
                    'progress_hooks': [my_hook],
                }
    
                if debug:
                    continue
    
                with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                    ydl.download(['https://www.youtube.com/watch?v={}'.format(item[self.VIDEO_ID])])
    
            print('\n>>> Finished Downloading')
            print('Downloaded {} new videos'.format(len(newVideos)))
    
        def __escape_file_name(self, fileName):
            for char in self.ILLEGAL_CHARS:
                fileName = fileName.replace(char, '')
    
            return fileName
    
    
    if __name__ == '__main__':
        API_KEY = 'AIzaSyD1cQOPzYDRe5pylXEFsQw6u-MaBSOX09Y'
        PLAYLIST_ID = 'PL7F-5FkCMt0F86pdKUaiTStIloZYDVfzl'
        DESTINATION_FOLDER = 'C:/Users/ROGO2/Desktop/123'
    
        saveMyPlaylist = SaveMyPlaylist(API_KEY, PLAYLIST_ID)
        saveMyPlaylist.download_items(DESTINATION_FOLDER, True)