logo

youtube-dl

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

twitcasting.py (4146B)


  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import re
  4. from .common import InfoExtractor
  5. from ..utils import (
  6. clean_html,
  7. float_or_none,
  8. get_element_by_class,
  9. get_element_by_id,
  10. parse_duration,
  11. str_to_int,
  12. unified_timestamp,
  13. urlencode_postdata,
  14. )
  15. class TwitCastingIE(InfoExtractor):
  16. _VALID_URL = r'https?://(?:[^/]+\.)?twitcasting\.tv/(?P<uploader_id>[^/]+)/movie/(?P<id>\d+)'
  17. _TESTS = [{
  18. 'url': 'https://twitcasting.tv/ivetesangalo/movie/2357609',
  19. 'md5': '745243cad58c4681dc752490f7540d7f',
  20. 'info_dict': {
  21. 'id': '2357609',
  22. 'ext': 'mp4',
  23. 'title': 'Live #2357609',
  24. 'uploader_id': 'ivetesangalo',
  25. 'description': 'Twitter Oficial da cantora brasileira Ivete Sangalo.',
  26. 'thumbnail': r're:^https?://.*\.jpg$',
  27. 'upload_date': '20110822',
  28. 'timestamp': 1314010824,
  29. 'duration': 32,
  30. 'view_count': int,
  31. },
  32. 'params': {
  33. 'skip_download': True,
  34. },
  35. }, {
  36. 'url': 'https://twitcasting.tv/mttbernardini/movie/3689740',
  37. 'info_dict': {
  38. 'id': '3689740',
  39. 'ext': 'mp4',
  40. 'title': 'Live playing something #3689740',
  41. 'uploader_id': 'mttbernardini',
  42. 'description': 'Salve, io sono Matto (ma con la e). Questa è la mia presentazione, in quanto sono letteralmente matto (nel senso di strano), con qualcosa in più.',
  43. 'thumbnail': r're:^https?://.*\.jpg$',
  44. 'upload_date': '20120212',
  45. 'timestamp': 1329028024,
  46. 'duration': 681,
  47. 'view_count': int,
  48. },
  49. 'params': {
  50. 'skip_download': True,
  51. 'videopassword': 'abc',
  52. },
  53. }]
  54. def _real_extract(self, url):
  55. uploader_id, video_id = re.match(self._VALID_URL, url).groups()
  56. video_password = self._downloader.params.get('videopassword')
  57. request_data = None
  58. if video_password:
  59. request_data = urlencode_postdata({
  60. 'password': video_password,
  61. })
  62. webpage = self._download_webpage(url, video_id, data=request_data)
  63. title = clean_html(get_element_by_id(
  64. 'movietitle', webpage)) or self._html_search_meta(
  65. ['og:title', 'twitter:title'], webpage, fatal=True)
  66. video_js_data = {}
  67. m3u8_url = self._search_regex(
  68. r'data-movie-url=(["\'])(?P<url>(?:(?!\1).)+)\1',
  69. webpage, 'm3u8 url', group='url', default=None)
  70. if not m3u8_url:
  71. video_js_data = self._parse_json(self._search_regex(
  72. r"data-movie-playlist='(\[[^']+\])'",
  73. webpage, 'movie playlist'), video_id)[0]
  74. m3u8_url = video_js_data['source']['url']
  75. # use `m3u8` entry_protocol until EXT-X-MAP is properly supported by `m3u8_native` entry_protocol
  76. formats = self._extract_m3u8_formats(
  77. m3u8_url, video_id, 'mp4', m3u8_id='hls')
  78. thumbnail = video_js_data.get('thumbnailUrl') or self._og_search_thumbnail(webpage)
  79. description = clean_html(get_element_by_id(
  80. 'authorcomment', webpage)) or self._html_search_meta(
  81. ['description', 'og:description', 'twitter:description'], webpage)
  82. duration = float_or_none(video_js_data.get(
  83. 'duration'), 1000) or parse_duration(clean_html(
  84. get_element_by_class('tw-player-duration-time', webpage)))
  85. view_count = str_to_int(self._search_regex(
  86. r'Total\s*:\s*([\d,]+)\s*Views', webpage, 'views', None))
  87. timestamp = unified_timestamp(self._search_regex(
  88. r'data-toggle="true"[^>]+datetime="([^"]+)"',
  89. webpage, 'datetime', None))
  90. return {
  91. 'id': video_id,
  92. 'title': title,
  93. 'description': description,
  94. 'thumbnail': thumbnail,
  95. 'timestamp': timestamp,
  96. 'uploader_id': uploader_id,
  97. 'duration': duration,
  98. 'view_count': view_count,
  99. 'formats': formats,
  100. }