]>
Commit | Line | Data |
---|---|---|
1 | import json | |
2 | ||
3 | from .common import InfoExtractor | |
4 | from ..utils import ( | |
5 | int_or_none, | |
6 | parse_iso8601, | |
7 | try_get, | |
8 | ) | |
9 | ||
10 | ||
11 | class TF1IE(InfoExtractor): | |
12 | _VALID_URL = r'https?://(?:www\.)?tf1\.fr/[^/]+/(?P<program_slug>[^/]+)/videos/(?P<id>[^/?&#]+)\.html' | |
13 | _TESTS = [{ | |
14 | 'url': 'https://www.tf1.fr/tmc/quotidien-avec-yann-barthes/videos/quotidien-premiere-partie-11-juin-2019.html', | |
15 | 'info_dict': { | |
16 | 'id': '13641379', | |
17 | 'ext': 'mp4', | |
18 | 'title': 'md5:f392bc52245dc5ad43771650c96fb620', | |
19 | 'description': 'md5:a02cdb217141fb2d469d6216339b052f', | |
20 | 'upload_date': '20190611', | |
21 | 'timestamp': 1560273989, | |
22 | 'duration': 1738, | |
23 | 'series': 'Quotidien avec Yann Barthès', | |
24 | 'tags': ['intégrale', 'quotidien', 'Replay'], | |
25 | }, | |
26 | 'params': { | |
27 | # Sometimes wat serves the whole file with the --test option | |
28 | 'skip_download': True, | |
29 | }, | |
30 | }, { | |
31 | 'url': 'http://www.tf1.fr/tf1/koh-lanta/videos/replay-koh-lanta-22-mai-2015.html', | |
32 | 'only_matching': True, | |
33 | }, { | |
34 | 'url': 'http://www.tf1.fr/hd1/documentaire/videos/mylene-farmer-d-une-icone.html', | |
35 | 'only_matching': True, | |
36 | }] | |
37 | ||
38 | def _real_extract(self, url): | |
39 | program_slug, slug = self._match_valid_url(url).groups() | |
40 | video = self._download_json( | |
41 | 'https://www.tf1.fr/graphql/web', slug, query={ | |
42 | 'id': '9b80783950b85247541dd1d851f9cc7fa36574af015621f853ab111a679ce26f', | |
43 | 'variables': json.dumps({ | |
44 | 'programSlug': program_slug, | |
45 | 'slug': slug, | |
46 | }) | |
47 | })['data']['videoBySlug'] | |
48 | wat_id = video['streamId'] | |
49 | ||
50 | tags = [] | |
51 | for tag in (video.get('tags') or []): | |
52 | label = tag.get('label') | |
53 | if not label: | |
54 | continue | |
55 | tags.append(label) | |
56 | ||
57 | decoration = video.get('decoration') or {} | |
58 | ||
59 | thumbnails = [] | |
60 | for source in (try_get(decoration, lambda x: x['image']['sources'], list) or []): | |
61 | source_url = source.get('url') | |
62 | if not source_url: | |
63 | continue | |
64 | thumbnails.append({ | |
65 | 'url': source_url, | |
66 | 'width': int_or_none(source.get('width')), | |
67 | }) | |
68 | ||
69 | return { | |
70 | '_type': 'url_transparent', | |
71 | 'id': wat_id, | |
72 | 'url': 'wat:' + wat_id, | |
73 | 'title': video.get('title'), | |
74 | 'thumbnails': thumbnails, | |
75 | 'description': decoration.get('description'), | |
76 | 'timestamp': parse_iso8601(video.get('date')), | |
77 | 'duration': int_or_none(try_get(video, lambda x: x['publicPlayingInfos']['duration'])), | |
78 | 'tags': tags, | |
79 | 'series': decoration.get('programLabel'), | |
80 | 'season_number': int_or_none(video.get('season')), | |
81 | 'episode_number': int_or_none(video.get('episode')), | |
82 | } |