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
,
52 self
._sort
_formats
(formats
)
56 'title': content
.get('title'),
57 'duration': float_or_none(content
.get('duration')),
58 'series': content
.get('tvShowTitle'),
62 def _real_extract(self
, url
):
63 video_id
= self
._match
_id
(url
)
64 webpage
= self
._download
_webpage
(url
, video_id
)
65 json_data
= self
._parse
_json
(
66 self
._search
_regex
(r
'<script id="state" type="text/plain">(.*)</script>', webpage
, 'json_data'),
69 video_title
= json_data
['views']['default']['page']['title']
70 contentResource
= json_data
['views']['default']['page']['contentResource']
71 content_id
= contentResource
[0]['id']
72 content_ids
= [{'id': id, 'subclip_start': content['start'], 'subclip_end': content['end']}
73 for id, content
in enumerate(contentResource
)]
75 time_of_request
= datetime
.datetime
.now()
76 not_before
= time_of_request
- datetime
.timedelta(minutes
=5)
77 expire
= time_of_request
+ datetime
.timedelta(minutes
=5)
80 content_id
: content_ids
,
82 'secure_delivery': True,
83 'iat': int(time_of_request
.timestamp()),
84 'nbf': int(not_before
.timestamp()),
85 'exp': int(expire
.timestamp()),
87 jwt_token
= jwt_encode_hs256(payload
, self
._ENCRYPTION
_KEY
, headers
={'kid': self._ACCESS_ID}
)
88 videos
= self
._download
_json
(
89 'https://vas-v4.p7s1video.net/4.0/getsources',
90 content_id
, 'Downloading videos JSON', query
={
91 'token': jwt_token
.decode('utf-8')
94 video_id
, videos_data
= list(videos
['data'].items())[0]
95 error_msg
= try_get(videos_data
, lambda x
: x
['error']['title'])
96 if error_msg
== 'Geo check failed':
97 self
.raise_geo_restricted(error_msg
)
99 raise ExtractorError(error_msg
)
101 self
._extract
_video
_info
(url
, contentResource
[video
['id']], video
)
102 for video
in videos_data
]
105 '_type': 'multi_video',
107 'title': video_title
,