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