]>
Commit | Line | Data |
---|---|---|
e496fa50 RA |
1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
4 | from .common import InfoExtractor | |
d347b52b | 5 | from ..utils import unified_timestamp |
fb9c36c4 | 6 | import re |
e496fa50 RA |
7 | |
8 | ||
9 | class URPlayIE(InfoExtractor): | |
efb62429 RA |
10 | _VALID_URL = r'https?://(?:www\.)?ur(?:play|skola)\.se/(?:program|Produkter)/(?P<id>[0-9]+)' |
11 | _TESTS = [{ | |
d347b52b | 12 | 'url': 'https://urplay.se/program/203704-ur-samtiden-livet-universum-och-rymdens-markliga-musik-om-vetenskap-kritiskt-tankande-och-motstand', |
13 | 'md5': 'ff5b0c89928f8083c74bbd5099c9292d', | |
14 | 'info_dict': { | |
15 | 'id': '203704', | |
16 | 'ext': 'mp4', | |
fb9c36c4 | 17 | 'title': 'Om vetenskap, kritiskt tänkande och motstånd', |
d347b52b | 18 | 'description': 'md5:5344508a52aa78c1ced6c1b8b9e44e9a', |
fb9c36c4 | 19 | 'timestamp': 1513292400, |
20 | 'upload_date': '20171214', | |
d347b52b | 21 | }, |
22 | }, { | |
23 | 'url': 'https://urskola.se/Produkter/190031-Tripp-Trapp-Trad-Sovkudde', | |
e496fa50 RA |
24 | 'info_dict': { |
25 | 'id': '190031', | |
26 | 'ext': 'mp4', | |
27 | 'title': 'Tripp, Trapp, Träd : Sovkudde', | |
28 | 'description': 'md5:b86bffdae04a7e9379d1d7e5947df1d1', | |
d347b52b | 29 | 'timestamp': 1440093600, |
30 | 'upload_date': '20150820', | |
efb62429 RA |
31 | }, |
32 | }, { | |
33 | 'url': 'http://urskola.se/Produkter/155794-Smasagor-meankieli-Grodan-i-vida-varlden', | |
34 | 'only_matching': True, | |
35 | }] | |
e496fa50 RA |
36 | |
37 | def _real_extract(self, url): | |
38 | video_id = self._match_id(url) | |
39 | ||
40 | webpage = self._download_webpage(url, video_id) | |
fb9c36c4 | 41 | urplayer_data = re.sub(""", "\"", self._search_regex( |
42 | r'components\/Player\/Player\" data-react-props=\"({.+?})\"', | |
43 | webpage, 'urplayer data')) | |
44 | urplayer_data = self._parse_json(urplayer_data, video_id) | |
45 | for i in range(len(urplayer_data['accessibleEpisodes'])): | |
46 | if urplayer_data.get('accessibleEpisodes', {})[i].get('id') == int(video_id): | |
47 | urplayer_data = urplayer_data['accessibleEpisodes'][i] | |
48 | break | |
e496fa50 | 49 | |
fb9c36c4 | 50 | host = self._download_json('http://streaming-loadbalancer.ur.se/loadbalancer.json', video_id)['redirect'] |
e496fa50 | 51 | formats = [] |
fb9c36c4 | 52 | urplayer_streams = urplayer_data.get("streamingInfo") |
53 | for quality in ('sd'), ('hd'): | |
54 | location = (urplayer_streams.get("raw", {}).get(quality, {}).get("location") | |
55 | or urplayer_streams.get("sweComplete", {}).get(quality, {}).get("location")) | |
56 | if location: | |
efb62429 | 57 | formats.extend(self._extract_wowza_formats( |
fb9c36c4 | 58 | 'http://%s/%s/playlist.m3u8' % (host, location), video_id, |
59 | skip_protocols=['f4m', 'rtmp', 'rtsp'])) | |
e496fa50 | 60 | self._sort_formats(formats) |
e496fa50 | 61 | subtitles = {} |
fb9c36c4 | 62 | subs = urplayer_streams.get("sweComplete", {}).get("tt", {}).get("location") |
63 | if subs: | |
64 | subtitles.setdefault('Svenska', []).append({ | |
65 | 'url': subs, | |
e496fa50 RA |
66 | }) |
67 | ||
68 | return { | |
69 | 'id': video_id, | |
70 | 'title': urplayer_data['title'], | |
71 | 'description': self._og_search_description(webpage), | |
fb9c36c4 | 72 | 'thumbnail': urplayer_data.get('image', {}).get('1280x720'), |
73 | 'timestamp': unified_timestamp(self._html_search_meta(('uploadDate', 'schema:uploadDate'), | |
74 | webpage, 'timestamp')), | |
75 | 'series': urplayer_data.get('seriesTitle'), | |
e496fa50 RA |
76 | 'subtitles': subtitles, |
77 | 'formats': formats, | |
4d86d200 | 78 | } |