mirror of
				https://github.com/ytdl-org/youtube-dl.git
				synced 2025-10-29 09:26:20 -07:00 
			
		
		
		
	[newstube] fix extraction
This commit is contained in:
		| @@ -1,12 +1,17 @@ | |||||||
| # coding: utf-8 | # coding: utf-8 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| import re | import base64 | ||||||
|  | import hashlib | ||||||
|  |  | ||||||
| from .common import InfoExtractor | from .common import InfoExtractor | ||||||
|  | from ..aes import aes_cbc_decrypt | ||||||
| from ..utils import ( | from ..utils import ( | ||||||
|     ExtractorError, |     bytes_to_intlist, | ||||||
|     int_or_none, |     int_or_none, | ||||||
|  |     intlist_to_bytes, | ||||||
|  |     parse_codecs, | ||||||
|  |     parse_duration, | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -14,7 +19,7 @@ class NewstubeIE(InfoExtractor): | |||||||
|     _VALID_URL = r'https?://(?:www\.)?newstube\.ru/media/(?P<id>.+)' |     _VALID_URL = r'https?://(?:www\.)?newstube\.ru/media/(?P<id>.+)' | ||||||
|     _TEST = { |     _TEST = { | ||||||
|         'url': 'http://www.newstube.ru/media/telekanal-cnn-peremestil-gorod-slavyansk-v-krym', |         'url': 'http://www.newstube.ru/media/telekanal-cnn-peremestil-gorod-slavyansk-v-krym', | ||||||
|         'md5': '801eef0c2a9f4089fa04e4fe3533abdc', |         'md5': '9d10320ad473444352f72f746ccb8b8c', | ||||||
|         'info_dict': { |         'info_dict': { | ||||||
|             'id': '728e0ef2-e187-4012-bac0-5a081fdcb1f6', |             'id': '728e0ef2-e187-4012-bac0-5a081fdcb1f6', | ||||||
|             'ext': 'mp4', |             'ext': 'mp4', | ||||||
| @@ -25,84 +30,45 @@ class NewstubeIE(InfoExtractor): | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     def _real_extract(self, url): |     def _real_extract(self, url): | ||||||
|         mobj = re.match(self._VALID_URL, url) |         video_id = self._match_id(url) | ||||||
|         video_id = mobj.group('id') |  | ||||||
|  |  | ||||||
|         page = self._download_webpage(url, video_id, 'Downloading page') |         page = self._download_webpage(url, video_id) | ||||||
|  |         title = self._html_search_meta(['og:title', 'twitter:title'], page, fatal=True) | ||||||
|  |  | ||||||
|         video_guid = self._html_search_regex( |         video_guid = self._html_search_regex( | ||||||
|             r'<meta property="og:video:url" content="https?://(?:www\.)?newstube\.ru/freshplayer\.swf\?guid=(?P<guid>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})', |             r'<meta\s+property="og:video(?::(?:(?:secure_)?url|iframe))?"\s+content="https?://(?:www\.)?newstube\.ru/embed/(?P<guid>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})', | ||||||
|             page, 'video GUID') |             page, 'video GUID') | ||||||
|  |  | ||||||
|         player = self._download_xml( |         enc_data = base64.b64decode(self._download_webpage( | ||||||
|             'http://p.newstube.ru/v2/player.asmx/GetAutoPlayInfo6?state=&url=%s&sessionId=&id=%s&placement=profile&location=n2' % (url, video_guid), |             'https://www.newstube.ru/embed/api/player/getsources2', | ||||||
|             video_guid, 'Downloading player XML') |             video_guid, query={ | ||||||
|  |                 'guid': video_guid, | ||||||
|         def ns(s): |                 'ff': 3, | ||||||
|             return s.replace('/', '/%(ns)s') % {'ns': '{http://app1.newstube.ru/N2SiteWS/player.asmx}'} |             })) | ||||||
|  |         key = hashlib.pbkdf2_hmac( | ||||||
|         error_message = player.find(ns('./ErrorMessage')) |             'sha1', video_guid.replace('-', '').encode(), enc_data[:16], 1)[:16] | ||||||
|         if error_message is not None: |         dec_data = aes_cbc_decrypt( | ||||||
|             raise ExtractorError('%s returned error: %s' % (self.IE_NAME, error_message.text), expected=True) |             bytes_to_intlist(enc_data[32:]), bytes_to_intlist(key), | ||||||
|  |             bytes_to_intlist(enc_data[16:32])) | ||||||
|         session_id = player.find(ns('./SessionId')).text |         sources = self._parse_json(intlist_to_bytes(dec_data[:-dec_data[-1]]), video_guid) | ||||||
|         media_info = player.find(ns('./Medias/MediaInfo')) |  | ||||||
|         title = media_info.find(ns('./Name')).text |  | ||||||
|         description = self._og_search_description(page) |  | ||||||
|         thumbnail = media_info.find(ns('./KeyFrame')).text |  | ||||||
|         duration = int(media_info.find(ns('./Duration')).text) / 1000.0 |  | ||||||
|  |  | ||||||
|         formats = [] |         formats = [] | ||||||
|  |         for source in sources: | ||||||
|         for stream_info in media_info.findall(ns('./Streams/StreamInfo')): |             source_url = source.get('Src') | ||||||
|             media_location = stream_info.find(ns('./MediaLocation')) |             if not source_url: | ||||||
|             if media_location is None: |  | ||||||
|                 continue |                 continue | ||||||
|  |             height = int_or_none(source.get('Height')) | ||||||
|             server = media_location.find(ns('./Server')).text |             f = { | ||||||
|             app = media_location.find(ns('./App')).text |                 'format_id': 'http' + ('-%dp' % height if height else ''), | ||||||
|             media_id = stream_info.find(ns('./Id')).text |                 'url': source_url, | ||||||
|             name = stream_info.find(ns('./Name')).text |                 'width': int_or_none(source.get('Width')), | ||||||
|             width = int(stream_info.find(ns('./Width')).text) |  | ||||||
|             height = int(stream_info.find(ns('./Height')).text) |  | ||||||
|  |  | ||||||
|             formats.append({ |  | ||||||
|                 'url': 'rtmp://%s/%s' % (server, app), |  | ||||||
|                 'app': app, |  | ||||||
|                 'play_path': '01/%s' % video_guid.upper(), |  | ||||||
|                 'rtmp_conn': ['S:%s' % session_id, 'S:%s' % media_id, 'S:n2'], |  | ||||||
|                 'page_url': url, |  | ||||||
|                 'ext': 'flv', |  | ||||||
|                 'format_id': 'rtmp' + ('-%s' % name if name else ''), |  | ||||||
|                 'width': width, |  | ||||||
|                 'height': height, |                 'height': height, | ||||||
|             }) |             } | ||||||
|  |             source_type = source.get('Type') | ||||||
|         sources_data = self._download_json( |             if source_type: | ||||||
|             'http://www.newstube.ru/player2/getsources?guid=%s' % video_guid, |                 f.update(parse_codecs(self._search_regex( | ||||||
|             video_guid, fatal=False) |                     r'codecs="([^"]+)"', source_type, 'codecs', fatal=False))) | ||||||
|         if sources_data: |             formats.append(f) | ||||||
|             for source in sources_data.get('Sources', []): |  | ||||||
|                 source_url = source.get('Src') |  | ||||||
|                 if not source_url: |  | ||||||
|                     continue |  | ||||||
|                 height = int_or_none(source.get('Height')) |  | ||||||
|                 f = { |  | ||||||
|                     'format_id': 'http' + ('-%dp' % height if height else ''), |  | ||||||
|                     'url': source_url, |  | ||||||
|                     'width': int_or_none(source.get('Width')), |  | ||||||
|                     'height': height, |  | ||||||
|                 } |  | ||||||
|                 source_type = source.get('Type') |  | ||||||
|                 if source_type: |  | ||||||
|                     mobj = re.search(r'codecs="([^,]+),\s*([^"]+)"', source_type) |  | ||||||
|                     if mobj: |  | ||||||
|                         vcodec, acodec = mobj.groups() |  | ||||||
|                         f.update({ |  | ||||||
|                             'vcodec': vcodec, |  | ||||||
|                             'acodec': acodec, |  | ||||||
|                         }) |  | ||||||
|                 formats.append(f) |  | ||||||
|  |  | ||||||
|         self._check_formats(formats, video_guid) |         self._check_formats(formats, video_guid) | ||||||
|         self._sort_formats(formats) |         self._sort_formats(formats) | ||||||
| @@ -110,8 +76,8 @@ class NewstubeIE(InfoExtractor): | |||||||
|         return { |         return { | ||||||
|             'id': video_guid, |             'id': video_guid, | ||||||
|             'title': title, |             'title': title, | ||||||
|             'description': description, |             'description': self._html_search_meta(['description', 'og:description'], page), | ||||||
|             'thumbnail': thumbnail, |             'thumbnail': self._html_search_meta(['og:image:secure_url', 'og:image', 'twitter:image'], page), | ||||||
|             'duration': duration, |             'duration': parse_duration(self._html_search_meta('duration', page)), | ||||||
|             'formats': formats, |             'formats': formats, | ||||||
|         } |         } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user