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