Advertisement
Guest User

Untitled

a guest
Jun 17th, 2010
376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.25 KB | None | 0 0
  1. Skunkworks:addons davilla$ cat plugin.hulu2/resources/lib/stream_hulu.py
  2. import xbmc
  3. import xbmcgui
  4. import xbmcplugin
  5. import common
  6. import re
  7. import sys
  8. import binascii
  9. import struct
  10. #if struct module does not contain class Struct, use wrapper provided instead
  11. if not 'Struct' in dir(struct):
  12. import pystruct as struct
  13. from aes import AES #wrapper around PyCrypto and pure python CryptoPy
  14. try:
  15. from Crypto.Hash import MD5
  16. except ImportError:
  17. import md5 as MD5
  18. from BeautifulSoup import BeautifulSoup, BeautifulStoneSoup
  19.  
  20. class Main:
  21.  
  22. def __init__( self ):
  23. #select from avaliable streams, then play the file
  24. self.play()
  25.  
  26. def decrypt_id(self, p):
  27. cp_strings = [
  28. '6fe8131ca9b01ba011e9b0f5bc08c1c9ebaf65f039e1592d53a30def7fced26c',
  29. 'd3802c10649503a60619b709d1278ffff84c1856dfd4097541d55c6740442d8b',
  30. 'c402fb2f70c89a0df112c5e38583f9202a96c6de3fa1aa3da6849bb317a983b3',
  31. 'e1a28374f5562768c061f22394a556a75860f132432415d67768e0c112c31495',
  32. 'd3802c10649503a60619b709d1278efef84c1856dfd4097541d55c6740442d8b'
  33. ]
  34.  
  35. v3 = p.split("~")
  36. v3a = binascii.unhexlify(v3[0])
  37. v3b = binascii.unhexlify(v3[1])
  38.  
  39. ecb = AES(v3b)
  40. tmp = ecb.decrypt(v3a)
  41.  
  42. for v1 in cp_strings[:]:
  43. ecb = AES(binascii.unhexlify(v1))
  44. v2 = ecb.decrypt(tmp)
  45. if (re.match("[0-9A-Za-z_-]{32}", v2)):
  46. return v2
  47.  
  48. def decrypt_SMIL(self, encsmil):
  49. encdata = binascii.unhexlify(encsmil)
  50.  
  51. xmldeckeys = [
  52. ['B7F67F4B985240FAB70FF1911FCBB48170F2C86645C0491F9B45DACFC188113F',
  53. 'uBFEvpZ00HobdcEo'],
  54. ['3484509D6B0B4816A6CFACB117A7F3C842268DF89FCC414F821B291B84B0CA71',
  55. 'SUxSFjNUavzKIWSh'],
  56. ['1F0FF021B7A04B96B4AB84CCFD7480DFA7A972C120554A25970F49B6BADD2F4F',
  57. 'tqo8cxuvpqc7irjw'],
  58. ['76A9FDA209D4C9DCDFDDD909623D1937F665D0270F4D3F5CA81AD2731996792F',
  59. 'd9af949851afde8c'],
  60. ['852AEA267B737642F4AE37F5ADDF7BD93921B65FE0209E47217987468602F337',
  61. 'qZRiIfTjIGi3MuJA'],
  62. ['8CE8829F908C2DFAB8B3407A551CB58EBC19B07F535651A37EBC30DEC33F76A2',
  63. 'O3r9EAcyEeWlm5yV'],
  64. ['246DB3463FC56FDBAD60148057CB9055A647C13C02C64A5ED4A68F81AE991BF5',
  65. 'vyf8PvpfXZPjc7B1'],
  66. ['4878B22E76379B55C962B18DDBC188D82299F8F52E3E698D0FAF29A40ED64B21',
  67. 'WA7hap7AGUkevuth']
  68. ]
  69.  
  70. for key in xmldeckeys[:]:
  71. smil=""
  72. out=[0,0,0,0]
  73. ecb = AES(binascii.unhexlify(key[0]))
  74. unaes = ecb.decrypt(encdata)
  75.  
  76. packer = struct.Struct("iiii")
  77. xorkey = packer.unpack(key[1])
  78.  
  79. for i in range(0, len(encdata)/16):
  80. x = unaes[i*16:i*16+16]
  81. res = packer.unpack(x)
  82. for j in range(0,4):
  83. out[j] = res[j] ^ xorkey[j]
  84. x = encdata[i*16:i*16+16]
  85. xorkey = packer.unpack(x)
  86. x = packer.pack(out[0],out[1],out[2],out[3])
  87. smil = smil + x
  88.  
  89. if (smil.find("<smil") == 0):
  90. i = smil.rfind("</smil>")
  91. smil = smil[0:i+7]
  92. return smil
  93.  
  94. def play( self ):
  95. #getCID
  96. print common.args.url
  97. html=common.getHTML(common.args.url)
  98. if common.args.mode == 'HD_play':
  99. p=re.compile('swfObject.addVariable\("content_id", ([0-9]*)\);')
  100. else:
  101. p=re.compile('UserHistory.add_watched_history\((.+?)\)')
  102. cid=p.findall(html)[0]
  103. cid="http://r.hulu.com/videos?content_id="+cid
  104. #getPID
  105. html=common.getHTML(cid)
  106. cidSoup=BeautifulStoneSoup(html)
  107. pid=cidSoup.findAll('pid')[0].contents[0]
  108. pid=self.decrypt_id(pid)
  109. m=MD5.new()
  110. m.update(str(pid) + "yumUsWUfrAPraRaNe2ru2exAXEfaP6Nugubepreb68REt7daS79fase9haqar9sa")
  111. auth=m.hexdigest()
  112. print auth
  113.  
  114. #getSMIL
  115. #smilURL = "http://releasegeo.hulu.com/content.select?pid=" + hulu_decrypt_id(pid) + "&mbr=true&format=smil"
  116. smilURL = "http://s.hulu.com/select.ashx?pid=" + pid + "&auth=" + auth + "&v=810006400"
  117. print 'HULU --> SMILURL: ' + smilURL
  118. smilXML=common.getHTML(smilURL)
  119. tmp=self.decrypt_SMIL(smilXML)
  120. smilSoup=BeautifulStoneSoup(tmp)
  121. print smilSoup.prettify()
  122. #getRTMP
  123. video=smilSoup.findAll('video')
  124. streams=[]
  125. selectedStream = None
  126. qtypes=['ask', 'H264 Medium', 'H264 650K', 'H264 400K',
  127. 'High', 'Medium', 'Low']
  128.  
  129. #label streams
  130. qt = int(common.settings['quality'])
  131. if qt < 0 or qt > 6: qt = 0
  132.  
  133. while qt < 6:
  134. qtext = qtypes[qt]
  135.  
  136. for vid in video:
  137. if qt == 0:
  138. streams.append([vid['profile'],vid['src']])
  139. if qt > 3 and 'H264' in vid['profile']: continue
  140. if qtext in vid['profile']:
  141. selectedStream = vid['src']
  142. break
  143.  
  144. if qt == 0 or selectedStream != None: break
  145. qt += 1
  146.  
  147. if qt == 0 or selectedStream == None:
  148. #ask user for quality level
  149. quality=xbmcgui.Dialog().select('Please select a quality level:', [stream[0] for stream in streams])
  150. print quality
  151. if quality!=-1:
  152. selectedStream = streams[quality][1]
  153. print "stream url"
  154. print selectedStream
  155. if selectedStream != None:
  156. #form proper streaming url
  157. rawurl=selectedStream.replace('&amp;','&').replace('&lt;','<').replace('&gt;','>')
  158. mainParts = rawurl.split("?")
  159. protocolSplit = rawurl.split("://")
  160.  
  161. pathSplit = protocolSplit[1].split("/");
  162.  
  163. server = pathSplit[0];
  164. appName = pathSplit[1];
  165.  
  166. videoIdentIp = server
  167. protocol = "rtmpe";
  168. port = "1935";
  169.  
  170. if "hulufs" in mainParts[0]:
  171. fileName = rawurl.split(appName + "/")[1]
  172.  
  173. else:
  174. queryStringParts = mainParts[1].split("&")
  175. v9 = queryStringParts[0]
  176. v6 = queryStringParts[1]
  177.  
  178. if "<break>" in queryStringParts[2]:
  179. breakParts = queryStringParts[2].split("<break>")
  180. v3 = breakParts[0];
  181. fileName = breakParts[1]
  182. else:
  183. v3 = queryStringParts[2]
  184. breakFilenameURL = mainParts[0].split("://");
  185. breakFilenamedir = breakFilenameURL[1].split("/");
  186. breakFilenames = breakFilenameURL[1].split(breakFilenamedir[1] + "/")
  187. fileName = breakFilenames[1]
  188.  
  189. appName += "?_fcs_vhost=" + server + "&" + v9 + "&" + v6 + "&" + v3
  190.  
  191.  
  192. newUrl = protocol + "://" + videoIdentIp + ":" + port + "/" + appName
  193. print "item url -- > " + newUrl
  194. print "playPath -- > " + fileName
  195. if common.args.mode == 'HD_play':
  196. SWFPlayer = 'http://www.hulu.com/playerHD.swf'
  197. else:
  198. SWFPlayer = 'http://www.hulu.com/player.swf'
  199.  
  200. #define item
  201. item = xbmcgui.ListItem(common.args.name)
  202. newUrl = newUrl + " swfurl=" + SWFPlayer + " playpath=" + fileName + " pageurl=" + common.args.url
  203. # item.setProperty("SWFPlayer", SWFPlayer)
  204. # item.setProperty("PlayPath", fileName)
  205. # item.setProperty("PageURL", common.args.url)
  206. #
  207. if common.settings['resolution_hack']:
  208. ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=newUrl,listitem=item)
  209. xbmcplugin.endOfDirectory( handle=int( sys.argv[ 1 ] ), updateListing=False, succeeded=ok)
  210. else:
  211. playlist = xbmc.PlayList(1)
  212. playlist.clear()
  213. playlist.add(newUrl, item)
  214. play=xbmc.Player().play(playlist)
  215. xbmc.executebuiltin('XBMC.ActivateWindow(fullscreenvideo)')
  216.  
  217.  
  218. Skunkworks:addons davilla$
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement