]> jfr.im git - yt-dlp.git/blame - yt_dlp/extractor/tvplayer.py
[misc] Add `hatch`, `ruff`, `pre-commit` and improve dev docs (#7409)
[yt-dlp.git] / yt_dlp / extractor / tvplayer.py
CommitLineData
4d32b638 1from .common import InfoExtractor
3d2623a8 2from ..compat import compat_str
3from ..networking.exceptions import HTTPError
4d32b638 4from ..utils import (
e897bd82 5 ExtractorError,
4d32b638 6 extract_attributes,
b364c87c 7 try_get,
4d32b638 8 urlencode_postdata,
4d32b638
RA
9)
10
11
12class TVPlayerIE(InfoExtractor):
13 _VALID_URL = r'https?://(?:www\.)?tvplayer\.com/watch/(?P<id>[^/?#]+)'
14 _TEST = {
15 'url': 'http://tvplayer.com/watch/bbcone',
16 'info_dict': {
17 'id': '89',
18 'ext': 'mp4',
19 'title': r're:^BBC One [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
20 },
21 'params': {
22 # m3u8 download
23 'skip_download': True,
24 }
25 }
26
27 def _real_extract(self, url):
28 display_id = self._match_id(url)
29 webpage = self._download_webpage(url, display_id)
30
31 current_channel = extract_attributes(self._search_regex(
32 r'(<div[^>]+class="[^"]*current-channel[^"]*"[^>]*>)',
33 webpage, 'channel element'))
34 title = current_channel['data-name']
35
b364c87c
S
36 resource_id = current_channel['data-id']
37
4d32b638 38 token = self._search_regex(
b364c87c
S
39 r'data-token=(["\'])(?P<token>(?!\1).+)\1', webpage,
40 'token', group='token')
41
42 context = self._download_json(
43 'https://tvplayer.com/watch/context', display_id,
44 'Downloading JSON context', query={
45 'resource': resource_id,
e1db730d 46 'gen': token,
b364c87c
S
47 })
48
49 validate = context['validate']
50 platform = try_get(
51 context, lambda x: x['platform']['key'], compat_str) or 'firefox'
4d32b638
RA
52
53 try:
54 response = self._download_json(
55 'http://api.tvplayer.com/api/v2/stream/live',
b364c87c 56 display_id, 'Downloading JSON stream', headers={
4d32b638
RA
57 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
58 }, data=urlencode_postdata({
b364c87c 59 'id': resource_id,
4d32b638
RA
60 'service': 1,
61 'platform': platform,
4d32b638
RA
62 'validate': validate,
63 }))['tvplayer']['response']
64 except ExtractorError as e:
3d2623a8 65 if isinstance(e.cause, HTTPError):
4d32b638 66 response = self._parse_json(
3d2623a8 67 e.cause.response.read().decode(), resource_id)['tvplayer']['response']
4d32b638
RA
68 raise ExtractorError(
69 '%s said: %s' % (self.IE_NAME, response['error']), expected=True)
70 raise
71
b364c87c 72 formats = self._extract_m3u8_formats(response['stream'], display_id, 'mp4')
4d32b638
RA
73
74 return {
75 'id': resource_id,
76 'display_id': display_id,
39ca3b5c 77 'title': title,
4d32b638
RA
78 'formats': formats,
79 'is_live': True,
80 }