X-Git-Url: https://git.rapsys.eu/youtubedl/blobdiff_plain/415fdb62500dca2e22067a05008dfbf87c75b662..b9a5031529f8a67d511988b11f489860413fad26:/youtube_dl/extractor/iprima.py diff --git a/youtube_dl/extractor/iprima.py b/youtube_dl/extractor/iprima.py index d1defd3..53a550c 100644 --- a/youtube_dl/extractor/iprima.py +++ b/youtube_dl/extractor/iprima.py @@ -1,107 +1,148 @@ -# -*- coding: utf-8 -*- +# coding: utf-8 from __future__ import unicode_literals import re -from random import random -from math import floor +import time from .common import InfoExtractor from ..utils import ( - compat_urllib_request, - ExtractorError, + determine_ext, + js_to_json, ) class IPrimaIE(InfoExtractor): - _VALID_URL = r'https?://play\.iprima\.cz/[^?#]+/(?P[^?#]+)' + _VALID_URL = r'https?://(?:[^/]+)\.iprima\.cz/(?:[^/]+/)*(?P[^/?#&]+)' + _GEO_BYPASS = False _TESTS = [{ - 'url': 'http://play.iprima.cz/particka/particka-92', + 'url': 'https://prima.iprima.cz/particka/92-epizoda', 'info_dict': { - 'id': '39152', - 'ext': 'flv', + 'id': 'p51388', + 'ext': 'mp4', 'title': 'Partička (92)', - 'description': 'md5:3740fda51464da35a2d4d0670b8e4fd6', - 'thumbnail': 'http://play.iprima.cz/sites/default/files/image_crops/image_620x349/3/491483_particka-92_image_620x349.jpg', + 'description': 'md5:859d53beae4609e6dd7796413f1b6cac', }, 'params': { - 'skip_download': True, # requires rtmpdump + 'skip_download': True, # m3u8 download }, }, { - 'url': 'http://play.iprima.cz/particka/tchibo-particka-jarni-moda', + 'url': 'https://cnn.iprima.cz/videa/70-epizoda', 'info_dict': { - 'id': '9718337', - 'ext': 'flv', - 'title': 'Tchibo Partička - Jarní móda', - 'description': 'md5:589f8f59f414220621ff8882eb3ce7be', - 'thumbnail': 're:^http:.*\.jpg$', + 'id': 'p681554', + 'ext': 'mp4', + 'title': 'HLAVNÍ ZPRÁVY 3.5.2020', }, 'params': { - 'skip_download': True, # requires rtmpdump + 'skip_download': True, # m3u8 download }, - 'skip': 'Do not have permission to access this page', + }, { + 'url': 'http://play.iprima.cz/particka/particka-92', + 'only_matching': True, + }, { + # geo restricted + 'url': 'http://play.iprima.cz/closer-nove-pripady/closer-nove-pripady-iv-1', + 'only_matching': True, + }, { + # iframe api.play-backend.iprima.cz + 'url': 'https://prima.iprima.cz/my-little-pony/mapa-znameni-2-2', + 'only_matching': True, + }, { + # iframe prima.iprima.cz + 'url': 'https://prima.iprima.cz/porady/jak-se-stavi-sen/rodina-rathousova-praha', + 'only_matching': True, + }, { + 'url': 'http://www.iprima.cz/filmy/desne-rande', + 'only_matching': True, + }, { + 'url': 'https://zoom.iprima.cz/10-nejvetsich-tajemstvi-zahad/posvatna-mista-a-stavby', + 'only_matching': True, + }, { + 'url': 'https://krimi.iprima.cz/mraz-0/sebevrazdy', + 'only_matching': True, + }, { + 'url': 'https://cool.iprima.cz/derava-silnice-nevadi', + 'only_matching': True, + }, { + 'url': 'https://love.iprima.cz/laska-az-za-hrob/slib-dany-bratrovi', + 'only_matching': True, + }, { + 'url': 'https://autosalon.iprima.cz/motorsport/7-epizoda-1', + 'only_matching': True, }] def _real_extract(self, url): - mobj = re.match(self._VALID_URL, url) - video_id = mobj.group('id') - - webpage = self._download_webpage(url, video_id) + video_id = self._match_id(url) - if re.search(r'Nemáte oprávnění přistupovat na tuto stránku\.\s*', webpage): - raise ExtractorError( - '%s said: You do not have permission to access this page' % self.IE_NAME, expected=True) + self._set_cookie('play.iprima.cz', 'ott_adult_confirmed', '1') - player_url = ( - 'http://embed.livebox.cz/iprimaplay/player-embed-v2.js?__tok%s__=%s' % - (floor(random()*1073741824), floor(random()*1073741824)) - ) - - req = compat_urllib_request.Request(player_url) - req.add_header('Referer', url) - playerpage = self._download_webpage(req, video_id) - - base_url = ''.join(re.findall(r"embed\['stream'\] = '(.+?)'.+'(\?auth=)'.+'(.+?)';", playerpage)[1]) + webpage = self._download_webpage(url, video_id) - zoneGEO = self._html_search_regex(r'"zoneGEO":(.+?),', webpage, 'zoneGEO') - if zoneGEO != '0': - base_url = base_url.replace('token', 'token_' + zoneGEO) + title = self._og_search_title( + webpage, default=None) or self._search_regex( + r'

