]>
Commit | Line | Data |
---|---|---|
1 | import re | |
2 | ||
3 | from .youtube import YoutubeIE | |
4 | from .zdf import ZDFBaseIE | |
5 | from ..utils import ( | |
6 | int_or_none, | |
7 | merge_dicts, | |
8 | try_get, | |
9 | unified_timestamp, | |
10 | urljoin, | |
11 | ) | |
12 | ||
13 | ||
14 | class PhoenixIE(ZDFBaseIE): | |
15 | IE_NAME = 'phoenix.de' | |
16 | _VALID_URL = r'https?://(?:www\.)?phoenix\.de/(?:[^/]+/)*[^/?#&]*-a-(?P<id>\d+)\.html' | |
17 | _TESTS = [{ | |
18 | # Same as https://www.zdf.de/politik/phoenix-sendungen/wohin-fuehrt-der-protest-in-der-pandemie-100.html | |
19 | 'url': 'https://www.phoenix.de/sendungen/ereignisse/corona-nachgehakt/wohin-fuehrt-der-protest-in-der-pandemie-a-2050630.html', | |
20 | 'md5': '34ec321e7eb34231fd88616c65c92db0', | |
21 | 'info_dict': { | |
22 | 'id': '210222_phx_nachgehakt_corona_protest', | |
23 | 'ext': 'mp4', | |
24 | 'title': 'Wohin führt der Protest in der Pandemie?', | |
25 | 'description': 'md5:7d643fe7f565e53a24aac036b2122fbd', | |
26 | 'duration': 1691, | |
27 | 'timestamp': 1613902500, | |
28 | 'upload_date': '20210221', | |
29 | 'uploader': 'Phoenix', | |
30 | 'series': 'corona nachgehakt', | |
31 | 'episode': 'Wohin führt der Protest in der Pandemie?', | |
32 | }, | |
33 | }, { | |
34 | # Youtube embed | |
35 | 'url': 'https://www.phoenix.de/sendungen/gespraeche/phoenix-streitgut-brennglas-corona-a-1965505.html', | |
36 | 'info_dict': { | |
37 | 'id': 'hMQtqFYjomk', | |
38 | 'ext': 'mp4', | |
39 | 'title': 'phoenix streitgut: Brennglas Corona - Wie gerecht ist unsere Gesellschaft?', | |
40 | 'description': 'md5:ac7a02e2eb3cb17600bc372e4ab28fdd', | |
41 | 'duration': 3509, | |
42 | 'upload_date': '20201219', | |
43 | 'uploader': 'phoenix', | |
44 | 'uploader_id': 'phoenix', | |
45 | }, | |
46 | 'params': { | |
47 | 'skip_download': True, | |
48 | }, | |
49 | }, { | |
50 | 'url': 'https://www.phoenix.de/entwicklungen-in-russland-a-2044720.html', | |
51 | 'only_matching': True, | |
52 | }, { | |
53 | # no media | |
54 | 'url': 'https://www.phoenix.de/sendungen/dokumentationen/mit-dem-jumbo-durch-die-nacht-a-89625.html', | |
55 | 'only_matching': True, | |
56 | }, { | |
57 | # Same as https://www.zdf.de/politik/phoenix-sendungen/die-gesten-der-maechtigen-100.html | |
58 | 'url': 'https://www.phoenix.de/sendungen/dokumentationen/gesten-der-maechtigen-i-a-89468.html?ref=suche', | |
59 | 'only_matching': True, | |
60 | }] | |
61 | ||
62 | def _real_extract(self, url): | |
63 | article_id = self._match_id(url) | |
64 | ||
65 | article = self._download_json( | |
66 | f'https://www.phoenix.de/response/id/{article_id}', article_id, | |
67 | 'Downloading article JSON') | |
68 | ||
69 | video = article['absaetze'][0] | |
70 | title = video.get('titel') or article.get('subtitel') | |
71 | ||
72 | if video.get('typ') == 'video-youtube': | |
73 | video_id = video['id'] | |
74 | return self.url_result( | |
75 | video_id, ie=YoutubeIE.ie_key(), video_id=video_id, | |
76 | video_title=title) | |
77 | ||
78 | video_id = str(video.get('basename') or video.get('content')) | |
79 | ||
80 | details = self._download_json( | |
81 | 'https://www.phoenix.de/php/mediaplayer/data/beitrags_details.php', | |
82 | video_id, 'Downloading details JSON', query={ | |
83 | 'ak': 'web', | |
84 | 'ptmd': 'true', | |
85 | 'id': video_id, | |
86 | 'profile': 'player2', | |
87 | }) | |
88 | ||
89 | title = title or details['title'] | |
90 | content_id = details['tracking']['nielsen']['content']['assetid'] | |
91 | ||
92 | info = self._extract_ptmd( | |
93 | f'https://tmd.phoenix.de/tmd/2/ngplayer_2_3/vod/ptmd/phoenix/{content_id}', | |
94 | content_id, None, url) | |
95 | ||
96 | duration = int_or_none(try_get( | |
97 | details, lambda x: x['tracking']['nielsen']['content']['length'])) | |
98 | timestamp = unified_timestamp(details.get('editorialDate')) | |
99 | series = try_get( | |
100 | details, lambda x: x['tracking']['nielsen']['content']['program'], | |
101 | str) | |
102 | episode = title if details.get('contentType') == 'episode' else None | |
103 | ||
104 | thumbnails = [] | |
105 | teaser_images = try_get(details, lambda x: x['teaserImageRef']['layouts'], dict) or {} | |
106 | for thumbnail_key, thumbnail_url in teaser_images.items(): | |
107 | thumbnail_url = urljoin(url, thumbnail_url) | |
108 | if not thumbnail_url: | |
109 | continue | |
110 | thumbnail = { | |
111 | 'url': thumbnail_url, | |
112 | } | |
113 | m = re.match('^([0-9]+)x([0-9]+)$', thumbnail_key) | |
114 | if m: | |
115 | thumbnail['width'] = int(m.group(1)) | |
116 | thumbnail['height'] = int(m.group(2)) | |
117 | thumbnails.append(thumbnail) | |
118 | ||
119 | return merge_dicts(info, { | |
120 | 'id': content_id, | |
121 | 'title': title, | |
122 | 'description': details.get('leadParagraph'), | |
123 | 'duration': duration, | |
124 | 'thumbnails': thumbnails, | |
125 | 'timestamp': timestamp, | |
126 | 'uploader': details.get('tvService'), | |
127 | 'series': series, | |
128 | 'episode': episode, | |
129 | }) |