ccma.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. from .common import InfoExtractor
  2. from ..utils import (
  3. clean_html,
  4. determine_ext,
  5. int_or_none,
  6. parse_duration,
  7. parse_resolution,
  8. try_get,
  9. unified_timestamp,
  10. url_or_none,
  11. )
  12. class CCMAIE(InfoExtractor):
  13. _VALID_URL = r'https?://(?:www\.)?ccma\.cat/(?:[^/]+/)*?(?P<type>video|audio)/(?P<id>\d+)'
  14. _TESTS = [{
  15. 'url': 'http://www.ccma.cat/tv3/alacarta/lespot-de-la-marato-de-tv3/lespot-de-la-marato-de-tv3/video/5630208/',
  16. 'md5': '7296ca43977c8ea4469e719c609b0871',
  17. 'info_dict': {
  18. 'id': '5630208',
  19. 'ext': 'mp4',
  20. 'title': 'L\'espot de La Marató de TV3',
  21. 'description': 'md5:f12987f320e2f6e988e9908e4fe97765',
  22. 'timestamp': 1478608140,
  23. 'upload_date': '20161108',
  24. 'age_limit': 0,
  25. },
  26. }, {
  27. 'url': 'http://www.ccma.cat/catradio/alacarta/programa/el-consell-de-savis-analitza-el-derbi/audio/943685/',
  28. 'md5': 'fa3e38f269329a278271276330261425',
  29. 'info_dict': {
  30. 'id': '943685',
  31. 'ext': 'mp3',
  32. 'title': 'El Consell de Savis analitza el derbi',
  33. 'description': 'md5:e2a3648145f3241cb9c6b4b624033e53',
  34. 'upload_date': '20170512',
  35. 'timestamp': 1494622500,
  36. 'vcodec': 'none',
  37. 'categories': ['Esports'],
  38. },
  39. }, {
  40. 'url': 'http://www.ccma.cat/tv3/alacarta/crims/crims-josep-tallada-lespereu-me-capitol-1/video/6031387/',
  41. 'md5': 'b43c3d3486f430f3032b5b160d80cbc3',
  42. 'info_dict': {
  43. 'id': '6031387',
  44. 'ext': 'mp4',
  45. 'title': 'Crims - Josep Talleda, l\'"Espereu-me" (capítol 1)',
  46. 'description': 'md5:7cbdafb640da9d0d2c0f62bad1e74e60',
  47. 'timestamp': 1582577700,
  48. 'upload_date': '20200224',
  49. 'subtitles': 'mincount:4',
  50. 'age_limit': 16,
  51. 'series': 'Crims',
  52. },
  53. }]
  54. def _real_extract(self, url):
  55. media_type, media_id = self._match_valid_url(url).groups()
  56. media = self._download_json(
  57. 'http://dinamics.ccma.cat/pvideo/media.jsp', media_id, query={
  58. 'media': media_type,
  59. 'idint': media_id,
  60. 'format': 'dm',
  61. })
  62. formats = []
  63. media_url = media['media']['url']
  64. if isinstance(media_url, list):
  65. for format_ in media_url:
  66. format_url = url_or_none(format_.get('file'))
  67. if not format_url:
  68. continue
  69. if determine_ext(format_url) == 'mpd':
  70. formats.extend(self._extract_mpd_formats(
  71. format_url, media_id, mpd_id='dash', fatal=False))
  72. continue
  73. label = format_.get('label')
  74. f = parse_resolution(label)
  75. f.update({
  76. 'url': format_url,
  77. 'format_id': label,
  78. })
  79. formats.append(f)
  80. else:
  81. formats.append({
  82. 'url': media_url,
  83. 'vcodec': 'none' if media_type == 'audio' else None,
  84. })
  85. informacio = media['informacio']
  86. title = informacio['titol']
  87. durada = informacio.get('durada') or {}
  88. duration = int_or_none(durada.get('milisegons'), 1000) or parse_duration(durada.get('text'))
  89. tematica = try_get(informacio, lambda x: x['tematica']['text'])
  90. data_utc = try_get(informacio, lambda x: x['data_emissio']['utc'])
  91. timestamp = unified_timestamp(data_utc)
  92. subtitles = {}
  93. subtitols = media.get('subtitols') or []
  94. if isinstance(subtitols, dict):
  95. subtitols = [subtitols]
  96. for st in subtitols:
  97. sub_url = st.get('url')
  98. if sub_url:
  99. subtitles.setdefault(
  100. st.get('iso') or st.get('text') or 'ca', []).append({
  101. 'url': sub_url,
  102. })
  103. thumbnails = []
  104. imatges = media.get('imatges', {})
  105. if imatges:
  106. thumbnail_url = imatges.get('url')
  107. if thumbnail_url:
  108. thumbnails = [{
  109. 'url': thumbnail_url,
  110. 'width': int_or_none(imatges.get('amplada')),
  111. 'height': int_or_none(imatges.get('alcada')),
  112. }]
  113. age_limit = None
  114. codi_etic = try_get(informacio, lambda x: x['codi_etic']['id'])
  115. if codi_etic:
  116. codi_etic_s = codi_etic.split('_')
  117. if len(codi_etic_s) == 2:
  118. if codi_etic_s[1] == 'TP':
  119. age_limit = 0
  120. else:
  121. age_limit = int_or_none(codi_etic_s[1])
  122. return {
  123. 'id': media_id,
  124. 'title': title,
  125. 'description': clean_html(informacio.get('descripcio')),
  126. 'duration': duration,
  127. 'timestamp': timestamp,
  128. 'thumbnails': thumbnails,
  129. 'subtitles': subtitles,
  130. 'formats': formats,
  131. 'age_limit': age_limit,
  132. 'alt_title': informacio.get('titol_complet'),
  133. 'episode_number': int_or_none(informacio.get('capitol')),
  134. 'categories': [tematica] if tematica else None,
  135. 'series': informacio.get('programa'),
  136. }