sportdeutschland.py (4320B)
1 # coding: utf-8 2 from __future__ import unicode_literals 3 4 from .common import InfoExtractor 5 from ..compat import ( 6 compat_parse_qs, 7 compat_urllib_parse_urlparse, 8 ) 9 from ..utils import ( 10 clean_html, 11 float_or_none, 12 int_or_none, 13 parse_iso8601, 14 strip_or_none, 15 try_get, 16 ) 17 18 19 class SportDeutschlandIE(InfoExtractor): 20 _VALID_URL = r'https?://sportdeutschland\.tv/(?P<id>(?:[^/]+/)?[^?#/&]+)' 21 _TESTS = [{ 22 'url': 'https://sportdeutschland.tv/badminton/re-live-deutsche-meisterschaften-2020-halbfinals?playlistId=0', 23 'info_dict': { 24 'id': '5318cac0275701382770543d7edaf0a0', 25 'ext': 'mp4', 26 'title': 'Re-live: Deutsche Meisterschaften 2020 - Halbfinals - Teil 1', 27 'duration': 16106.36, 28 }, 29 'params': { 30 'noplaylist': True, 31 # m3u8 download 32 'skip_download': True, 33 }, 34 }, { 35 'url': 'https://sportdeutschland.tv/badminton/re-live-deutsche-meisterschaften-2020-halbfinals?playlistId=0', 36 'info_dict': { 37 'id': 'c6e2fdd01f63013854c47054d2ab776f', 38 'title': 'Re-live: Deutsche Meisterschaften 2020 - Halbfinals', 39 'description': 'md5:5263ff4c31c04bb780c9f91130b48530', 40 'duration': 31397, 41 }, 42 'playlist_count': 2, 43 }, { 44 'url': 'https://sportdeutschland.tv/freeride-world-tour-2021-fieberbrunn-oesterreich', 45 'only_matching': True, 46 }] 47 48 def _real_extract(self, url): 49 display_id = self._match_id(url) 50 data = self._download_json( 51 'https://backend.sportdeutschland.tv/api/permalinks/' + display_id, 52 display_id, query={'access_token': 'true'}) 53 asset = data['asset'] 54 title = (asset.get('title') or asset['label']).strip() 55 asset_id = asset.get('id') or asset.get('uuid') 56 info = { 57 'id': asset_id, 58 'title': title, 59 'description': clean_html(asset.get('body') or asset.get('description')) or asset.get('teaser'), 60 'duration': int_or_none(asset.get('seconds')), 61 } 62 videos = asset.get('videos') or [] 63 if len(videos) > 1: 64 playlist_id = compat_parse_qs(compat_urllib_parse_urlparse(url).query).get('playlistId', [None])[0] 65 if playlist_id: 66 if self._downloader.params.get('noplaylist'): 67 videos = [videos[int(playlist_id)]] 68 self.to_screen('Downloading just a single video because of --no-playlist') 69 else: 70 self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % asset_id) 71 72 def entries(): 73 for i, video in enumerate(videos, 1): 74 video_id = video.get('uuid') 75 video_url = video.get('url') 76 if not (video_id and video_url): 77 continue 78 formats = self._extract_m3u8_formats( 79 video_url.replace('.smil', '.m3u8'), video_id, 'mp4', fatal=False) 80 if not formats: 81 continue 82 yield { 83 'id': video_id, 84 'formats': formats, 85 'title': title + ' - ' + (video.get('label') or 'Teil %d' % i), 86 'duration': float_or_none(video.get('duration')), 87 } 88 info.update({ 89 '_type': 'multi_video', 90 'entries': entries(), 91 }) 92 else: 93 formats = self._extract_m3u8_formats( 94 videos[0]['url'].replace('.smil', '.m3u8'), asset_id, 'mp4') 95 section_title = strip_or_none(try_get(data, lambda x: x['section']['title'])) 96 info.update({ 97 'formats': formats, 98 'display_id': asset.get('permalink'), 99 'thumbnail': try_get(asset, lambda x: x['images'][0]), 100 'categories': [section_title] if section_title else None, 101 'view_count': int_or_none(asset.get('views')), 102 'is_live': asset.get('is_live') is True, 103 'timestamp': parse_iso8601(asset.get('date') or asset.get('published_at')), 104 }) 105 return info