2 from __future__
import unicode_literals
6 from .common
import InfoExtractor
15 class ATVAtIE(InfoExtractor
):
16 _VALID_URL
= r
'https?://(?:www\.)?atv\.at/tv/(?:[^/]+/){2,3}(?P<id>.*)'
19 'url': 'https://www.atv.at/tv/bauer-sucht-frau/staffel-18/bauer-sucht-frau/bauer-sucht-frau-staffel-18-folge-3-die-hofwochen',
20 'md5': '3c3b4aaca9f63e32b35e04a9c2515903',
22 'id': 'v-ce9cgn1e70n5-1',
24 'title': 'Bauer sucht Frau - Staffel 18 Folge 3 - Die Hofwochen',
27 'url': 'https://www.atv.at/tv/bauer-sucht-frau/staffel-18/episode-01/bauer-sucht-frau-staffel-18-vorstellungsfolge-1',
28 'only_matching': True,
31 # extracted from bootstrap.js function (search for e.encryption_key and use your browser's debugger)
33 _ENCRYPTION_KEY
= 'Hohnaekeishoogh2omaeghooquooshia'
35 def _extract_video_info(self
, url
, content
, video
):
36 clip_id
= content
.get('splitId', content
['id'])
38 clip_urls
= video
['urls']
39 for protocol
, variant
in clip_urls
.items():
40 source_url
= try_get(variant
, lambda x
: x
['clear']['url'])
43 if protocol
== 'dash':
44 formats
.extend(self
._extract
_mpd
_formats
(
45 source_url
, clip_id
, mpd_id
=protocol
, fatal
=False))
46 elif protocol
== 'hls':
47 formats
.extend(self
._extract
_m
3u8_formats
(
48 source_url
, clip_id
, 'mp4', 'm3u8_native',
49 m3u8_id
=protocol
, fatal
=False))
53 'format_id': protocol
,
55 self
._sort
_formats
(formats
)
59 'title': content
.get('title'),
60 'duration': float_or_none(content
.get('duration')),
61 'series': content
.get('tvShowTitle'),
65 def _real_extract(self
, url
):
66 video_id
= self
._match
_id
(url
)
67 webpage
= self
._download
_webpage
(url
, video_id
)
68 json_data
= self
._parse
_json
(
69 self
._search
_regex
(r
'<script id="state" type="text/plain">(.*)</script>', webpage
, 'json_data'),
72 video_title
= json_data
['views']['default']['page']['title']
73 contentResource
= json_data
['views']['default']['page']['contentResource']
74 content_id
= contentResource
[0]['id']
75 content_ids
= [{'id': id, 'subclip_start': content['start'], 'subclip_end': content['end']}
76 for id, content
in enumerate(contentResource
)]
78 time_of_request
= datetime
.datetime
.now()
79 not_before
= time_of_request
- datetime
.timedelta(minutes
=5)
80 expire
= time_of_request
+ datetime
.timedelta(minutes
=5)
83 content_id
: content_ids
,
85 'secure_delivery': True,
86 'iat': int(time_of_request
.timestamp()),
87 'nbf': int(not_before
.timestamp()),
88 'exp': int(expire
.timestamp()),
90 jwt_token
= jwt_encode_hs256(payload
, self
._ENCRYPTION
_KEY
, headers
={'kid': self._ACCESS_ID}
)
91 videos
= self
._download
_json
(
92 'https://vas-v4.p7s1video.net/4.0/getsources',
93 content_id
, 'Downloading videos JSON', query
={
94 'token': jwt_token
.decode('utf-8')
97 video_id
, videos_data
= list(videos
['data'].items())[0]
98 error_msg
= try_get(videos_data
, lambda x
: x
['error']['title'])
99 if error_msg
== 'Geo check failed':
100 self
.raise_geo_restricted(error_msg
)
102 raise ExtractorError(error_msg
)
104 self
._extract
_video
_info
(url
, contentResource
[video
['id']], video
)
105 for video
in videos_data
]
108 '_type': 'multi_video',
110 'title': video_title
,