# -*- coding: utf-8 -*- ################################################### # LOCAL import ################################################### from Plugins.Extensions.IPTVPlayer.tools.iptvtools import printDBG, printExc from Plugins.Extensions.IPTVPlayer.tools.iptvtypes import strwithmeta from Plugins.Extensions.IPTVPlayer.libs.pCommon import CParsingHelper, common from Plugins.Extensions.IPTVPlayer.libs import m3u8 ################################################### # FOREIGN import ################################################### from binascii import hexlify import re import time import string import codecs import urllib ################################################### try: from hashlib import md5 def hex_md5(e): return md5(e).hexdigest() except: from Plugins.Extensions.IPTVPlayer.libs.crypto.hash.md5Hash import MD5 as md5 def hex_md5(e): hashAlg = MD5() return hexlify(hashAlg(e)) def int2base(x, base): digs = string.digits + string.lowercase if x < 0: sign = -1 elif x==0: return '0' else: sign = 1 x *= sign digits = [] while x: digits.append(digs[x % base]) x /= base if sign < 0: digits.append('-') digits.reverse() return ''.join(digits) def JS_toString(x, base): return int2base(x, base) # returns timestamp in milliseconds def JS_DateValueOf(): return time.time()*1000 def JS_FromCharCode(*args): return ''.join(map(unichr, args)) def unicode_escape(s): decoder = codecs.getdecoder('unicode_escape') return re.sub(r'\\u[0-9a-fA-F]{4,}', lambda m: decoder(m.group(0))[0], s).encode('utf-8') def drdX_fx(e): t = {} n = 0 r = 0 i = [] s = "" o = JS_FromCharCode u = [[65, 91], [97, 123], [48, 58], [43, 44], [47, 48]] for z in range(len(u)): n = u[z][0] while n < u[z][1]: i.append(o(n)) n += 1 n = 0 while n < 64: t[i[n]] = n n += 1 n = 0 while n < len(e): a = 0 f = 0 l = 0 c = 0 h = e[n:n+72] while l < len(h): f = t[h[l]] a = (a << 6) + f c += 6 while c >= 8: c -= 8 s += o((a >> c) % 256) l += 1 n += 72 return s #################################################### # myobfuscate.com #################################################### def MYOBFUSCATECOM_OIO(data, _0lllOI="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", enc=''): i = 0; while i < len(data): h1 = _0lllOI.find(data[i]); h2 = _0lllOI.find(data[i+1]); h3 = _0lllOI.find(data[i+2]); h4 = _0lllOI.find(data[i+3]); i += 4; bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; o1 = bits >> 16 & 0xff; o2 = bits >> 8 & 0xff; o3 = bits & 0xff; if h3 == 64: enc += chr(o1); else: if h4 == 64: enc += chr(o1) + chr(o2); else: enc += chr(o1) + chr(o2) + chr(o3); return enc def MYOBFUSCATECOM_0ll(string, baseRet=''): ret = baseRet i = len(string) - 1 while i >= 0: ret += string[i] i -= 1 return ret def VIDEOMEGA_decryptPlayerParams(p, a, c, k, e, d): def e1(c): return JS_toString(c, 36) return ret def k1(matchobj): return d[matchobj.group(0)] def e2(t=None): return '\\w+' e = e1 if True: while c != 0: c -= 1 tmp1 = e(c) d[tmp1] = k[c] if '' == d[tmp1]: d[tmp1] = e(c) c = 1 k = [k1] e = e2 while c != 0: c -= 1 if k[c]: reg = '\\b' + e(c) + '\\b' p = re.sub(reg, k[c], p) return p def SAWLIVETV_decryptPlayerParams(p, a, c, k, e, d): def e1(c): if c < a: ret = '' else: ret = e(c / a) c = c % a if c > 35: ret += chr(c+29) else: ret += JS_toString(c, 36) return ret def k1(matchobj): return d[matchobj.group(0)] def e2(t=None): return '\\w+' e = e1 if True: while c != 0: c -= 1 tmp1 = e(c) d[tmp1] = k[c] if '' == d[tmp1]: d[tmp1] = e(c) c = 1 k = [k1] e = e2 while c != 0: c -= 1 if k[c]: reg = '\\b' + e(c) + '\\b' p = re.sub(reg, k[c], p) return p def OPENLOADIO_decryptPlayerParams(p, a, c, k, e, d): def e1(c): return c def e2(t=None): return '\\w+' def k1(matchobj): return d[int(matchobj.group(0))] e = e1 if True: while c != 0: c -= 1 d[c] = k[c] if c < len(k): d[c] = k[c] else: d[c] = c c = 1 k = [k1] e = e2 while c != 0: c -= 1 if k[c]: reg = '\\b' + e(c) + '\\b' p = re.sub(reg, k[c], p) return p def TEAMCASTPL_decryptPlayerParams(p, a, c, k, e=None, d=None): def e1(c): if c < a: ret = '' else: ret = e(c / a) c = c % a if c > 35: ret += chr(c+29) else: ret += JS_toString(c, 36) return ret e = e1 while c != 0: c -= 1 if k[c]: reg = '\\b' + e(c) + '\\b' p = re.sub(reg, k[c], p) return p ############################################################################### # VIDUP.ME HELPER FUNCTIONS ############################################################################### # there is problem in exec when this functions are class methods # sub (even static) or functions # Code example: #
# # #
# # def getParamsTouple(code, type=1, r1=False, r2=False ): mark1Tab = ["}(", "}\r\n(", "}\n(", "}\r("] mark2 = "))" for mark1 in mark1Tab: if r1: idx1 = code.rfind(mark1) else: idx1 = code.find(mark1) if idx1 > -1: break if -1 == idx1: return '' idx1 += len(mark1) if r2: idx2 = code.rfind(mark2, idx1) else: idx2 = code.find(mark2, idx1) if -1 == idx2: return '' idx2 += type return code[idx1:idx2] def unpackJSPlayerParams(code, decryptionFun, type=1, r1=False, r2=False): printDBG('unpackJSPlayerParams') code = getParamsTouple(code, type, r1, r2) return unpackJS(code, decryptionFun) def unpackJS(data, decryptionFun, addCode=''): paramsCode = addCode paramsCode += 'paramsTouple = (' + data + ')' try: paramsAlgoObj = compile(paramsCode, '', 'exec') except: printExc('unpackJS compile algo code EXCEPTION') return '' vGlobals = {"__builtins__": None, 'string': string, 'decodeURIComponent':urllib.unquote, 'unescape':urllib.unquote} vLocals = { 'paramsTouple': None } try: exec( paramsAlgoObj, vGlobals, vLocals ) except: printExc('unpackJS exec code EXCEPTION') return '' # decrypt JS Player params try: return decryptionFun(*vLocals['paramsTouple']) except: printExc('decryptPlayerParams EXCEPTION') return '' def VIDUPME_decryptPlayerParams(p=None, a=None, c=None, k=None, e=None, d=None): while c > 0: c -= 1 if k[c]: p = re.sub('\\b'+ int2base(c, a) +'\\b', k[c], p) return p ############################################################################### ############################################################################### # VIDEOWEED HELPER FUNCTIONS ############################################################################### def VIDEOWEED_decryptPlayerParams(w, i, s, e): lIll = 0 ll1I = 0 Il1l = 0 ll1l = [] l1lI = [] while True: if lIll < 5: l1lI.append(w[lIll]) elif lIll < len(w): ll1l.append(w[lIll]) lIll += 1 if ll1I < 5: l1lI.append(i[ll1I]) elif ll1I < len(i): ll1l.append(i[ll1I]) ll1I += 1 if Il1l < 5: l1lI.append(s[Il1l]) elif Il1l < len(s): ll1l.append(s[Il1l]) Il1l += 1 if len(w) + len(i) + len(s) + len(e) == len(ll1l) + len(l1lI) + len(e): break lI1l = ''.join(ll1l) I1lI = ''.join(l1lI) ll1I = 0 l1ll = [] lIll = 0 while lIll < len(ll1l): ll11 = -1; if ord(I1lI[ll1I]) % 2: ll11 = 1 l1ll.append( JS_FromCharCode( int( lI1l[lIll:lIll+2], 36 ) - ll11 ) ) ll1I += 1; if ll1I >= len(l1lI): ll1I = 0 lIll += 2 return ''.join(l1ll) def VIDEOWEED_decryptPlayerParams2(w, i, s=None, e=None): s = 0 while s < len(w): i += JS_FromCharCode(int(w[s:s+2], 36)) s += 2 return i def VIDEOWEED_unpackJSPlayerParams(code): sts, code = CParsingHelper.rgetDataBeetwenMarkers(code, 'eval(function', '') if not sts: return '' while True: mark1 = "}(" mark2 = "));" idx1 = code.rfind(mark1) if -1 == idx1: return '' idx1 += len(mark1) idx2 = code.rfind(mark2, idx1) if -1 == idx2: return '' #idx2 += 1 paramsCode = 'paramsTouple = (' + code[idx1:idx2] + ')' paramsAlgoObj = compile(paramsCode, '', 'exec') try: paramsAlgoObj = compile(paramsCode, '', 'exec') except: printDBG('unpackJSPlayerParams compile algo code EXCEPTION') return '' vGlobals = {"__builtins__": None, 'string': string} vLocals = { 'paramsTouple': None } try: exec( paramsAlgoObj, vGlobals, vLocals ) except: printDBG('unpackJSPlayerParams exec code EXCEPTION') return '' # decrypt JS Player params code = VIDEOWEED_decryptPlayerParams(*vLocals['paramsTouple']) try: code = VIDEOWEED_decryptPlayerParams(*vLocals['paramsTouple']) if -1 == code.find('eval'): return code except: printDBG('decryptPlayerParams EXCEPTION') return '' return '' def pythonUnescape(data): sourceCode = "retData = '''%s'''" % data try: code = compile(sourceCode, '', 'exec') except: printExc('pythonUnescape compile algo code EXCEPTION') return '' vGlobals = {"__builtins__": None, 'string': string} vLocals = { 'paramsTouple': None } try: exec( code, vGlobals, vLocals ) except: printExc('pythonUnescape exec code EXCEPTION') return '' return vLocals['retData'] ############################################################################### class captchaParser: def __init__(self): pass def textCaptcha(self, data): strTab = [] valTab = [] match = re.compile("padding-(.+?):(.+?)px;padding-top:.+?px;'>(.+?)<").findall(data) if len(match) > 0: for i in range(len(match)): value = match[i] strTab.append(value[2]) strTab.append(int(value[1])) valTab.append(strTab) strTab = [] if match[i][0] == 'left': valTab.sort(key=lambda x: x[1], reverse=False) else: valTab.sort(key=lambda x: x[1], reverse=True) return valTab def reCaptcha(self, data): pass ################################################################################ def decorateUrl(url, metaParams={}): retUrl = strwithmeta( url ) retUrl.meta.update(metaParams) urlLower = url.lower() if 'iptv_proto' not in retUrl.meta: if urlLower.startswith('merge://'): retUrl.meta['iptv_proto'] = 'merge' elif urlLower.split('?')[0].endswith('.m3u8'): retUrl.meta['iptv_proto'] = 'm3u8' elif urlLower.split('?')[0].endswith('.f4m'): retUrl.meta['iptv_proto'] = 'f4m' elif urlLower.startswith('rtmp'): retUrl.meta['iptv_proto'] = 'rtmp' elif urlLower.startswith('https'): retUrl.meta['iptv_proto'] = 'https' elif urlLower.startswith('http'): retUrl.meta['iptv_proto'] = 'http' elif urlLower.startswith('file'): retUrl.meta['iptv_proto'] = 'file' elif urlLower.startswith('rtsp'): retUrl.meta['iptv_proto'] = 'rtsp' elif urlLower.startswith('mms'): retUrl.meta['iptv_proto'] = 'mms' elif urlLower.startswith('mmsh'): retUrl.meta['iptv_proto'] = 'mmsh' elif 'protocol=hls' in url.lower(): retUrl.meta['iptv_proto'] = 'm3u8' return retUrl def getDirectM3U8Playlist(M3U8Url, checkExt=True, variantCheck=True, cookieParams={}): if checkExt and not M3U8Url.split('?')[0].endswith('.m3u8'): return [] cm = common() meta = strwithmeta(M3U8Url).meta params, postData = cm.getParamsFromUrlWithMeta(M3U8Url) params.update(cookieParams) retPlaylists = [] try: finallM3U8Url = meta.get('iptv_m3u8_custom_base_link', '') if '' == finallM3U8Url: params['return_data'] = False sts, response = cm.getPage(M3U8Url, params, postData) finallM3U8Url = response.geturl() data = response.read().strip() response.close() else: sts, data = cm.getPage(M3U8Url, params, postData) data = data.strip() m3u8Obj = m3u8.inits(data, finallM3U8Url) if m3u8Obj.is_variant: for playlist in m3u8Obj.playlists: item = {} if not variantCheck or playlist.absolute_uri.split('?')[-1].endswith('.m3u8'): meta.update({'iptv_proto':'m3u8', 'iptv_bitrate':playlist.stream_info.bandwidth}) item['url'] = strwithmeta(playlist.absolute_uri, meta) else: meta.pop('iptv_proto', None) item['url'] = decorateUrl(playlist.absolute_uri, meta) item['bitrate'] = playlist.stream_info.bandwidth if None != playlist.stream_info.resolution: item['with'] = playlist.stream_info.resolution[0] item['heigth'] = playlist.stream_info.resolution[1] else: item['with'] = 0 item['heigth'] = 0 item['codec'] = playlist.stream_info.codecs item['name'] = "bitrate: %s res: %dx%d kodek: %s" % ( item['bitrate'], \ item['with'], \ item['heigth'], \ item['codec'] ) retPlaylists.append(item) else: item = {'name':'m3u8', 'url':M3U8Url, 'codec':'unknown', 'with':0, 'heigth':0, 'bitrate':'unknown'} retPlaylists.append(item) except: printExc() return retPlaylists def getF4MLinksWithMeta(manifestUrl, checkExt=True): if checkExt and not manifestUrl.split('?')[0].endswith('.f4m'): return [] cm = common() headerParams, postData = cm.getParamsFromUrlWithMeta(manifestUrl) retPlaylists = [] sts, data = cm.getPage(manifestUrl, headerParams, postData) if sts: liveStreamDetected = False if 'live' == CParsingHelper.getDataBeetwenMarkers('', '', False): liveStreamDetected = True bitrates = re.compile('bitrate="([0-9]+?)"').findall(data) for item in bitrates: link = strwithmeta(manifestUrl, {'iptv_proto':'f4m', 'iptv_bitrate':item}) if liveStreamDetected: link.meta['iptv_livestream'] = True retPlaylists.append({'name':'[f4m/hds] bitrate[%s]' % item, 'url':link}) if 0 == len(retPlaylists): link = strwithmeta(manifestUrl, {'iptv_proto':'f4m'}) if liveStreamDetected: link.meta['iptv_livestream'] = True retPlaylists.append({'name':'[f4m/hds]', 'url':link}) return retPlaylists