youtube-dl

Another place where youtube-dl lives on
git clone git://git.oshgnacknak.de/youtube-dl.git
Log | Files | Refs | README | LICENSE

commit b8972bd69da48509333a8239fc0b755dccb1a681
parent 0ae937a798c2c9a2eae4c6dbadc68a1a4c5e101c
Author: Yen Chi Hsuan <yan12125@gmail.com>
Date:   Thu,  3 Mar 2016 14:24:24 +0800

[twitter] Fix extraction of test_Twitter and test_Twitter_1

Diffstat:
Myoutube_dl/extractor/twitter.py | 71+++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 51 insertions(+), 20 deletions(-)

diff --git a/youtube_dl/extractor/twitter.py b/youtube_dl/extractor/twitter.py @@ -95,6 +95,8 @@ class TwitterCardIE(TwitterBaseIE): config = None formats = [] + duration = None + for user_agent in USER_AGENTS: request = sanitized_Request(url) request.add_header('User-Agent', user_agent) @@ -109,33 +111,60 @@ class TwitterCardIE(TwitterBaseIE): config = self._parse_json(self._html_search_regex( r'data-(?:player-)?config="([^"]+)"', webpage, 'data player config'), video_id) - if 'playlist' not in config: - vmap_url = config.get('vmapUrl') or config.get('vmap_url') - if vmap_url: - formats.append({ - 'url': self._get_vmap_video_url(vmap_url, video_id), - }) - break # same video regardless of UA - continue - video_url = config['playlist'][0]['source'] + playlist = config.get('playlist') + if playlist: + video_url = playlist[0]['source'] - f = { - 'url': video_url, - } + f = { + 'url': video_url, + } + + m = re.search(r'/(?P<width>\d+)x(?P<height>\d+)/', video_url) + if m: + f.update({ + 'width': int(m.group('width')), + 'height': int(m.group('height')), + }) + formats.append(f) + continue - m = re.search(r'/(?P<width>\d+)x(?P<height>\d+)/', video_url) - if m: - f.update({ - 'width': int(m.group('width')), - 'height': int(m.group('height')), + vmap_url = config.get('vmapUrl') or config.get('vmap_url') + if vmap_url: + formats.append({ + 'url': self._get_vmap_video_url(vmap_url, video_id), }) - formats.append(f) + break # same video regardless of UA + + media_info = config.get('status', {}).get('entities', [{}])[0].get('mediaInfo', {}) + if media_info: + for media_variant in media_info['variants']: + media_url = media_variant['url'] + if media_url.endswith('.m3u8'): + formats.extend(self._extract_m3u8_formats(media_url, video_id, ext='mp4', m3u8_id='hls')) + elif media_url.endswith('.mpd'): + formats.extend(self._extract_mpd_formats(media_url, video_id, mpd_id='dash')) + else: + vbr = int_or_none(media_variant.get('bitRate'), scale=1000) + a_format = { + 'url': media_url, + 'format_id': 'http-%d' % vbr if vbr else 'http', + 'vbr': vbr, + } + # Reported bitRate may be zero + if not a_format['vbr']: + del a_format['vbr'] + + formats.append(a_format) + + duration = float_or_none(media_info.get('duration', {}).get('nanos'), scale=1e9) + break # same video regardless of UA + self._sort_formats(formats) title = self._search_regex(r'<title>([^<]+)</title>', webpage, 'title') thumbnail = config.get('posterImageUrl') or config.get('image_src') - duration = float_or_none(config.get('duration')) + duration = float_or_none(config.get('duration')) or duration return { 'id': video_id, @@ -153,7 +182,6 @@ class TwitterIE(InfoExtractor): _TESTS = [{ 'url': 'https://twitter.com/freethenipple/status/643211948184596480', - # MD5 checksums are different in different places 'info_dict': { 'id': '643211948184596480', 'ext': 'mp4', @@ -164,6 +192,9 @@ class TwitterIE(InfoExtractor): 'uploader': 'FREE THE NIPPLE', 'uploader_id': 'freethenipple', }, + 'params': { + 'skip_download': True, # requires ffmpeg + }, }, { 'url': 'https://twitter.com/giphz/status/657991469417025536/photo/1', 'md5': 'f36dcd5fb92bf7057f155e7d927eeb42',