Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Skunkworks:addons davilla$ cat plugin.hulu2/resources/lib/stream_hulu.py
- import xbmc
- import xbmcgui
- import xbmcplugin
- import common
- import re
- import sys
- import binascii
- import struct
- #if struct module does not contain class Struct, use wrapper provided instead
- if not 'Struct' in dir(struct):
- import pystruct as struct
- from aes import AES #wrapper around PyCrypto and pure python CryptoPy
- try:
- from Crypto.Hash import MD5
- except ImportError:
- import md5 as MD5
- from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
- class Main:
- def __init__( self ):
- #select from avaliable streams, then play the file
- self.play()
- def decrypt_id(self, p):
- cp_strings = [
- '6fe8131ca9b01ba011e9b0f5bc08c1c9ebaf65f039e1592d53a30def7fced26c',
- 'd3802c10649503a60619b709d1278ffff84c1856dfd4097541d55c6740442d8b',
- 'c402fb2f70c89a0df112c5e38583f9202a96c6de3fa1aa3da6849bb317a983b3',
- 'e1a28374f5562768c061f22394a556a75860f132432415d67768e0c112c31495',
- 'd3802c10649503a60619b709d1278efef84c1856dfd4097541d55c6740442d8b'
- ]
- v3 = p.split("~")
- v3a = binascii.unhexlify(v3[0])
- v3b = binascii.unhexlify(v3[1])
- ecb = AES(v3b)
- tmp = ecb.decrypt(v3a)
- for v1 in cp_strings[:]:
- ecb = AES(binascii.unhexlify(v1))
- v2 = ecb.decrypt(tmp)
- if (re.match("[0-9A-Za-z_-]{32}", v2)):
- return v2
- def decrypt_SMIL(self, encsmil):
- encdata = binascii.unhexlify(encsmil)
- xmldeckeys = [
- ['B7F67F4B985240FAB70FF1911FCBB48170F2C86645C0491F9B45DACFC188113F',
- 'uBFEvpZ00HobdcEo'],
- ['3484509D6B0B4816A6CFACB117A7F3C842268DF89FCC414F821B291B84B0CA71',
- 'SUxSFjNUavzKIWSh'],
- ['1F0FF021B7A04B96B4AB84CCFD7480DFA7A972C120554A25970F49B6BADD2F4F',
- 'tqo8cxuvpqc7irjw'],
- ['76A9FDA209D4C9DCDFDDD909623D1937F665D0270F4D3F5CA81AD2731996792F',
- 'd9af949851afde8c'],
- ['852AEA267B737642F4AE37F5ADDF7BD93921B65FE0209E47217987468602F337',
- 'qZRiIfTjIGi3MuJA'],
- ['8CE8829F908C2DFAB8B3407A551CB58EBC19B07F535651A37EBC30DEC33F76A2',
- 'O3r9EAcyEeWlm5yV'],
- ['246DB3463FC56FDBAD60148057CB9055A647C13C02C64A5ED4A68F81AE991BF5',
- 'vyf8PvpfXZPjc7B1'],
- ['4878B22E76379B55C962B18DDBC188D82299F8F52E3E698D0FAF29A40ED64B21',
- 'WA7hap7AGUkevuth']
- ]
- for key in xmldeckeys[:]:
- smil=""
- out=[0,0,0,0]
- ecb = AES(binascii.unhexlify(key[0]))
- unaes = ecb.decrypt(encdata)
- packer = struct.Struct("iiii")
- xorkey = packer.unpack(key[1])
- for i in range(0, len(encdata)/16):
- x = unaes[i*16:i*16+16]
- res = packer.unpack(x)
- for j in range(0,4):
- out[j] = res[j] ^ xorkey[j]
- x = encdata[i*16:i*16+16]
- xorkey = packer.unpack(x)
- x = packer.pack(out[0],out[1],out[2],out[3])
- smil = smil + x
- if (smil.find("<smil") == 0):
- i = smil.rfind("</smil>")
- smil = smil[0:i+7]
- return smil
- def play( self ):
- #getCID
- print common.args.url
- html=common.getHTML(common.args.url)
- if common.args.mode == 'HD_play':
- p=re.compile('swfObject.addVariable\("content_id", ([0-9]*)\);')
- else:
- p=re.compile('UserHistory.add_watched_history\((.+?)\)')
- cid=p.findall(html)[0]
- cid="http://r.hulu.com/videos?content_id="+cid
- #getPID
- html=common.getHTML(cid)
- cidSoup=BeautifulStoneSoup(html)
- pid=cidSoup.findAll('pid')[0].contents[0]
- pid=self.decrypt_id(pid)
- m=MD5.new()
- m.update(str(pid) + "yumUsWUfrAPraRaNe2ru2exAXEfaP6Nugubepreb68REt7daS79fase9haqar9sa")
- auth=m.hexdigest()
- print auth
- #getSMIL
- #smilURL = "http://releasegeo.hulu.com/content.select?pid=" + hulu_decrypt_id(pid) + "&mbr=true&format=smil"
- smilURL = "http://s.hulu.com/select.ashx?pid=" + pid + "&auth=" + auth + "&v=810006400"
- print 'HULU --> SMILURL: ' + smilURL
- smilXML=common.getHTML(smilURL)
- tmp=self.decrypt_SMIL(smilXML)
- smilSoup=BeautifulStoneSoup(tmp)
- print smilSoup.prettify()
- #getRTMP
- video=smilSoup.findAll('video')
- streams=[]
- selectedStream = None
- qtypes=['ask', 'H264 Medium', 'H264 650K', 'H264 400K',
- 'High', 'Medium', 'Low']
- #label streams
- qt = int(common.settings['quality'])
- if qt < 0 or qt > 6: qt = 0
- while qt < 6:
- qtext = qtypes[qt]
- for vid in video:
- if qt == 0:
- streams.append([vid['profile'],vid['src']])
- if qt > 3 and 'H264' in vid['profile']: continue
- if qtext in vid['profile']:
- selectedStream = vid['src']
- break
- if qt == 0 or selectedStream != None: break
- qt += 1
- if qt == 0 or selectedStream == None:
- #ask user for quality level
- quality=xbmcgui.Dialog().select('Please select a quality level:', [stream[0] for stream in streams])
- print quality
- if quality!=-1:
- selectedStream = streams[quality][1]
- print "stream url"
- print selectedStream
- if selectedStream != None:
- #form proper streaming url
- rawurl=selectedStream.replace('&','&').replace('<','<').replace('>','>')
- mainParts = rawurl.split("?")
- protocolSplit = rawurl.split("://")
- pathSplit = protocolSplit[1].split("/");
- server = pathSplit[0];
- appName = pathSplit[1];
- videoIdentIp = server
- protocol = "rtmpe";
- port = "1935";
- if "hulufs" in mainParts[0]:
- fileName = rawurl.split(appName + "/")[1]
- else:
- queryStringParts = mainParts[1].split("&")
- v9 = queryStringParts[0]
- v6 = queryStringParts[1]
- if "<break>" in queryStringParts[2]:
- breakParts = queryStringParts[2].split("<break>")
- v3 = breakParts[0];
- fileName = breakParts[1]
- else:
- v3 = queryStringParts[2]
- breakFilenameURL = mainParts[0].split("://");
- breakFilenamedir = breakFilenameURL[1].split("/");
- breakFilenames = breakFilenameURL[1].split(breakFilenamedir[1] + "/")
- fileName = breakFilenames[1]
- appName += "?_fcs_vhost=" + server + "&" + v9 + "&" + v6 + "&" + v3
- newUrl = protocol + "://" + videoIdentIp + ":" + port + "/" + appName
- print "item url -- > " + newUrl
- print "playPath -- > " + fileName
- if common.args.mode == 'HD_play':
- SWFPlayer = 'http://www.hulu.com/playerHD.swf'
- else:
- SWFPlayer = 'http://www.hulu.com/player.swf'
- #define item
- item = xbmcgui.ListItem(common.args.name)
- newUrl = newUrl + " swfurl=" + SWFPlayer + " playpath=" + fileName + " pageurl=" + common.args.url
- # item.setProperty("SWFPlayer", SWFPlayer)
- # item.setProperty("PlayPath", fileName)
- # item.setProperty("PageURL", common.args.url)
- #
- if common.settings['resolution_hack']:
- ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=newUrl,listitem=item)
- xbmcplugin.endOfDirectory( handle=int( sys.argv[ 1 ] ), updateListing=False, succeeded=ok)
- else:
- playlist = xbmc.PlayList(1)
- playlist.clear()
- playlist.add(newUrl, item)
- play=xbmc.Player().play(playlist)
- xbmc.executebuiltin('XBMC.ActivateWindow(fullscreenvideo)')
- Skunkworks:addons davilla$
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement