Python module (submodule repositary), which provides content (video streams) from various online stream sources to corresponding Enigma2, Kodi, Plex plugins

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. # -*- coding: UTF-8 -*-
  2. # * GNU General Public License for more details.
  3. # *
  4. # *
  5. # * You should have received a copy of the GNU General Public License
  6. # * along with this program; see the file COPYING. If not, write to
  7. # * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  8. # * http://www.gnu.org/copyleft/gpl.html
  9. # *
  10. # *
  11. # * based on https://gitorious.org/iptv-pl-dla-openpli/ urlresolver
  12. # */
  13. from StringIO import StringIO
  14. import json
  15. import re
  16. import base64
  17. import urllib
  18. import sys,os
  19. try:
  20. import util
  21. except:
  22. pp = os.path.dirname(os.path.abspath(__file__))
  23. sys.path.insert(0, os.sep.join(pp.split(os.sep)[:-1]))
  24. import util
  25. import requests
  26. try:
  27. from requests.packages.urllib3.exceptions import InsecureRequestWarning
  28. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  29. except:
  30. pass
  31. __author__ = 'ivars777'
  32. __name__ = 'hqq' if __name__ <> "__main__" else __name__
  33. def supports(url):
  34. #return False
  35. return _regex(url) is not None
  36. def _decode(data):
  37. def O1l(string):
  38. ret = ""
  39. i = len(string) - 1
  40. while i >= 0:
  41. ret += string[i]
  42. i -= 1
  43. return ret
  44. def l0I(string):
  45. enc = ""
  46. dec = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
  47. i = 0
  48. while True:
  49. h1 = dec.find(string[i])
  50. i += 1
  51. h2 = dec.find(string[i])
  52. i += 1
  53. h3 = dec.find(string[i])
  54. i += 1
  55. h4 = dec.find(string[i])
  56. i += 1
  57. bits = h1 << 18 | h2 << 12 | h3 << 6 | h4
  58. o1 = bits >> 16 & 0xff
  59. o2 = bits >> 8 & 0xff
  60. o3 = bits & 0xff
  61. if h3 == 64:
  62. enc += unichr(o1)
  63. else:
  64. if h4 == 64:
  65. enc += unichr(o1) + unichr(o2)
  66. else:
  67. enc += unichr(o1) + unichr(o2) + unichr(o3)
  68. if i >= len(string):
  69. break
  70. return enc
  71. escape = re.search("var _escape=\'([^\']+)", l0I(O1l(data))).group(1)
  72. return escape.replace('%', '\\').decode('unicode-escape')
  73. def _decode2(file_url):
  74. def K12K(a, typ='b'):
  75. codec_a = ["G", "L", "M", "N", "Z", "o", "I", "t", "V", "y", "x", "p", "R", "m", "z", "u",
  76. "D", "7", "W", "v", "Q", "n", "e", "0", "b", "="]
  77. codec_b = ["2", "6", "i", "k", "8", "X", "J", "B", "a", "s", "d", "H", "w", "f", "T", "3",
  78. "l", "c", "5", "Y", "g", "1", "4", "9", "U", "A"]
  79. if 'd' == typ:
  80. tmp = codec_a
  81. codec_a = codec_b
  82. codec_b = tmp
  83. idx = 0
  84. while idx < len(codec_a):
  85. a = a.replace(codec_a[idx], "___")
  86. a = a.replace(codec_b[idx], codec_a[idx])
  87. a = a.replace("___", codec_b[idx])
  88. idx += 1
  89. return a
  90. def _xc13(_arg1):
  91. _lg27 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
  92. _local2 = ""
  93. _local3 = [0, 0, 0, 0]
  94. _local4 = [0, 0, 0]
  95. _local5 = 0
  96. while _local5 < len(_arg1):
  97. _local6 = 0
  98. while _local6 < 4 and (_local5 + _local6) < len(_arg1):
  99. _local3[_local6] = _lg27.find(_arg1[_local5 + _local6])
  100. _local6 += 1
  101. _local4[0] = ((_local3[0] << 2) + ((_local3[1] & 48) >> 4))
  102. _local4[1] = (((_local3[1] & 15) << 4) + ((_local3[2] & 60) >> 2))
  103. _local4[2] = (((_local3[2] & 3) << 6) + _local3[3])
  104. _local7 = 0
  105. while _local7 < len(_local4):
  106. if _local3[_local7 + 1] == 64:
  107. break
  108. _local2 += chr(_local4[_local7])
  109. _local7 += 1
  110. _local5 += 4
  111. return _local2
  112. return _xc13(K12K(file_url, 'e'))
  113. def resolve(url):
  114. m = _regex(url)
  115. if m:
  116. headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  117. 'Content-Type': 'text/html; charset=utf-8'}
  118. if "goo.gl" in url:
  119. data = util.request(url, headers)
  120. player_url = re.search("var ppage = '(.+?)'",data).group(1)
  121. player_url = urllib.unquote(player_url)
  122. else:
  123. vid = m.group('vid')
  124. player_url = "http://hqq.tv/player/embed_player.php?vid=%s&autoplay=no" % vid
  125. data = util.request(player_url, headers)
  126. b64enc = re.search('base64([^\"]+)', data, re.DOTALL)
  127. b64dec = b64enc and base64.decodestring(b64enc.group(1))
  128. enc = b64dec and re.search("\'([^']+)\'", b64dec).group(1)
  129. if enc:
  130. data = re.findall('<input name="([^"]+?)" [^>]+? value="([^"]+?)">', _decode(enc))
  131. post_data = {}
  132. for idx in range(len(data)):
  133. post_data[data[idx][0]] = data[idx][1]
  134. data = util.post(player_url, post_data, headers)
  135. b64enc = re.search('base64([^\"]+)', data, re.DOTALL)
  136. b64dec = b64enc and base64.decodestring(b64enc.group(1))
  137. enc = b64dec and re.search("\'([^']+)\'", b64dec).group(1)
  138. if enc:
  139. data = re.findall('<input name="([^"]+?)" [^>]+? value="([^"]*)">', _decode(enc))
  140. post_data = {}
  141. for idx in range(len(data)):
  142. post_data[data[idx][0]] = data[idx][1]
  143. data = urllib.unquote(util.request("http://hqq.tv/sec/player/embed_player.php?" +
  144. urllib.urlencode(post_data), headers))
  145. server_1 = re.search("server_1: (\w+)",data).group(1)
  146. link_1 = re.search("link_1: (\w+)",data).group(1)
  147. vid_server = re.search(r'var\s*%s\s*=\s*"([^"]*?)"'%server_1, data)
  148. vid_link = re.search(r'var\s*%s\s*=\s*"([^"]*?)"'%link_1, data)
  149. at = re.search(r'var\s*at\s*=\s*"([^"]*?)"', data)
  150. vid = re.search('vid: "([^"]+)"',data)
  151. sub_url = re.search('sub:"(.+?)"',data).group(1) if re.search('sub:"(.+?)"',data) else ""
  152. subs_lang = re.search('sublangs:"(.+?)"',data).group(1) if re.search('sub:"(.+?)"',data) else ""
  153. if sub_url:
  154. subs=[{"url":sub_url,'name':subs_lang,"lang":subs_lang}]
  155. else:
  156. subs = []
  157. if vid_server and vid_link and at:
  158. get_data = {'server_1': vid_server.group(1),
  159. 'link_1': vid_link.group(1),
  160. 'at': at.group(1),
  161. 'adb': '0/',
  162. 'b':'1',
  163. 'vid': vid.group(1)}
  164. # X-Requested-With: XMLHttpRequest
  165. headers["X-Requested-With"] = "XMLHttpRequest"
  166. html = util.request("http://hqq.tv/player/get_md5.php?"+urllib.urlencode(get_data), headers)
  167. data = json.load(StringIO(html))
  168. if 'file' in data:
  169. file_url = _decode2(data['file'])
  170. file_url = re.sub(r'\?socket=?$', '.mp4.m3u8',file_url)
  171. stream = {
  172. 'url': file_url,
  173. 'name': file_url,
  174. 'subs':subs,
  175. 'quality': 'hqq',
  176. 'resolver': 'hqq',
  177. "headers":{"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/47.0.2526.70 Mobile/13C71 Safari/601.1.46"}
  178. }
  179. return [stream]
  180. return []
  181. def _regex(url):
  182. # https://goo.gl/yMTzqf
  183. match = re.search("(hqq|netu)\.tv/watch_video\.php\?v=(?P<vid>[0-9A-Z]+)", url)
  184. if match:
  185. return match
  186. match = re.search(r'(hqq|netu)\.tv/player/embed_player\.php\?vid=(?P<vid>[0-9A-Za-z]+)', url)
  187. if match:
  188. return match
  189. match = re.search(r'(hqq|netu)\.tv/player/hash\.php\?hash=\d+', url)
  190. if match:
  191. match = re.search(r'var\s+vid\s*=\s*\'(?P<vid>[^\']+)\'', urllib.unquote(util.request(url)))
  192. if match:
  193. return match
  194. # https://goo.gl/yMTzqf
  195. match = re.search("(goo)\.gl/(?P<vid>[\w]+)", url)
  196. if match:
  197. return match
  198. b64enc = re.search(r'data:text/javascript\;charset\=utf\-8\;base64([^\"]+)', url)
  199. b64dec = b64enc and base64.decodestring(b64enc.group(1))
  200. enc = b64dec and re.search(r"\'([^']+)\'", b64dec).group(1)
  201. if enc:
  202. decoded = _decode(enc)
  203. match = re.search(r'<input name="vid"[^>]+? value="(?P<vid>[^"]+?)">', decoded)
  204. if re.search(r'<form(.+?)action="[^"]*(hqq|netu)\.tv/player/embed_player\.php"[^>]*>',
  205. decoded) and match:
  206. return match
  207. return None
  208. if __name__ == "__main__":
  209. url = "http://hqq.tv/player/embed_player.php?vid=nYAKgzBAf7ll"
  210. streams = resolve(url)
  211. if not streams:
  212. print "No streams found"
  213. sys.exit()
  214. for s in streams:
  215. print s
  216. print streams[0]["url"]
  217. util.play_video(streams)
  218. pass