diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index f6a9433d..5e7f686b 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -6071,6 +6071,10 @@ msgctxt "#70817" msgid "La Serie "%s" non è gestita da KoD, Vuoi cercarla?" msgstr "" +msgctxt "#70818" +msgid "YouTube is installed on your device, but is not active. Do you want to activate it?" +msgstr "" + # DNS start [ settings and declaration ] msgctxt "#707401" msgid "Enable DNS check alert" diff --git a/resources/language/resource.language.it_it/strings.po b/resources/language/resource.language.it_it/strings.po index a4e88eaa..90e9007f 100644 --- a/resources/language/resource.language.it_it/strings.po +++ b/resources/language/resource.language.it_it/strings.po @@ -6071,6 +6071,10 @@ msgctxt "#70817" msgid "La Serie "%s" non è gestita da KoD, Vuoi cercarla?" msgstr "La Serie "%s" non è gestita da KoD, Vuoi cercarla?" +msgctxt "#70818" +msgid "YouTube is installed on your device, but is not active. Do you want to activate it?" +msgstr "YouTube è installato sul tuo dispositivo, ma non è attivo. Vuoi Attivarlo?" + # DNS start [ settings and declaration ] msgctxt "#707401" msgid "Enable DNS check alert" diff --git a/servers/youtube.py b/servers/youtube.py index 531a2df2..f0250994 100644 --- a/servers/youtube.py +++ b/servers/youtube.py @@ -1,91 +1,9 @@ # s-*- coding: utf-8 -*- -import sys -PY3 = False -if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int - -if PY3: - #from future import standard_library - #standard_library.install_aliases() - import urllib.parse as urllib # Es muy lento en PY2. En PY3 es nativo - import urllib.parse as urlparse -else: - import urllib # Usamos el nativo de PY2 que es más rápido - import urlparse - -import re - -from core import httptools -from core import jsontools as json -from core import scrapertools -from platformcode import config, logger - - -itag_list = {1: "video", - 5: "flv 240p", - 6: "flv 270p", - 17: "3gp 144p", - 18: "mp4 360p", - 22: "mp4 720p", - 34: "flv 360p", - 35: "flv 480p", - 36: "3gp 180p", - 37: "mp4 1080p", - 38: "mp4 3072p", - 43: "webm 360p", - 44: "webm 480p", - 45: "webm 720p", - 46: "webm 1080p", - 82: "mp4 360p 3D", - 83: "mp4 480p 3D", - 84: "mp4 720p 3D", - 85: "mp4 1080p 3D", - 92: "hls 240p 3D", - 93: "hls 360p 3D", - 94: "hls 480p 3D", - 95: "hls 720p 3D", - 96: "hls 1080p", - 100: "webm 360p 3D", - 101: "webm 480p 3D", - 102: "webm 720p 3D", - 132: "hls 240p", - 133: "mp4 240p", - 134: "mp4 360p", - 135: "mp4 480p", - 136: "mp4 720p", - 137: "mp4 1080p", - 138: "mp4 2160p", - 160: "mp4 144p", - 167: "webm 360p", - 168: "webm 480p", - 169: "webm 1080p", - 219: "webm 144p", - 242: "webm 240p", - 243: "webm 360p", - 244: "webm 480p", - 245: "webm 480p", - 246: "webm 480p", - 247: "webm 720p", - 248: "webm 1080p", - 266: "mp4 2160p", - 271: "webm 1440p", - 272: "webm 4320p", - 278: "webm 144p", - 298: "mp4 720p", - 299: "mp4 1080p", - 302: "webm 720p", - 303: "webm 1080p", - 308: "webm 1440p", - 313: "webm 2160p", - 315: "webm 2160p", - 330: "webm 144p hdr", - 331: "webm 240p hdr", - 332: "webm 360p hdr", - 333: "webm 480p hdr", - 334: "webm 720p hdr", - 335: "webm 1080p hdr", - 336: "webm 1440p hdr"} +from core import httptools, scrapertools, filetools +from platformcode import config, logger, platformtools +name = 'plugin.video.youtube' def test_video_exists(page_url): logger.info("(page_url='%s')" % page_url) @@ -93,137 +11,37 @@ def test_video_exists(page_url): data = httptools.downloadpage(page_url).data if "File was deleted" in data or "Video non disponibile" in data: - return False, config.get_localized_string(70449) % "Youtube" + return False, config.get_localized_string(70449) % "YouTube" return True, "" def get_video_url(page_url, premium=False, user="", password="", video_password=""): + import xbmc from xbmcaddon import Addon logger.info("(page_url='%s')" % page_url) + video_urls = [] if not page_url.startswith("http"): page_url = "http://www.youtube.com/watch?v=%s" % page_url logger.info(" page_url->'%s'" % page_url) video_id = scrapertools.find_single_match(page_url, '(?:v=|embed/)([A-z0-9_-]{11})') + # from core.support import dbg;dbg() try: - __settings__ = Addon('plugin.video.youtube') - if not __settings__.getSetting('kodion.video.quality.mpd'): + __settings__ = Addon(name) + if __settings__.getSetting('kodion.video.quality.mpd') == 'false': __settings__.setSetting('kodion.video.quality.mpd', 'true') - video_urls = [[ 'con YouTube', 'plugin://plugin.video.youtube/play/?video_id=' + video_id ]] + video_urls = [['con YouTube', 'plugin://plugin.video.youtube/play/?video_id=' + video_id ]] except: - video_urls = extract_videos(video_id) - - return sorted(video_urls, reverse=True) - - -def remove_additional_ending_delimiter(data): - pos = data.find("};") - if pos != -1: - data = data[:pos + 1] - return data - - -def normalize_url(url): - if url[0:2] == "//": - url = "http:" + url - return url - - -def extract_flashvars(data): - assets = 0 - flashvars = {} - found = False - - for line in data.split("\n"): - if line.strip().find(";ytplayer.config = ") > 0: - found = True - p1 = line.find(";ytplayer.config = ") + len(";ytplayer.config = ") - 1 - p2 = line.rfind(";") - if p1 <= 0 or p2 <= 0: - continue - data = line[p1 + 1:p2] - break - data = remove_additional_ending_delimiter(data) - - if found: - data = json.load(data) - if assets: - flashvars = data["assets"] + if filetools.exists(xbmc.translatePath('special://profile/addon_data/' + name)): + if platformtools.dialog_yesno(config.get_localized_string(70784), config.get_localized_string(70818)): + xbmc.executeJSONRPC('{"jsonrpc": "2.0", "id":1, "method": "Addons.SetAddonEnabled", "params": { "addonid": "' + name + '", "enabled": true }}') + else: return [['','']] else: - flashvars = data["args"] + xbmc.executebuiltin('InstallAddon(' + name + ')', wait=True) + try: Addon(name) + except: return [['','']] - for k in ["html", "css", "js"]: - if k in flashvars: - flashvars[k] = normalize_url(flashvars[k]) + return get_video_url(page_url) + return video_urls - return flashvars - - -def get_signature(youtube_page_data): - - from lib.jsinterpreter import JSInterpreter - - urljs = scrapertools.find_single_match(youtube_page_data, '"assets":.*?"js":\s*"([^"]+)"') - urljs = urljs.replace("\\", "") - if urljs: - if not re.search(r'https?://', urljs): - urljs = urlparse.urljoin("https://www.youtube.com", urljs) - data_js = httptools.downloadpage(urljs).data - - pattern = r'(?P\w+)=function\(\w+\){(\w)=\2\.split\(""\);.*?return\s+\2\.join\(""\)}' - - funcname = re.search(pattern, data_js).group('fname') - - jsi = JSInterpreter(data_js) - js_signature = jsi.extract_function(funcname) - - return js_signature - - -def extract_videos(video_id): - - - url = 'https://www.youtube.com/get_video_info?video_id=%s&eurl=https://youtube.googleapis.com/v/%s&ssl_stream=1' % \ - (video_id, video_id) - data = httptools.downloadpage(url).data - - video_urls = [] - params = dict(urlparse.parse_qsl(data)) - - if params.get('hlsvp'): - video_urls.append(["(LIVE .m3u8) [youtube]", params['hlsvp']]) - return video_urls - - if config.is_xbmc(): - import xbmc - xbmc_version = config.get_platform(True)['num_version'] - if xbmc_version >= 17 and xbmc.getCondVisibility('System.HasAddon(inputstream.adaptive)') \ - and params.get('dashmpd'): - if params.get('use_cipher_signature', '') != 'True': - video_urls.append(['mpd HD [youtube]', params['dashmpd'], 0, '', True]) - - youtube_page_data = httptools.downloadpage("https://www.youtube.com/watch?v=%s" % video_id).data - - params = extract_flashvars(youtube_page_data) - - if params.get('player_response'): - params = json.load(params.get('player_response')) - data_flashvars = params["streamingData"] - for s_data in data_flashvars: - if s_data in ["adaptiveFormats", "formats"]: - for opt in data_flashvars[s_data]: - opt = dict(opt) - if "audioQuality" not in opt: - continue - if "cipher" in opt: - signature = get_signature(youtube_page_data) - cipher = dict(urlparse.parse_qsl(urllib.unquote(opt["cipher"]))) - url = re.search('url=(.*)', opt["cipher"]).group(1) - s = cipher.get('s') - url = "%s&sig=%s" % (urllib.unquote(url), signature([s])) - video_urls.append(["%s" % itag_list.get(opt["itag"], "video"), url]) - elif opt["itag"] in itag_list: - video_urls.append(["%s" % itag_list.get(opt["itag"], "video"), opt["url"]]) - - return video_urls \ No newline at end of file