([^<]+)', webpage, 'title') + + video_id = self._search_regex( + (r']+\bsrc=["\'](?:https?:)?//(?:api\.play-backend\.iprima\.cz/prehravac/embedded|prima\.iprima\.cz/[^/]+/[^/]+)\?.*?\bid=(p\d+)', + r'data-product="([^"]+)">', + r'id=["\']player-(p\d+)"', + r'playerId\s*:\s*["\']player-(p\d+)'), + webpage, 'real id') + + playerpage = self._download_webpage( + 'http://play.iprima.cz/prehravac/init', + video_id, note='Downloading player', query={ + '_infuse': 1, + '_ts': round(time.time()), + 'productId': video_id, + }, headers={'Referer': url}) formats = [] - for format_id in ['lq', 'hq', 'hd']: - filename = self._html_search_regex( - r'"%s_id":(.+?),' % format_id, webpage, 'filename') - - if filename == 'null': - continue - - real_id = self._search_regex( - r'Prima-(?:[0-9]{10}|WEB)-([0-9]+)[-_]', - filename, 'real video id') - - if format_id == 'lq': - quality = 0 - elif format_id == 'hq': - quality = 1 - elif format_id == 'hd': - quality = 2 - filename = 'hq/' + filename - - formats.append({ - 'format_id': format_id, - 'url': base_url, - 'quality': quality, - 'play_path': 'mp4:' + filename.replace('"', '')[:-4], - 'rtmp_live': True, - 'ext': 'flv', - }) + + def extract_formats(format_url, format_key=None, lang=None): + ext = determine_ext(format_url) + new_formats = [] + if format_key == 'hls' or ext == 'm3u8': + new_formats = self._extract_m3u8_formats( + format_url, video_id, 'mp4', entry_protocol='m3u8_native', + m3u8_id='hls', fatal=False) + elif format_key == 'dash' or ext == 'mpd': + return + new_formats = self._extract_mpd_formats( + format_url, video_id, mpd_id='dash', fatal=False) + if lang: + for f in new_formats: + if not f.get('language'): + f['language'] = lang + formats.extend(new_formats) + + options = self._parse_json( + self._search_regex( + r'(?s)(?:TDIPlayerOptions|playerOptions)\s*=\s*({.+?});\s*\]\]', + playerpage, 'player options', default='{}'), + video_id, transform_source=js_to_json, fatal=False) + if options: + for key, tracks in options.get('tracks', {}).items(): + if not isinstance(tracks, list): + continue + for track in tracks: + src = track.get('src') + if src: + extract_formats(src, key.lower(), track.get('lang')) + + if not formats: + for _, src in re.findall(r'src["\']\s*:\s*(["\'])(.+?)\1', playerpage): + extract_formats(src) + + if not formats and '>GEO_IP_NOT_ALLOWED<' in playerpage: + self.raise_geo_restricted(countries=['CZ']) self._sort_formats(formats) return { - 'id': real_id, - 'title': self._og_search_title(webpage), - 'thumbnail': self._og_search_thumbnail(webpage), + 'id': video_id, + 'title': title, + 'thumbnail': self._og_search_thumbnail(webpage, default=None), 'formats': formats, - 'description': self._og_search_description(webpage), + 'description': self._og_search_description(webpage, default=None), }