3 from .common
import InfoExtractor
12 class ATVAtIE(InfoExtractor
):
13 _VALID_URL
= r
'https?://(?:www\.)?atv\.at/tv/(?:[^/]+/){2,3}(?P<id>.*)'
16 'url': 'https://www.atv.at/tv/bauer-sucht-frau/staffel-18/bauer-sucht-frau/bauer-sucht-frau-staffel-18-folge-3-die-hofwochen',
17 'md5': '3c3b4aaca9f63e32b35e04a9c2515903',
19 'id': 'v-ce9cgn1e70n5-1',
21 'title': 'Bauer sucht Frau - Staffel 18 Folge 3 - Die Hofwochen',
24 'url': 'https://www.atv.at/tv/bauer-sucht-frau/staffel-18/episode-01/bauer-sucht-frau-staffel-18-vorstellungsfolge-1',
25 'only_matching': True,
28 # extracted from bootstrap.js function (search for e.encryption_key and use your browser's debugger)
30 _ENCRYPTION_KEY
= 'Hohnaekeishoogh2omaeghooquooshia'
32 def _extract_video_info(self
, url
, content
, video
):
33 clip_id
= content
.get('splitId', content
['id'])
35 clip_urls
= video
['urls']
36 for protocol
, variant
in clip_urls
.items():
37 source_url
= try_get(variant
, lambda x
: x
['clear']['url'])
40 if protocol
== 'dash':
41 formats
.extend(self
._extract
_mpd
_formats
(
42 source_url
, clip_id
, mpd_id
=protocol
, fatal
=False))
43 elif protocol
== 'hls':
44 formats
.extend(self
._extract
_m
3u8_formats
(
45 source_url
, clip_id
, 'mp4', 'm3u8_native',
46 m3u8_id
=protocol
, fatal
=False))
50 'format_id': protocol
,
55 'title': content
.get('title'),
56 'duration': float_or_none(content
.get('duration')),
57 'series': content
.get('tvShowTitle'),
61 def _real_extract(self
, url
):
62 video_id
= self
._match
_id
(url
)
63 webpage
= self
._download
_webpage
(url
, video_id
)
64 json_data
= self
._parse
_json
(
65 self
._search
_regex
(r
'<script id="state" type="text/plain">(.*)</script>', webpage
, 'json_data'),
68 video_title
= json_data
['views']['default']['page']['title']
69 content_resource
= json_data
['views']['default']['page']['contentResource']
70 content_id
= content_resource
[0]['id']
71 content_ids
= [{'id': id_
, 'subclip_start': content
['start'], 'subclip_end': content
['end']}
72 for id_
, content
in enumerate(content_resource
)]
74 time_of_request
= dt
.datetime
.now()
75 not_before
= time_of_request
- dt
.timedelta(minutes
=5)
76 expire
= time_of_request
+ dt
.timedelta(minutes
=5)
79 content_id
: content_ids
,
81 'secure_delivery': True,
82 'iat': int(time_of_request
.timestamp()),
83 'nbf': int(not_before
.timestamp()),
84 'exp': int(expire
.timestamp()),
86 jwt_token
= jwt_encode_hs256(payload
, self
._ENCRYPTION
_KEY
, headers
={'kid': self
._ACCESS
_ID
})
87 videos
= self
._download
_json
(
88 'https://vas-v4.p7s1video.net/4.0/getsources',
89 content_id
, 'Downloading videos JSON', query
={
90 'token': jwt_token
.decode('utf-8'),
93 video_id
, videos_data
= next(iter(videos
['data'].items()))
94 error_msg
= try_get(videos_data
, lambda x
: x
['error']['title'])
95 if error_msg
== 'Geo check failed':
96 self
.raise_geo_restricted(error_msg
)
98 raise ExtractorError(error_msg
)
100 self
._extract
_video
_info
(url
, content_resource
[video
['id']], video
)
101 for video
in videos_data
]
104 '_type': 'multi_video',
106 'title': video_title
,