diff --git a/youtube-dl b/youtube-dl index dd875a38e..4ea5319d3 100755 --- a/youtube-dl +++ b/youtube-dl @@ -2096,7 +2096,8 @@ class YahooSearchIE(InfoExtractor): class YoutubePlaylistIE(InfoExtractor): """Information Extractor for YouTube playlists.""" - _VALID_URL = r'(?:http://)?(?:\w+\.)?youtube.com/(?:(?:view_play_list|my_playlists|artist)\?.*?(p|a)=|user/.*?/user/|p/)([^&]+).*' + _VALID_URL = r'(?:http://)?(?:\w+\.)?youtube.com/(?:(?:view_play_list|my_playlists|artist)\?.*?(?Pp|a)=|user/.*?/user/|p/|user/.*?#(?Pg|p)/c/)(?P[^&]+).*' + _COMBO_ID = r'(?:[^&]+)/(?:[^&]+)/(?P[^&]+)' _TEMPLATE_URL = 'http://www.youtube.com/%s?%s=%s&page=%s&gl=US&hl=en' _VIDEO_INDICATOR = r'/watch\?v=(.+?)&' _MORE_PAGES_INDICATOR = r'(?m)>\s*Next\s*' @@ -2125,17 +2126,29 @@ class YoutubePlaylistIE(InfoExtractor): return # Download playlist pages + playlist_prefix = mobj.group('Pre1') + playlist_altprefix = mobj.group('Pre2') + playlist_id = mobj.group('ID') + is_playlist = True + video_ids = [] + pagenum = 1 # prefix is 'p' as default for playlists but there are other types that need extra care - playlist_prefix = mobj.group(1) if playlist_prefix == 'a': playlist_access = 'artist' else: - playlist_access = 'view_play_list' - playlist_id = mobj.group(2) - video_ids = [] - pagenum = 1 + # Not really a playlist but single video within the list: + if playlist_altprefix == 'p': + is_playlist = False + ids = re.match(self._COMBO_ID, playlist_id) + if ids is None: + self._downloader.trouble(u'ERROR: invalid url: %s' % url) + return + video_ids = [ids.group('ID')] + else: + playlist_prefix = 'p' + playlist_access = 'view_play_list' - while True: + while is_playlist: self.report_download_page(playlist_id, pagenum) request = urllib2.Request(self._TEMPLATE_URL % (playlist_access, playlist_prefix, playlist_id, pagenum)) try: @@ -2155,9 +2168,10 @@ class YoutubePlaylistIE(InfoExtractor): break pagenum = pagenum + 1 - playliststart = self._downloader.params.get('playliststart', 1) - 1 - playlistend = self._downloader.params.get('playlistend', -1) - video_ids = video_ids[playliststart:playlistend] + if is_playlist: + playliststart = self._downloader.params.get('playliststart', 1) - 1 + playlistend = self._downloader.params.get('playlistend', -1) + video_ids = video_ids[playliststart:playlistend] for id in video_ids: self._youtube_ie.extract('http://www.youtube.com/watch?v=%s' % id)