YouTube come add-on esterno
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<fname>\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
|
||||
Reference in New Issue
Block a user