1# coding: utf-8 2from __future__ import unicode_literals 3 4from .common import InfoExtractor 5from ..utils import ( 6 determine_ext, 7 ExtractorError, 8 int_or_none, 9 mimetype2ext, 10 parse_iso8601, 11 unified_timestamp, 12 url_or_none, 13) 14 15 16class AMPIE(InfoExtractor): 17 # parse Akamai Adaptive Media Player feed 18 def _extract_feed_info(self, url): 19 feed = self._download_json( 20 url, None, 'Downloading Akamai AMP feed', 21 'Unable to download Akamai AMP feed') 22 item = feed.get('channel', {}).get('item') 23 if not item: 24 raise ExtractorError('%s said: %s' % (self.IE_NAME, feed['error'])) 25 26 video_id = item['guid'] 27 28 def get_media_node(name, default=None): 29 media_name = 'media-%s' % name 30 media_group = item.get('media-group') or item 31 return media_group.get(media_name) or item.get(media_name) or item.get(name, default) 32 33 thumbnails = [] 34 media_thumbnail = get_media_node('thumbnail') 35 if media_thumbnail: 36 if isinstance(media_thumbnail, dict): 37 media_thumbnail = [media_thumbnail] 38 for thumbnail_data in media_thumbnail: 39 thumbnail = thumbnail_data.get('@attributes', {}) 40 thumbnail_url = url_or_none(thumbnail.get('url')) 41 if not thumbnail_url: 42 continue 43 thumbnails.append({ 44 'url': self._proto_relative_url(thumbnail_url, 'http:'), 45 'width': int_or_none(thumbnail.get('width')), 46 'height': int_or_none(thumbnail.get('height')), 47 }) 48 49 subtitles = {} 50 media_subtitle = get_media_node('subTitle') 51 if media_subtitle: 52 if isinstance(media_subtitle, dict): 53 media_subtitle = [media_subtitle] 54 for subtitle_data in media_subtitle: 55 subtitle = subtitle_data.get('@attributes', {}) 56 subtitle_href = url_or_none(subtitle.get('href')) 57 if not subtitle_href: 58 continue 59 subtitles.setdefault(subtitle.get('lang') or 'en', []).append({ 60 'url': subtitle_href, 61 'ext': mimetype2ext(subtitle.get('type')) or determine_ext(subtitle_href), 62 }) 63 64 formats = [] 65 media_content = get_media_node('content') 66 if isinstance(media_content, dict): 67 media_content = [media_content] 68 for media_data in media_content: 69 media = media_data.get('@attributes', {}) 70 media_url = url_or_none(media.get('url')) 71 if not media_url: 72 continue 73 ext = mimetype2ext(media.get('type')) or determine_ext(media_url) 74 if ext == 'f4m': 75 formats.extend(self._extract_f4m_formats( 76 media_url + '?hdcore=3.4.0&plugin=aasp-3.4.0.132.124', 77 video_id, f4m_id='hds', fatal=False)) 78 elif ext == 'm3u8': 79 formats.extend(self._extract_m3u8_formats( 80 media_url, video_id, 'mp4', m3u8_id='hls', fatal=False)) 81 else: 82 formats.append({ 83 'format_id': media_data.get('media-category', {}).get('@attributes', {}).get('label'), 84 'url': media_url, 85 'tbr': int_or_none(media.get('bitrate')), 86 'filesize': int_or_none(media.get('fileSize')), 87 'ext': ext, 88 }) 89 90 self._sort_formats(formats) 91 92 timestamp = unified_timestamp(item.get('pubDate'), ' ') or parse_iso8601(item.get('dc-date')) 93 94 return { 95 'id': video_id, 96 'title': get_media_node('title'), 97 'description': get_media_node('description'), 98 'thumbnails': thumbnails, 99 'timestamp': timestamp, 100 'duration': int_or_none(media_content[0].get('@attributes', {}).get('duration')), 101 'subtitles': subtitles, 102 'formats': formats, 103 } 104