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)