logo

youtube-dl

[mirror] Download/Watch videos from video hostersgit clone https://hacktivis.me/git/mirror/youtube-dl.git

contv.py (4196B)


  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. from .common import InfoExtractor
  4. from ..utils import (
  5. float_or_none,
  6. int_or_none,
  7. )
  8. class CONtvIE(InfoExtractor):
  9. _VALID_URL = r'https?://(?:www\.)?contv\.com/details-movie/(?P<id>[^/]+)'
  10. _TESTS = [{
  11. 'url': 'https://www.contv.com/details-movie/CEG10022949/days-of-thrills-&-laughter',
  12. 'info_dict': {
  13. 'id': 'CEG10022949',
  14. 'ext': 'mp4',
  15. 'title': 'Days Of Thrills & Laughter',
  16. 'description': 'md5:5d6b3d0b1829bb93eb72898c734802eb',
  17. 'upload_date': '20180703',
  18. 'timestamp': 1530634789.61,
  19. },
  20. 'params': {
  21. # m3u8 download
  22. 'skip_download': True,
  23. },
  24. }, {
  25. 'url': 'https://www.contv.com/details-movie/CLIP-show_fotld_bts/fight-of-the-living-dead:-behind-the-scenes-bites',
  26. 'info_dict': {
  27. 'id': 'CLIP-show_fotld_bts',
  28. 'title': 'Fight of the Living Dead: Behind the Scenes Bites',
  29. },
  30. 'playlist_mincount': 7,
  31. }]
  32. def _real_extract(self, url):
  33. video_id = self._match_id(url)
  34. details = self._download_json(
  35. 'http://metax.contv.live.junctiontv.net/metax/2.5/details/' + video_id,
  36. video_id, query={'device': 'web'})
  37. if details.get('type') == 'episodic':
  38. seasons = self._download_json(
  39. 'http://metax.contv.live.junctiontv.net/metax/2.5/seriesfeed/json/' + video_id,
  40. video_id)
  41. entries = []
  42. for season in seasons:
  43. for episode in season.get('episodes', []):
  44. episode_id = episode.get('id')
  45. if not episode_id:
  46. continue
  47. entries.append(self.url_result(
  48. 'https://www.contv.com/details-movie/' + episode_id,
  49. CONtvIE.ie_key(), episode_id))
  50. return self.playlist_result(entries, video_id, details.get('title'))
  51. m_details = details['details']
  52. title = details['title']
  53. formats = []
  54. media_hls_url = m_details.get('media_hls_url')
  55. if media_hls_url:
  56. formats.extend(self._extract_m3u8_formats(
  57. media_hls_url, video_id, 'mp4',
  58. m3u8_id='hls', fatal=False))
  59. media_mp4_url = m_details.get('media_mp4_url')
  60. if media_mp4_url:
  61. formats.append({
  62. 'format_id': 'http',
  63. 'url': media_mp4_url,
  64. })
  65. self._sort_formats(formats)
  66. subtitles = {}
  67. captions = m_details.get('captions') or {}
  68. for caption_url in captions.values():
  69. subtitles.setdefault('en', []).append({
  70. 'url': caption_url
  71. })
  72. thumbnails = []
  73. for image in m_details.get('images', []):
  74. image_url = image.get('url')
  75. if not image_url:
  76. continue
  77. thumbnails.append({
  78. 'url': image_url,
  79. 'width': int_or_none(image.get('width')),
  80. 'height': int_or_none(image.get('height')),
  81. })
  82. description = None
  83. for p in ('large_', 'medium_', 'small_', ''):
  84. d = m_details.get(p + 'description')
  85. if d:
  86. description = d
  87. break
  88. return {
  89. 'id': video_id,
  90. 'title': title,
  91. 'formats': formats,
  92. 'thumbnails': thumbnails,
  93. 'description': description,
  94. 'timestamp': float_or_none(details.get('metax_added_on'), 1000),
  95. 'subtitles': subtitles,
  96. 'duration': float_or_none(m_details.get('duration'), 1000),
  97. 'view_count': int_or_none(details.get('num_watched')),
  98. 'like_count': int_or_none(details.get('num_fav')),
  99. 'categories': details.get('category'),
  100. 'tags': details.get('tags'),
  101. 'season_number': int_or_none(details.get('season')),
  102. 'episode_number': int_or_none(details.get('episode')),
  103. 'release_year': int_or_none(details.get('pub_year')),
  104. }