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