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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #!/usr/bin/env python
  2. # coding=utf8
  3. #
  4. # This file is part of PlayStream - enigma2 plugin to play video streams from various sources
  5. # Copyright (c) 2016 ivars777 (ivars777@gmail.com)
  6. # Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
  7. #
  8. try:
  9. import json
  10. except:
  11. import simplejson as json
  12. import urllib2, urllib
  13. import binascii
  14. import datetime, re, sys,os, time
  15. import ConfigParser
  16. from collections import OrderedDict
  17. from SourceBase import SourceBase
  18. import requests
  19. import ssl
  20. if "_create_unverified_context" in dir(ssl):
  21. ssl._create_default_https_context = ssl._create_unverified_context
  22. try:
  23. from requests.packages.urllib3.exceptions import InsecureRequestWarning
  24. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  25. except:
  26. pass
  27. #import resolver
  28. try:
  29. import util
  30. except:
  31. sys.path.insert(0,'..')
  32. import util
  33. headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
  34. class Source(SourceBase):
  35. def __init__(self, country="",cfg_path=None):
  36. self.hidden = False # nerāda menu nestrādājošos avotus
  37. self.name = "filmas"
  38. self.title = "Filmas.lv"
  39. self.img = "filmas.png"
  40. self.desc = "Filmas.lv - Latvijas filmas"
  41. self.headers = headers2dict("""
  42. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
  43. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  44. Accept-Language: en-US,en;q=0.5
  45. Accept-Encoding: gzip, deflate, br
  46. """)
  47. self.headers2 = headers2dict("""
  48. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
  49. X-Requested-With: XMLHttpRequest
  50. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  51. """)
  52. self.url = "https://www.filmas.lv/"
  53. ######### Entry point ########
  54. def get_content(self, data):
  55. print "[filmas] get_content:", data
  56. source, data, path, plist, clist, params, qs = self.parse_data(data)
  57. content = []
  58. content.append(("..return", "back","back.png","Return back"))
  59. if clist=="home":
  60. content.extend([
  61. ("Meklēt", "filmas::lmdb/api/search/?term={0}","","Meklēt"),
  62. ("Visas", "filmas::filmu-katalogs/?tab=movies&sub_tab=movies-all&watch=latvia&pg=1","","Latvijā skatamās visas filmas"),
  63. ("Spēlfilmas", "filmu-katalogs/?tab=movies&sub_tab=movies-all&mp20=112&watch=latvia&pg=1","","Latvijā skatamās spēlfilmas"),
  64. ("Dokumentalās filmas", "filmas::filmu-katalogs/?tab=movies&sub_tab=movies-hronika&pg=1","","Latvijā skatamās kinohronikas") ,
  65. ("Animācijas filmas", "filmu-katalogs/?tab=movies&sub_tab=movies-all&mp20=113&watch=latvia&pg=1","","Latvijā skatamās animācijas filmas"),
  66. ("Kinohronikas", "filmas::filmu-katalogs/filmu-katalogs/?tab=movies&sub_tab=movies-hronika","","Latvijā skatamās kinohronikas") ,
  67. ("Pēc alfabēta", "filmas::filmu-katalogs/?ml=A&tab=movies&sub_tab=movies-abc&pg=1","","Latvija skatamās filmas pēc alfabēta") ,
  68. ])
  69. return content
  70. elif "api/search" in data:
  71. r = self.call(data)
  72. js = json.loads(r)
  73. for it in js:
  74. if "type" in it and it["type"] == "movie":
  75. title = it["label"] + "(%s)" % it["year"] if "year" in it else ""
  76. img = ("https://www.filmas.lv/images/movies/" + it["photo"]) if "photo" in it and it["photo"] else ""
  77. desc = title
  78. data2 = "movie/%s" % it["value"]
  79. content.append((title,self.name+"::"+data2,img,desc))
  80. return content
  81. elif clist=="filmu-katalogs":
  82. r=self.call(data)
  83. result = re.findall(r'<a href="/(movie/\d+)">.+?src="([^"]+)".+?"movie-catalog-title">([^<]+)<.+?"movie-catalog-year">([^<]+)<', r, re.DOTALL)
  84. for item in result:
  85. title = item[2]+' (%s)'%item[3]
  86. data2 = item[0]
  87. img = item[1]
  88. desc = title
  89. content.append((title,self.name+"::"+data2,img,desc))
  90. m = re.search("<a class='next' href='(.+?)'", r, re.DOTALL)
  91. if m:
  92. data2 = "filmu-katalogs/"+m.group(1)
  93. content.append(("Next page",self.name+"::"+data2, "","Next page"))
  94. return content
  95. ### kaut kas neparedzets ###
  96. else:
  97. return content
  98. def is_video(self,data):
  99. source,data,path,plist,clist,params,qs = self.parse_data(data)
  100. if clist=="movie":
  101. return True
  102. else:
  103. return False
  104. def call(self, data,params=None,headers=None,lang=""):
  105. if not headers: headers = self.headers
  106. url = self.url+data
  107. result = self._http_request(url,params,headers=headers)
  108. return result
  109. def get_streams(self,data):
  110. print "[filmas] get_streams:", data
  111. source, data, path, plist, clist, params, qs = self.parse_data(data)
  112. streams = []
  113. url = self.url+data
  114. mid = data.split("/")[1]
  115. r = requests.get(url, headers=self.headers, verify=False)
  116. if not "PHPSESSID" in r.cookies:
  117. return streams
  118. phpsessid = r.cookies["PHPSESSID"]
  119. ### Main playlist ###
  120. m = re.search('lmdb.video_src = "/(.+?m3u8)"', r.content)
  121. url = "https://www.filmas.lv/%s"%m.group(1)
  122. headers = headers2dict("""
  123. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
  124. Accept: */*
  125. Accept-Language: en-US,en;q=0.5
  126. Accept-Encoding: gzip, deflate, br
  127. Referer: https://www.filmas.lv/movie/%s/
  128. """%mid)
  129. r = requests.get(url, headers=headers, verify=False, cookies={"phpsessid":phpsessid} )
  130. filmassession = r.cookies["filmassession"]
  131. result = re.findall(r'#EXT-X-STREAM-INF:PROGRAM-ID=(\d+),BANDWIDTH=(\d+),RESOLUTION=(.+?),CODECS="(.+?)"\n(.+?)$', r.content, re.IGNORECASE | re.MULTILINE)
  132. title = url.split("/")[-1].split(".")[0]
  133. ### Initial key requests
  134. url = "https://www.filmas.lv/lmdb/hls/key/request/%s?%s"%(mid,int(time.time()))
  135. r=requests.get(url,headers=headers,cookies = {"filmassession":filmassession}, verify=False )
  136. filmassession = r.cookies["filmassession"]
  137. ### Metada ###
  138. url = "https://www.filmas.lv/charts/api/api/?method=search_movie&query=%s"%mid
  139. r = requests.get(url, headers=headers, verify=False)
  140. if not "error" in r.content:
  141. title = r.json()["nodes"][0]["name"]
  142. img = self.url+r.json()["nodes"][0]["image"]
  143. desc = r.json()["nodes"][0]["plot"]
  144. else:
  145. img = desc = ""
  146. for h in result:
  147. url = h[4]
  148. ### Key request ###
  149. headers["Origin"] = "https://www.filmas.lv"
  150. headers["Referer"] = "https://www.filmas.lv/" + data
  151. headers["Cookie"] = 'filmassession=%s; PHPSESSID=%s' % (filmassession, phpsessid)
  152. #r=requests.get(url,headers=headers, verify=False)
  153. #url_key = re.search('#EXT-X-KEY:METHOD=AES-128,URI="(.+?)"', r.content, re.IGNORECASE | re.MULTILINE).group(1)
  154. #r=requests.get(url_key,headers=headers, cookies={"filmassession":filmassession,"PHPSESSID":phpsessid}, verify=False)
  155. #key = r.content if not "error" in r.content else ""
  156. stream = util.item()
  157. stream["name"] = title
  158. stream["url"] = url
  159. stream["img"] = img
  160. stream["desc"] = desc
  161. stream["headers"] = headers #{"key":binascii.b2a_hex(key)}
  162. stream["quality"] = h[2]
  163. stream["order"] = int(h[1])
  164. stream["resolver"] = "filmas"
  165. streams.append(stream)
  166. return sorted(streams,key=lambda item: item["order"],reverse=True)
  167. def download_hls(url, title, download_dir="", headers=None, overwrite=True):
  168. UA = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0"
  169. if not headers:
  170. headers = {"User-Agent" : UA}
  171. key = headers["key"] if "key" in headers else ""
  172. if not "User-Agent" in headers:
  173. headers["User-Agent"] = UA
  174. tsname = os.path.join(download_dir,title+".ts")
  175. if not os.path.exists(tsname) or overwrite:
  176. tsfile = open(tsname,"wb")
  177. print "Downloading ", tsname
  178. try:
  179. r=requests.get(url,headers=headers, verify=False)
  180. except Exception as e:
  181. print "Got Exception: ", str(e)
  182. import traceback
  183. traceback.print_exc()
  184. sys.exit()
  185. ts_list = re.findall(r"#EXTINF:([\d\.]+),\n(.+?)$", r.content, re.IGNORECASE | re.MULTILINE)
  186. for ts in ts_list:
  187. url2 = ts[1]
  188. #print "Downloading ", url2
  189. #fname = os.path.join(download_dir,url2.split("/")[-1])
  190. r = requests.get(url2, headers=headers, verify=False)
  191. content = r.content
  192. if key:
  193. from Crypto.Cipher import AES
  194. key2 = binascii.a2b_hex(key)
  195. iv = content[:16]
  196. d = AES.new(key2, AES.MODE_CBC, iv)
  197. content = d.decrypt(content[16:])
  198. #with open(fname,"wb") as f:
  199. #f.write(content)
  200. tsfile.write(content)
  201. #lfile.write("file '%s'"%fname)
  202. #lfile.close()
  203. tsfile.close()
  204. from subprocess import call
  205. cmd = [r"ffmpeg.exe","-i", tsname.encode(sys.getfilesystemencoding()), "-c","copy", os.path.join(download_dir,title+".mp4").encode(sys.getfilesystemencoding())]
  206. ret = call(cmd)
  207. if __name__ == "__main__":
  208. #url = "http://localhost:88/https%3A//as2.filmas.lv/FilmasLV/508D4024A83FDC1AA61D727DE5046D12/index-f3-v1-a1.m3u8?~key=4cb5c12b2aaa3d2cf211583cc9add2dd"
  209. #download_hls(url, "video", "")
  210. # c = Source()
  211. # if len(sys.argv)>1:
  212. # data= sys.argv[1]
  213. # else:
  214. # data = "movie/3112/"
  215. # if "movie" in data:
  216. # if data.startswith("http"):
  217. # data = data.replace("https://www.filmas.lv/","")
  218. # streams = c.get_streams(data)
  219. # #for s in streams:
  220. # s = streams[0]
  221. # download_hls(s["url"],"%s %s"%(s["name"],s["quality"]),"",s["headers"])
  222. # sys.exit()
  223. sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
  224. import run
  225. source = Source()
  226. data= sys.argv[1] if len(sys.argv)>1 else source.name+"::home"
  227. run.run(source, data)
  228. sys.exit()