From 1f11ae44112b7174f324bfb0e52ad50034b0e33f Mon Sep 17 00:00:00 2001 From: AndroKev Date: Mon, 12 Oct 2015 12:44:59 +0200 Subject: [PATCH 1/3] Update nowtv.py Now you can download a season or the full serie! example: http://www.nowtv.at/rtl/das-supertalent/list/free-staffel-8 http://www.nowtv.at/rtl/das-supertalent both works now and download the season 8 (url1) or the whole serie (url2) --- youtube_dl/extractor/nowtv.py | 108 ++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/youtube_dl/extractor/nowtv.py b/youtube_dl/extractor/nowtv.py index b0bdffc4e..fada80673 100644 --- a/youtube_dl/extractor/nowtv.py +++ b/youtube_dl/extractor/nowtv.py @@ -12,10 +12,8 @@ from ..utils import ( remove_start, ) - class NowTVIE(InfoExtractor): - _VALID_URL = r'https?://(?:www\.)?nowtv\.(?:de|at|ch)/(?:rtl|rtl2|rtlnitro|superrtl|ntv|vox)/(?P.+?)/(?:player|preview)' - + _VALID_URL = r'https?://(?:www\.)?nowtv\.(?:de|at|ch)/(?:rtl|rtl2|rtlnitro|superrtl|ntv|vox)/(?P.+?)$' _TESTS = [{ # rtl 'url': 'http://www.nowtv.de/rtl/bauer-sucht-frau/die-neuen-bauern-und-eine-hochzeit/player', @@ -34,6 +32,18 @@ class NowTVIE(InfoExtractor): # rtmp download 'skip_download': True, }, + # rtl + 'url': 'http://www.nowtv.at/rtl/stern-tv/list/aktuell', + 'info_dict': { + 'title': 'stern TV', + 'id': '2385', + }, + # rtl + 'url': 'http://www.nowtv.at/rtl/das-supertalent/list/free-staffel-8', + 'info_dict': { + 'title': 'Das Supertalent', + 'id': '46', + }, }, { # rtl2 'url': 'http://www.nowtv.de/rtl2/berlin-tag-nacht/berlin-tag-nacht-folge-934/player', @@ -138,12 +148,76 @@ class NowTVIE(InfoExtractor): def _real_extract(self, url): display_id = self._match_id(url) display_id_split = display_id.split('/') - if len(display_id) > 2: - display_id = '/'.join((display_id_split[0], display_id_split[-1])) + if url.endswith('/player') or url.endswith('/preview'): + if len(display_id) > 2: + display_id = '/'.join((display_id_split[0], display_id_split[-2])) - info = self._download_json( - 'https://api.nowtv.de/v3/movies/%s?fields=id,title,free,geoblocked,articleLong,articleShort,broadcastStartDate,seoUrl,duration,format,files' % display_id, - display_id) + info = self._download_json( + 'https://api.nowtv.de/v3/movies/%s?fields=id,title,free,geoblocked,articleLong,articleShort,broadcastStartDate,seoUrl,duration,format,files' % display_id, + display_id) + + video_id, title, description, timestamp, duration, formats = self.episode_details(info) + + f = info.get('format', {}) + thumbnail = f.get('defaultImage169Format') or f.get('defaultImage169Logo') + + return { + 'id': video_id, + 'display_id': display_id, + 'title': title, + 'description': description, + 'thumbnail': thumbnail, + 'timestamp': timestamp, + 'duration': duration, + 'formats': formats, + } + else: + if len(display_id_split) > 1: + display_id = display_id_split[0] + season = display_id_split[2] + + info = self._download_json( + 'https://api.nowtv.de/v3/formats/seo?fields=id,title,defaultImage169Format,defaultImage169Logo,formatTabs.*,formatTabs.formatTabPages.container.movies.*,formatTabs.formatTabPages.container.movies.files&name=%s.php' % display_id, + display_id) + + playlist_id = info['id'] + playlist_title = info['title'] + thumbnail = info.get('defaultImage169Format') or info.get('defaultImage169Logo') + + files = info['formatTabs'] + + videos = [] + playlists = [] + + for season_item in files['items']: + try: + if season != season_item['seoheadline']: + continue + except: + pass + + for items in season_item['formatTabPages']['items']: + try: + for episode in items['container']['movies']['items']: + + video_id, title, description, timestamp, duration, formats = self.episode_details(episode) + + videos.append({ + 'id': video_id, + 'display_id': display_id, + 'title': "%s - %s" % (playlist_title, title), + 'description': description, + 'thumbnail': thumbnail, + 'timestamp': timestamp, + 'duration': duration, + 'formats': formats, + }) + except: + continue + + return self.playlist_result(videos, playlist_id, playlist_title) + + def episode_details(self, info): video_id = compat_str(info['id']) @@ -173,21 +247,9 @@ class NowTVIE(InfoExtractor): }) self._sort_formats(formats) - title = info['title'] description = info.get('articleLong') or info.get('articleShort') timestamp = parse_iso8601(info.get('broadcastStartDate'), ' ') duration = parse_duration(info.get('duration')) - - f = info.get('format', {}) - thumbnail = f.get('defaultImage169Format') or f.get('defaultImage169Logo') - - return { - 'id': video_id, - 'display_id': display_id, - 'title': title, - 'description': description, - 'thumbnail': thumbnail, - 'timestamp': timestamp, - 'duration': duration, - 'formats': formats, - } + title = info['title'] + # title = "S%dE%d - %s" % (episode['season'], episode['episode'], episode['title']) + return video_id, title, description, timestamp, duration, formats From 46862bd0f9ccc0a99a45acc5b6ba9d4be045833a Mon Sep 17 00:00:00 2001 From: AndroKev Date: Sun, 18 Oct 2015 21:52:46 +0200 Subject: [PATCH 2/3] seperate code in seperate function --> easier to read and unterstand --- youtube_dl/extractor/nowtv.py | 128 ++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 61 deletions(-) diff --git a/youtube_dl/extractor/nowtv.py b/youtube_dl/extractor/nowtv.py index fada80673..6e09602b4 100644 --- a/youtube_dl/extractor/nowtv.py +++ b/youtube_dl/extractor/nowtv.py @@ -146,76 +146,81 @@ class NowTVIE(InfoExtractor): }] def _real_extract(self, url): + url = url.split('?')[0] display_id = self._match_id(url) display_id_split = display_id.split('/') - if url.endswith('/player') or url.endswith('/preview'): - if len(display_id) > 2: + + if 'player' in url or 'preview' in url: # then the link is a direct videoclip-link! + if len(display_id_split) > 2: display_id = '/'.join((display_id_split[0], display_id_split[-2])) - - info = self._download_json( - 'https://api.nowtv.de/v3/movies/%s?fields=id,title,free,geoblocked,articleLong,articleShort,broadcastStartDate,seoUrl,duration,format,files' % display_id, - display_id) - - video_id, title, description, timestamp, duration, formats = self.episode_details(info) - - f = info.get('format', {}) - thumbnail = f.get('defaultImage169Format') or f.get('defaultImage169Logo') - - return { - 'id': video_id, - 'display_id': display_id, - 'title': title, - 'description': description, - 'thumbnail': thumbnail, - 'timestamp': timestamp, - 'duration': duration, - 'formats': formats, - } + return self._extract_videoclip(display_id) else: + season = None if len(display_id_split) > 1: display_id = display_id_split[0] season = display_id_split[2] + return self._extract_playlist(display_id, season) - info = self._download_json( - 'https://api.nowtv.de/v3/formats/seo?fields=id,title,defaultImage169Format,defaultImage169Logo,formatTabs.*,formatTabs.formatTabPages.container.movies.*,formatTabs.formatTabPages.container.movies.files&name=%s.php' % display_id, - display_id) - - playlist_id = info['id'] - playlist_title = info['title'] - thumbnail = info.get('defaultImage169Format') or info.get('defaultImage169Logo') - - files = info['formatTabs'] - - videos = [] - playlists = [] + def _extract_videoclip(self, display_id): + info = self._download_json( + 'https://api.nowtv.de/v3/movies/%s?fields=id,title,season,episode,free,geoblocked,articleLong,articleShort,broadcastStartDate,seoUrl,duration,format,files' % display_id, + display_id) - for season_item in files['items']: + video_id, title, title_long, description, timestamp, duration, formats = self.episode_details(info) + + f = info.get('format', {}) + thumbnail = f.get('defaultImage169Format') or f.get('defaultImage169Logo') + + return { + 'id': video_id, + 'display_id': display_id, + 'title': '%s - %s' % (info['format']['title'], title), + 'description': description, + 'thumbnail': thumbnail, + 'timestamp': timestamp, + 'duration': duration, + 'formats': formats, + } + + def _extract_playlist(self, display_id, season): + info = self._download_json( + 'https://api.nowtv.de/v3/formats/seo?fields=id,title,defaultImage169Format,defaultImage169Logo,formatTabs.*,formatTabs.formatTabPages.container.movies.*,formatTabs.formatTabPages.container.movies.files&name=%s.php' % display_id, + display_id) + + playlist_id = info['id'] + playlist_title = info['title'] + thumbnail = info.get('defaultImage169Format') or info.get('defaultImage169Logo') + + files = info['formatTabs'] + + videos = [] + playlists = [] + + for season_item in files['items']: + if season: + if season != season_item['seoheadline']: + continue + + for items in season_item['formatTabPages']['items']: try: - if season != season_item['seoheadline']: - continue - except: - pass - - for items in season_item['formatTabPages']['items']: - try: - for episode in items['container']['movies']['items']: - - video_id, title, description, timestamp, duration, formats = self.episode_details(episode) + for episode in items['container']['movies']['items']: - videos.append({ - 'id': video_id, - 'display_id': display_id, - 'title': "%s - %s" % (playlist_title, title), - 'description': description, - 'thumbnail': thumbnail, - 'timestamp': timestamp, - 'duration': duration, - 'formats': formats, - }) - except: - continue - - return self.playlist_result(videos, playlist_id, playlist_title) + video_id, title, title_long, description, timestamp, duration, formats = self.episode_details(episode) + + videos.append({ + 'id': video_id, + 'display_id': display_id, + 'title': title_long, + 'description': description, + 'thumbnail': thumbnail, + 'timestamp': timestamp, + 'duration': duration, + 'formats': formats, + }) + except: + continue + + return self.playlist_result(videos.reverse(), playlist_id, playlist_title) def episode_details(self, info): @@ -251,5 +256,6 @@ class NowTVIE(InfoExtractor): timestamp = parse_iso8601(info.get('broadcastStartDate'), ' ') duration = parse_duration(info.get('duration')) title = info['title'] - # title = "S%dE%d - %s" % (episode['season'], episode['episode'], episode['title']) - return video_id, title, description, timestamp, duration, formats + title_long = "S%sE%s - %s" % (info['season'], info['episode'], title) + + return video_id, title, title_long, description, timestamp, duration, formats From 257abcbd3c6b8a4525592878619912953748b725 Mon Sep 17 00:00:00 2001 From: AndroKev Date: Fri, 30 Oct 2015 10:16:38 +0100 Subject: [PATCH 3/3] Playlist order chaged (oldest first, newest last) --- youtube_dl/extractor/nowtv.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/youtube_dl/extractor/nowtv.py b/youtube_dl/extractor/nowtv.py index 6e09602b4..d2f2707ec 100644 --- a/youtube_dl/extractor/nowtv.py +++ b/youtube_dl/extractor/nowtv.py @@ -200,7 +200,6 @@ class NowTVIE(InfoExtractor): if season: if season != season_item['seoheadline']: continue - for items in season_item['formatTabPages']['items']: try: for episode in items['container']['movies']['items']: @@ -220,7 +219,7 @@ class NowTVIE(InfoExtractor): except: continue - return self.playlist_result(videos.reverse(), playlist_id, playlist_title) + return self.playlist_result(reversed(videos), playlist_id, playlist_title) def episode_details(self, info):