tv4.py (4536B)
1 # coding: utf-8 2 from __future__ import unicode_literals 3 4 import re 5 6 from .common import InfoExtractor 7 from ..utils import ( 8 int_or_none, 9 parse_iso8601, 10 ) 11 12 13 class TV4IE(InfoExtractor): 14 IE_DESC = 'tv4.se and tv4play.se' 15 _VALID_URL = r'''(?x)https?://(?:www\.)? 16 (?: 17 tv4\.se/(?:[^/]+)/klipp/(?:.*)-| 18 tv4play\.se/ 19 (?: 20 (?:program|barn)/(?:(?:[^/]+/){1,2}|(?:[^\?]+)\?video_id=)| 21 iframe/video/| 22 film/| 23 sport/| 24 ) 25 )(?P<id>[0-9]+)''' 26 _GEO_COUNTRIES = ['SE'] 27 _TESTS = [ 28 { 29 'url': 'http://www.tv4.se/kalla-fakta/klipp/kalla-fakta-5-english-subtitles-2491650', 30 'md5': 'cb837212f342d77cec06e6dad190e96d', 31 'info_dict': { 32 'id': '2491650', 33 'ext': 'mp4', 34 'title': 'Kalla Fakta 5 (english subtitles)', 35 'thumbnail': r're:^https?://.*\.jpg$', 36 'timestamp': int, 37 'upload_date': '20131125', 38 }, 39 }, 40 { 41 'url': 'http://www.tv4play.se/iframe/video/3054113', 42 'md5': 'cb837212f342d77cec06e6dad190e96d', 43 'info_dict': { 44 'id': '3054113', 45 'ext': 'mp4', 46 'title': 'Så här jobbar ficktjuvarna - se avslöjande bilder', 47 'thumbnail': r're:^https?://.*\.jpg$', 48 'description': 'Unika bilder avslöjar hur turisternas fickor vittjas mitt på Stockholms central. Två experter på ficktjuvarna avslöjar knepen du ska se upp för.', 49 'timestamp': int, 50 'upload_date': '20150130', 51 }, 52 }, 53 { 54 'url': 'http://www.tv4play.se/sport/3060959', 55 'only_matching': True, 56 }, 57 { 58 'url': 'http://www.tv4play.se/film/2378136', 59 'only_matching': True, 60 }, 61 { 62 'url': 'http://www.tv4play.se/barn/looney-tunes?video_id=3062412', 63 'only_matching': True, 64 }, 65 { 66 'url': 'http://www.tv4play.se/program/farang/3922081', 67 'only_matching': True, 68 }, 69 { 70 'url': 'https://www.tv4play.se/program/nyheterna/avsnitt/13315940', 71 'only_matching': True, 72 } 73 ] 74 75 def _real_extract(self, url): 76 video_id = self._match_id(url) 77 78 info = self._download_json( 79 'https://playback-api.b17g.net/asset/%s' % video_id, 80 video_id, 'Downloading video info JSON', query={ 81 'service': 'tv4', 82 'device': 'browser', 83 'protocol': 'hls,dash', 84 'drm': 'widevine', 85 })['metadata'] 86 87 title = info['title'] 88 89 manifest_url = self._download_json( 90 'https://playback-api.b17g.net/media/' + video_id, 91 video_id, query={ 92 'service': 'tv4', 93 'device': 'browser', 94 'protocol': 'hls', 95 })['playbackItem']['manifestUrl'] 96 formats = self._extract_m3u8_formats( 97 manifest_url, video_id, 'mp4', 98 'm3u8_native', m3u8_id='hls', fatal=False) 99 formats.extend(self._extract_mpd_formats( 100 manifest_url.replace('.m3u8', '.mpd'), 101 video_id, mpd_id='dash', fatal=False)) 102 formats.extend(self._extract_f4m_formats( 103 manifest_url.replace('.m3u8', '.f4m'), 104 video_id, f4m_id='hds', fatal=False)) 105 formats.extend(self._extract_ism_formats( 106 re.sub(r'\.ism/.*?\.m3u8', r'.ism/Manifest', manifest_url), 107 video_id, ism_id='mss', fatal=False)) 108 109 if not formats and info.get('is_geo_restricted'): 110 self.raise_geo_restricted(countries=self._GEO_COUNTRIES) 111 112 self._sort_formats(formats) 113 114 return { 115 'id': video_id, 116 'title': title, 117 'formats': formats, 118 # 'subtitles': subtitles, 119 'description': info.get('description'), 120 'timestamp': parse_iso8601(info.get('broadcast_date_time')), 121 'duration': int_or_none(info.get('duration')), 122 'thumbnail': info.get('image'), 123 'is_live': info.get('isLive') is True, 124 'series': info.get('seriesTitle'), 125 'season_number': int_or_none(info.get('seasonNumber')), 126 'episode': info.get('episodeTitle'), 127 'episode_number': int_or_none(info.get('episodeNumber')), 128 }