[ccma] Add new extractor(closes #11359)
[youtube-dl] / youtube_dl / extractor / ccma.py
1 # coding: utf-8
2 from __future__ import unicode_literals
3
4 import re
5
6 from .common import InfoExtractor
7 from ..utils import (
8     int_or_none,
9     parse_duration,
10     parse_iso8601,
11     clean_html,
12 )
13
14
15 class CCMAIE(InfoExtractor):
16     _VALID_URL = r'https?://(?:www\.)?ccma\.cat/(?:[^/]+/)*?(?P<type>video|audio)/(?P<id>\d+)'
17     _TESTS = [{
18         'url': 'http://www.ccma.cat/tv3/alacarta/lespot-de-la-marato-de-tv3/lespot-de-la-marato-de-tv3/video/5630208/',
19         'md5': '7296ca43977c8ea4469e719c609b0871',
20         'info_dict': {
21             'id': '5630208',
22             'ext': 'mp4',
23             'title': 'L\'espot de La Marató de TV3',
24             'description': 'md5:f12987f320e2f6e988e9908e4fe97765',
25             'timestamp': 1470918540,
26             'upload_date': '20160811',
27         }
28     }, {
29         'url': 'http://www.ccma.cat/catradio/alacarta/programa/el-consell-de-savis-analitza-el-derbi/audio/943685/',
30         'md5': 'fa3e38f269329a278271276330261425',
31         'info_dict': {
32             'id': '943685',
33             'ext': 'mp3',
34             'title': 'El Consell de Savis analitza el derbi',
35             'description': 'md5:e2a3648145f3241cb9c6b4b624033e53',
36             'upload_date': '20171205',
37             'timestamp': 1512507300,
38         }
39     }]
40
41     def _real_extract(self, url):
42         media_type, media_id = re.match(self._VALID_URL, url).groups()
43         media_data = {}
44         formats = []
45         profiles = ['pc'] if media_type == 'audio' else ['mobil', 'pc']
46         for i, profile in enumerate(profiles):
47             md = self._download_json('http://dinamics.ccma.cat/pvideo/media.jsp', media_id, query={
48                 'media': media_type,
49                 'idint': media_id,
50                 'profile': profile,
51             }, fatal=False)
52             if md:
53                 media_data = md
54                 media_url = media_data.get('media', {}).get('url')
55                 if media_url:
56                     formats.append({
57                         'format_id': profile,
58                         'url': media_url,
59                         'quality': i,
60                     })
61         self._sort_formats(formats)
62
63         informacio = media_data['informacio']
64         title = informacio['titol']
65         durada = informacio.get('durada', {})
66         duration = int_or_none(durada.get('milisegons'), 1000) or parse_duration(durada.get('text'))
67         timestamp = parse_iso8601(informacio.get('data_emissio', {}).get('utc'))
68
69         subtitles = {}
70         subtitols = media_data.get('subtitols', {})
71         if subtitols:
72             sub_url = subtitols.get('url')
73             if sub_url:
74                 subtitles.setdefault(
75                     subtitols.get('iso') or subtitols.get('text') or 'ca', []).append({
76                         'url': sub_url,
77                     })
78
79         thumbnails = []
80         imatges = media_data.get('imatges', {})
81         if imatges:
82             thumbnail_url = imatges.get('url')
83             if thumbnail_url:
84                 thumbnails = [{
85                     'url': thumbnail_url,
86                     'width': int_or_none(imatges.get('amplada')),
87                     'height': int_or_none(imatges.get('alcada')),
88                 }]
89
90         return {
91             'id': media_id,
92             'title': title,
93             'description': clean_html(informacio.get('descripcio')),
94             'duration': duration,
95             'timestamp': timestamp,
96             'thumnails': thumbnails,
97             'subtitles': subtitles,
98             'formats': formats,
99         }