diff --git a/yt_dlp/extractor/abc.py b/yt_dlp/extractor/abc.py index 354453a27..0dde4a9a5 100644 --- a/yt_dlp/extractor/abc.py +++ b/yt_dlp/extractor/abc.py @@ -300,11 +300,10 @@ class ABCIViewShowSeriesIE(InfoExtractor): unescapeHTML(webpage_data).encode('utf-8').decode('unicode_escape'), show_id) video_data = video_data['route']['pageData']['_embedded'] - if self.get_param('noplaylist') and 'highlightVideo' in video_data: - self.to_screen('Downloading just the highlight video because of --no-playlist') - return self.url_result(video_data['highlightVideo']['shareUrl'], ie=ABCIViewIE.ie_key()) + highlight = try_get(video_data, lambda x: ['highlightVideo']['shareUrl']) + if not self._yes_playlist(show_id, bool(highlight), video_label='highlight video'): + return self.url_result(highlight, ie=ABCIViewIE.ie_key()) - self.to_screen(f'Downloading playlist {show_id} - add --no-playlist to just download the highlight video') series = video_data['selectedSeries'] return { '_type': 'playlist', diff --git a/yt_dlp/extractor/common.py b/yt_dlp/extractor/common.py index 74114e355..77e358bbe 100644 --- a/yt_dlp/extractor/common.py +++ b/yt_dlp/extractor/common.py @@ -3710,6 +3710,22 @@ class InfoExtractor(object): return [] if default is NO_DEFAULT else default return list(val) if casesense else [x.lower() for x in val] + def _yes_playlist(self, playlist_id, video_id, smuggled_data=None, *, playlist_label='playlist', video_label='video'): + if not playlist_id or not video_id: + return not video_id + + no_playlist = (smuggled_data or {}).get('force_noplaylist') + if no_playlist is not None: + return not no_playlist + + video_id = '' if video_id is True else f' {video_id}' + playlist_id = '' if playlist_id is True else f' {playlist_id}' + if self.get_param('noplaylist'): + self.to_screen(f'Downloading just the {video_label}{video_id} because of --no-playlist') + return False + self.to_screen(f'Downloading {playlist_label}{playlist_id} - add --no-playlist to download just the {video_label}{video_id}') + return True + class SearchInfoExtractor(InfoExtractor): """ diff --git a/yt_dlp/extractor/dailymotion.py b/yt_dlp/extractor/dailymotion.py index b4211e1e4..e71462061 100644 --- a/yt_dlp/extractor/dailymotion.py +++ b/yt_dlp/extractor/dailymotion.py @@ -207,12 +207,10 @@ class DailymotionIE(DailymotionBaseInfoExtractor): video_id, playlist_id = self._match_valid_url(url).groups() if playlist_id: - if not self.get_param('noplaylist'): - self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % playlist_id) + if self._yes_playlist(playlist_id, video_id): return self.url_result( 'http://www.dailymotion.com/playlist/' + playlist_id, 'DailymotionPlaylist', playlist_id) - self.to_screen('Downloading just video %s because of --no-playlist' % video_id) password = self.get_param('videopassword') media = self._call_api( diff --git a/yt_dlp/extractor/daum.py b/yt_dlp/extractor/daum.py index 8aa2af9a8..4362e92cb 100644 --- a/yt_dlp/extractor/daum.py +++ b/yt_dlp/extractor/daum.py @@ -157,11 +157,8 @@ class DaumListIE(InfoExtractor): query_dict = parse_qs(url) if 'clipid' in query_dict: clip_id = query_dict['clipid'][0] - if self.get_param('noplaylist'): - self.to_screen('Downloading just video %s because of --no-playlist' % clip_id) + if not self._yes_playlist(list_id, clip_id): return self.url_result(DaumClipIE._URL_TEMPLATE % clip_id, 'DaumClip') - else: - self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % list_id) class DaumPlaylistIE(DaumListIE): diff --git a/yt_dlp/extractor/imggaming.py b/yt_dlp/extractor/imggaming.py index 14d3fad55..bae74b290 100644 --- a/yt_dlp/extractor/imggaming.py +++ b/yt_dlp/extractor/imggaming.py @@ -64,10 +64,7 @@ class ImgGamingBaseIE(InfoExtractor): domain, media_type, media_id, playlist_id = self._match_valid_url(url).groups() if playlist_id: - if self.get_param('noplaylist'): - self.to_screen('Downloading just video %s because of --no-playlist' % media_id) - else: - self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % playlist_id) + if self._yes_playlist(playlist_id, media_id): media_type, media_id = 'playlist', playlist_id if media_type == 'playlist': diff --git a/yt_dlp/extractor/litv.py b/yt_dlp/extractor/litv.py index 18d237ef9..73822def1 100644 --- a/yt_dlp/extractor/litv.py +++ b/yt_dlp/extractor/litv.py @@ -7,6 +7,7 @@ from .common import InfoExtractor from ..utils import ( ExtractorError, int_or_none, + traverse_obj, smuggle_url, unsmuggle_url, ) @@ -55,9 +56,6 @@ class LiTVIE(InfoExtractor): episode_title = program_info['title'] content_id = season_list['contentId'] - if prompt: - self.to_screen('Downloading playlist %s - add --no-playlist to just download video %s' % (content_id, video_id)) - all_episodes = [ self.url_result(smuggle_url( self._URL_TEMPLATE % (program_info['contentType'], episode['contentId']), @@ -71,12 +69,6 @@ class LiTVIE(InfoExtractor): video_id = self._match_id(url) - noplaylist = self.get_param('noplaylist') - noplaylist_prompt = True - if 'force_noplaylist' in data: - noplaylist = data['force_noplaylist'] - noplaylist_prompt = False - webpage = self._download_webpage(url, video_id) program_info = self._parse_json(self._search_regex( @@ -84,14 +76,9 @@ class LiTVIE(InfoExtractor): video_id) season_list = list(program_info.get('seasonList', {}).values()) - if season_list: - if not noplaylist: - return self._extract_playlist( - season_list[0], video_id, program_info, - prompt=noplaylist_prompt) - - if noplaylist_prompt: - self.to_screen('Downloading just video %s because of --no-playlist' % video_id) + playlist_id = traverse_obj(season_list, 0, 'contentId') + if self._yes_playlist(playlist_id, video_id, smuggled_data): + return self._extract_playlist(season_list[0], video_id, program_info) # In browsers `getMainUrl` request is always issued. Usually this # endpoint gives the same result as the data embedded in the webpage. diff --git a/yt_dlp/extractor/nba.py b/yt_dlp/extractor/nba.py index 7390ef8bc..359cc52b7 100644 --- a/yt_dlp/extractor/nba.py +++ b/yt_dlp/extractor/nba.py @@ -165,14 +165,10 @@ class NBAWatchIE(NBAWatchBaseIE): def _real_extract(self, url): display_id = self._match_id(url) collection_id = parse_qs(url).get('collection', [None])[0] - if collection_id: - if self.get_param('noplaylist'): - self.to_screen('Downloading just video %s because of --no-playlist' % display_id) - else: - self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % collection_id) - return self.url_result( - 'https://www.nba.com/watch/list/collection/' + collection_id, - NBAWatchCollectionIE.ie_key(), collection_id) + if self._yes_playlist(collection_id, display_id): + return self.url_result( + 'https://www.nba.com/watch/list/collection/' + collection_id, + NBAWatchCollectionIE.ie_key(), collection_id) return self._extract_video('seoName', display_id) diff --git a/yt_dlp/extractor/neteasemusic.py b/yt_dlp/extractor/neteasemusic.py index 7652371b3..57b4774b6 100644 --- a/yt_dlp/extractor/neteasemusic.py +++ b/yt_dlp/extractor/neteasemusic.py @@ -405,17 +405,12 @@ class NetEaseMusicProgramIE(NetEaseMusicBaseIE): name = info['name'] description = info['description'] - if not info['songs'] or self.get_param('noplaylist'): - if info['songs']: - self.to_screen( - 'Downloading just the main audio %s because of --no-playlist' - % info['mainSong']['id']) - + if not self._yes_playlist(info['songs'] and program_id, info['mainSong']['id']): formats = self.extract_formats(info['mainSong']) self._sort_formats(formats) return { - 'id': program_id, + 'id': info['mainSong']['id'], 'title': name, 'description': description, 'creator': info['dj']['brand'], @@ -425,10 +420,6 @@ class NetEaseMusicProgramIE(NetEaseMusicBaseIE): 'formats': formats, } - self.to_screen( - 'Downloading playlist %s - add --no-playlist to just download the main audio %s' - % (program_id, info['mainSong']['id'])) - song_ids = [info['mainSong']['id']] song_ids.extend([song['id'] for song in info['songs']]) entries = [ diff --git a/yt_dlp/extractor/onet.py b/yt_dlp/extractor/onet.py index bf53ea0b0..95177a213 100644 --- a/yt_dlp/extractor/onet.py +++ b/yt_dlp/extractor/onet.py @@ -182,14 +182,9 @@ class OnetChannelIE(OnetBaseIE): video_id = remove_start(current_clip_info['ckmId'], 'mvp:') video_name = url_basename(current_clip_info['url']) - if self.get_param('noplaylist'): - self.to_screen( - 'Downloading just video %s because of --no-playlist' % video_name) + if not self._yes_playlist(channel_id, video_name, playlist_label='channel'): return self._extract_from_id(video_id, webpage) - self.to_screen( - 'Downloading channel %s - add --no-playlist to just download video %s' % ( - channel_id, video_name)) matches = re.findall( r']+href=[\'"](%s[a-z]+/[0-9a-z-]+/[0-9a-z]+)' % self._URL_BASE_RE, webpage) diff --git a/yt_dlp/extractor/sportdeutschland.py b/yt_dlp/extractor/sportdeutschland.py index 94bcaba44..15b488ab7 100644 --- a/yt_dlp/extractor/sportdeutschland.py +++ b/yt_dlp/extractor/sportdeutschland.py @@ -59,12 +59,8 @@ class SportDeutschlandIE(InfoExtractor): videos = asset.get('videos') or [] if len(videos) > 1: playlist_id = parse_qs(url).get('playlistId', [None])[0] - if playlist_id: - if self.get_param('noplaylist'): - videos = [videos[int(playlist_id)]] - self.to_screen('Downloading just a single video because of --no-playlist') - else: - self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % asset_id) + if not self._yes_playlist(playlist_id, asset_id): + videos = [videos[int(playlist_id)]] def entries(): for i, video in enumerate(videos, 1): diff --git a/yt_dlp/extractor/viu.py b/yt_dlp/extractor/viu.py index 1b34c5296..b633df95d 100644 --- a/yt_dlp/extractor/viu.py +++ b/yt_dlp/extractor/viu.py @@ -287,8 +287,7 @@ class ViuOTTIE(InfoExtractor): raise ExtractorError('This video is not available in your region.', expected=True) series_id = video_data.get('series_id') - if not self.get_param('noplaylist') and not idata.get('force_noplaylist'): - self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % series_id) + if self._yes_playlist(series_id, video_id, idata): series = product_data.get('series', {}) product = series.get('product') if product: @@ -308,9 +307,6 @@ class ViuOTTIE(InfoExtractor): return self.playlist_result(entries, series_id, series.get('name'), series.get('description')) - if self.get_param('noplaylist'): - self.to_screen('Downloading just video %s because of --no-playlist' % video_id) - duration_limit = False query = { 'ccs_product_id': video_data['ccs_product_id'], diff --git a/yt_dlp/extractor/vlive.py b/yt_dlp/extractor/vlive.py index 547bdd323..74dc349d5 100644 --- a/yt_dlp/extractor/vlive.py +++ b/yt_dlp/extractor/vlive.py @@ -146,30 +146,24 @@ class VLiveIE(VLiveBaseIE): 'post/v1.0/officialVideoPost-%s', video_id, 'author{nickname},channel{channelCode,channelName},officialVideo{commentCount,exposeStatus,likeCount,playCount,playTime,status,title,type,vodId},playlist{playlistSeq,totalCount,name}') - playlist = post.get('playlist') - if not playlist or self.get_param('noplaylist'): - if playlist: - self.to_screen( - 'Downloading just video %s because of --no-playlist' - % video_id) - + playlist_id = str_or_none(try_get(post, lambda x: x['playlist']['playlistSeq'])) + if not self._yes_playlist(playlist_id, video_id): video = post['officialVideo'] return self._get_vlive_info(post, video, video_id) - else: - playlist_name = playlist.get('name') - playlist_id = str_or_none(playlist.get('playlistSeq')) - playlist_count = str_or_none(playlist.get('totalCount')) - playlist = self._call_api( - 'playlist/v1.0/playlist-%s/posts', playlist_id, 'data', {'limit': playlist_count}) + playlist_name = str_or_none(try_get(post, lambda x: x['playlist']['name'])) + playlist_count = str_or_none(try_get(post, lambda x: x['playlist']['totalCount'])) - entries = [] - for video_data in playlist['data']: - video = video_data.get('officialVideo') - video_id = str_or_none(video.get('videoSeq')) - entries.append(self._get_vlive_info(video_data, video, video_id)) + playlist = self._call_api( + 'playlist/v1.0/playlist-%s/posts', playlist_id, 'data', {'limit': playlist_count}) - return self.playlist_result(entries, playlist_id, playlist_name) + entries = [] + for video_data in playlist['data']: + video = video_data.get('officialVideo') + video_id = str_or_none(video.get('videoSeq')) + entries.append(self._get_vlive_info(video_data, video, video_id)) + + return self.playlist_result(entries, playlist_id, playlist_name) def _get_vlive_info(self, post, video, video_id): def get_common_fields():