]>
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': 'https://www.tf1.fr/tmc/burger-quiz/videos/burger-quiz-du-19-aout-2023-s03-episode-21-85585666.html', | |
32 | 'info_dict': { | |
33 | 'id': '14010600', | |
34 | 'ext': 'mp4', | |
35 | 'title': 'Burger Quiz - S03 EP21 avec Eye Haidara, Anne Depétrini, Jonathan Zaccaï et Pio Marmaï', | |
36 | 'thumbnail': 'https://photos.tf1.fr/1280/720/burger-quiz-11-9adb79-0@1x.jpg', | |
37 | 'description': 'Manu Payet recevra Eye Haidara, Anne Depétrini, Jonathan Zaccaï et Pio Marmaï.', | |
38 | 'upload_date': '20230819', | |
39 | 'timestamp': 1692469471, | |
40 | 'season_number': 3, | |
41 | 'series': 'Burger Quiz', | |
42 | 'episode_number': 21, | |
43 | 'season': 'Season 3', | |
44 | 'tags': 'count:13', | |
45 | 'episode': 'Episode 21', | |
46 | 'duration': 2312 | |
47 | }, | |
48 | 'params': {'skip_download': 'm3u8'}, | |
49 | }, { | |
50 | 'url': 'http://www.tf1.fr/tf1/koh-lanta/videos/replay-koh-lanta-22-mai-2015.html', | |
51 | 'only_matching': True, | |
52 | }, { | |
53 | 'url': 'http://www.tf1.fr/hd1/documentaire/videos/mylene-farmer-d-une-icone.html', | |
54 | 'only_matching': True, | |
55 | }] | |
56 | ||
57 | def _real_extract(self, url): | |
58 | program_slug, slug = self._match_valid_url(url).groups() | |
59 | video = self._download_json( | |
60 | 'https://www.tf1.fr/graphql/web', slug, query={ | |
61 | 'id': '9b80783950b85247541dd1d851f9cc7fa36574af015621f853ab111a679ce26f', | |
62 | 'variables': json.dumps({ | |
63 | 'programSlug': program_slug, | |
64 | 'slug': slug, | |
65 | }) | |
66 | })['data']['videoBySlug'] | |
67 | wat_id = video['streamId'] | |
68 | ||
69 | tags = [] | |
70 | for tag in (video.get('tags') or []): | |
71 | label = tag.get('label') | |
72 | if not label: | |
73 | continue | |
74 | tags.append(label) | |
75 | ||
76 | decoration = video.get('decoration') or {} | |
77 | ||
78 | thumbnails = [] | |
79 | for source in (try_get(decoration, lambda x: x['image']['sources'], list) or []): | |
80 | source_url = source.get('url') | |
81 | if not source_url: | |
82 | continue | |
83 | thumbnails.append({ | |
84 | 'url': source_url, | |
85 | 'width': int_or_none(source.get('width')), | |
86 | }) | |
87 | ||
88 | return { | |
89 | '_type': 'url_transparent', | |
90 | 'id': wat_id, | |
91 | 'url': 'wat:' + wat_id, | |
92 | 'title': video.get('title'), | |
93 | 'thumbnails': thumbnails, | |
94 | 'description': decoration.get('description'), | |
95 | 'timestamp': parse_iso8601(video.get('date')), | |
96 | 'duration': int_or_none(try_get(video, lambda x: x['publicPlayingInfos']['duration'])), | |
97 | 'tags': tags, | |
98 | 'series': decoration.get('programLabel'), | |
99 | 'season_number': int_or_none(video.get('season')), | |
100 | 'episode_number': int_or_none(video.get('episode')), | |
101 | } |