Enigma2 plugin to to play various online streams (mostly Latvian).

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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 requests
  13. try:
  14. from requests.packages.urllib3.exceptions import InsecureRequestWarning
  15. requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
  16. except:
  17. pass
  18. import urlparse, urllib
  19. import datetime, time,re, sys,os
  20. from collections import OrderedDict
  21. import ssl
  22. if "_create_unverified_context" in dir(ssl):
  23. ssl._create_default_https_context = ssl._create_unverified_context
  24. from SourceBase import SourceBase
  25. try:
  26. import util
  27. except:
  28. parent = os.path.dirname(os.path.abspath(__file__))
  29. parent = os.sep.join(parent.split(os.sep)[:-1])
  30. sys.path.insert(0,parent)
  31. import util
  32. headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
  33. class Source(SourceBase):
  34. def __init__(self,language="en",cfg_path=None):
  35. self.name = "viaplay"
  36. self.title = "viaplay.lv"
  37. self.img = "https://yt3.ggpht.com/-noVdjbNR-V8/AAAAAAAAAAI/AAAAAAAAAAA/yZ9XNP5urLY/s900-c-k-no-mo-rj-c0xffffff/photo.jpg"
  38. self.desc = "Viaplay.lv saturs"
  39. self.url = "https://viaplay.lv/"
  40. self.headers = headers2dict("""
  41. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
  42. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  43. Connection: keep-alive
  44. Upgrade-Insecure-Requests: 1
  45. """)
  46. #self.language=language
  47. cur_directory = os.path.dirname(os.path.abspath(__file__))
  48. if not cfg_path: cfg_path = cur_directory
  49. self.config_file = os.path.join(cfg_path,self.name+".cfg")
  50. self.options = OrderedDict([("user","change_user"),("password","change_password"),("device","")])
  51. self.options_read()
  52. self.device = self.options["device"]
  53. self.r = None # requests
  54. self.play_session = None
  55. self.s = None
  56. def login(self,user="",password=""):
  57. self.options_read()
  58. if not user: user=self.options["user"]
  59. if not password: password = self.options["password"]
  60. self.s = requests.Session()
  61. ### Dabu sesijas ID ===
  62. headers = headers2dict("""
  63. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
  64. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  65. Accept-Language: en-US,en;q=0.5
  66. Accept-Encoding: gzip, deflate, br
  67. Referer: https://viaplay.lv/
  68. Cookie: ott_cookies_confirmed=1;
  69. DNT: 1
  70. Connection: keep-alive
  71. Upgrade-Insecure-Requests: 1
  72. """)
  73. r = requests.get(self.url,headers=headers)
  74. if not "PLAY_SESSION" in r.cookies:
  75. return False
  76. self.play_session = r.cookies["PLAY_SESSION"]
  77. self.csrfToken = re.search("csrfToken=(.+)",self.play_session).group(1)
  78. ### Ielogojamies ###
  79. headers = headers2dict("""
  80. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
  81. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  82. Accept-Language: en-US,en;q=0.5
  83. Accept-Encoding: gzip, deflate, br
  84. Referer: https://viaplay.lv/
  85. Cookie: ott_cookies_confirmed=1; PLAY_SESSION=e618c42b377a65021298ff63309d5a907988ed1b-PSESSIONID=b010ea1b-fc5e-4a18-aa15-ebbe8b57b3f0&csrfToken=b4eb35263d9be16ef9f7b2f5d10a8ee99dfe75a8-1478051634814-63682b20f1e7e5579de6d056
  86. DNT: 1
  87. Connection: keep-alive
  88. Upgrade-Insecure-Requests: 1
  89. Content-Type: application/x-www-form-urlencoded
  90. """)
  91. url = "https://viaplay.lv/tdi/login/nav/form?csrfToken=%s"%self.csrfToken
  92. # https://viaplay.lv/tdi/login/nav/form?_infuse=1&_ts=1490554674901&csrfToken=
  93. params = "nav_redirectUri=https%3A%2F%2Fviaplay.lv%2F&nav_email={}&nav_password={}".format(urllib.quote(user),urllib.quote(password))
  94. # nav_redirectUri=https%3A%2F%2Fviaplay.lv%2F&nav_email=ivars777%40gmail.com&nav_password=kaskade7&nav_remember=true
  95. headers["Cookie"] = "ott_cookies_confirmed=1; PLAY_SESSION=%s;"%self.play_session
  96. if self.device:
  97. headers["Cookie"] += "ott_dids=%s"%self.device
  98. #cookie = dict(PLAY_SESSION=self.play_session,_hjIncludedInSample=1, mobileAppPromo="shown")
  99. r = requests.post(url,params,headers=headers,allow_redirects=False)
  100. if not "Set-Cookie" in r.headers:
  101. self.play_session = None
  102. return False
  103. if not "ott_web_sac" in r.cookies:
  104. self.play_session = None
  105. return False
  106. self.ott = r.cookies["ott_web_sac"]
  107. ### Dabu iekārtas ID ###
  108. if not self.device:
  109. headers = headers2dict("""
  110. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
  111. Accept: application/xml, text/xml, */*; q=0.01
  112. Accept-Language: en-US,en;q=0.5
  113. Accept-Encoding: gzip, deflate, br
  114. Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  115. X-Requested-With: XMLHttpRequest
  116. Referer: https://viaplay.lv/movies/me-and-earl-and-the-dying-girl
  117. DNT: 1
  118. Connection: keep-alive """)
  119. url = "https://viaplay.lv/tdi/account/device/create?_infuse=1&csrfToken=%s"%self.csrfToken
  120. params = "successRedirectUri=https%3A%2F%2Fviaplay.lv%2Fmovies%2F&slotId=&title=Enigma2"
  121. headers["Cookie"] = "PLAY_SESSION=%s; ott_cookies_confirmed=1; ott_web_sac=%s;"%(self.play_session,self.ott)
  122. #cookie = dict(PLAY_SESSION=self.play_session,_hjIncludedInSample=1, mobileAppPromo="shown")
  123. r = requests.post(url,params,headers=headers,allow_redirects=False)
  124. if not ("Set-Cookie" in r.headers and "ott_dids" in r.headers["Set-Cookie"]):
  125. self.play_session = None
  126. return False
  127. self.device = r.cookies["ott_dids"]
  128. self.options["device"] = self.device
  129. self.options_write(self.options)
  130. return True
  131. def logout(self):
  132. return True
  133. def is_logedin(self):
  134. if self.play_session:
  135. return True
  136. else:
  137. return False
  138. def get_video_info(self,vid):
  139. import demjson
  140. ### Dabu strimus ###
  141. headers = headers2dict("""
  142. Host: viaplay.lv
  143. 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
  144. Accept: application/xml, text/xml, */*; q=0.01
  145. Accept-Language: en-US,en;q=0.5
  146. Accept-Encoding: gzip, deflate, br
  147. X-Requested-With: XMLHttpRequest
  148. DNT: 1
  149. Connection: keep-alive
  150. Referer: https://viaplay.lv/
  151. """)
  152. url = "https://viaplay.lv/prehravac/init?_infuse=1&productId=%s"%vid #t110623
  153. headers["Cookie"] = "ott_cookies_confirmed=1; ott_dids=%s; PLAY_SESSION=%s"%(self.device,self.play_session)
  154. r = requests.get(url,headers=headers,allow_redirects=False)
  155. statuss = re.search("<status>(.+?)</status>", r.content).group(1)
  156. if statuss.lower() <> "ok":
  157. raise Exception(statuss)
  158. #print r.content
  159. m = re.search(r"<!\[CDATA\[\s+var TDIPlayerOptions = (.+?);[\n\t\s]+\]\]>\s+</script>", r.content, re.DOTALL)
  160. if not m:
  161. raise "Can not find stream info"
  162. txt = m.group(1)
  163. txt = re.sub("// .+$", "", txt, flags=re.MULTILINE)
  164. #print txt
  165. #for m in re.finditer("// .+$", txt, re.MULTILINE):
  166. # txt = txt[:m.start()] + txt[m.end():]
  167. #print txt
  168. js = demjson.decode(txt)
  169. return js
  170. #return txt
  171. def get_content(self, data):
  172. print "[%s] get_content:"%self.name, data
  173. source,data,path,plist,clist,params,qs = self.parse_data(data)
  174. content=[]
  175. content.append(("..return", "back","","Return back"))
  176. if clist=="home":
  177. content.extend([
  178. ("Search", "viaplay::search-results-all?query={0}",self.img,"Meklēt"),
  179. ("Filmas", "viaplay::movies",self.img,"Filmas"),
  180. ("Seriāli", "viaplay::series",self.img,"Seriāli"),
  181. ("Bērniem", "viaplay::kids",self.img,"Bērniem"),
  182. ("Dokumentalās filmas", "viaplay::documentary",self.img,"Dokumentalās filmas"),
  183. ("Sports", "viaplay::live",self.img,"Sports"),
  184. ])
  185. return content
  186. ### Meklēt ###
  187. elif clist=="search-results-all":
  188. url = "https://viaplay.lv/"+data
  189. r = self._http_request(url)
  190. result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<h3 class="is-size-h6">([^<]+)</h3>.*?<p>([^<]+).+?</p>.+?<p class="promo-notice">([^<]+)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
  191. for item in result:
  192. vid = item[0]
  193. data2 = item[1].replace("https://viaplay.lv/","")
  194. img = item[2]
  195. ep = item[3]
  196. title= item[4]
  197. seas = item[5].replace("\n","").replace("\t","")
  198. desc = item[6]
  199. desc2 = item[7]
  200. if ep==title:
  201. title = "%s (%s)"%(title,seas)
  202. else:
  203. title = "%s - %s%s"%(title,seas,ep)
  204. desc = "%s\n%s\n%s"%(title,desc2,desc)
  205. content.append((title,self.name+"::"+data2,img,desc))
  206. return content
  207. ### Sadalas ##
  208. elif data in ["movies","series","kids","documentary"]:
  209. r = self._http_request(self.url+data)
  210. # https://viaplay.lv/tdi/movies/next?sections[]=MOVIES&genres[]=a3591&sort[]=latest&offset=0
  211. # https://viaplay.lv/tdi/series/next?sections[]=SERIES&sort[]=latest&offset=0
  212. # https://viaplay.lv/tdi/kids/next?sections[]=KIDS&cat[]=SERIES&cat[]=MOVIE&sort[]=latest&offset=18
  213. # https://viaplay.lv/kids?sections[]=KIDS&cat[]=SERIES&sort[]=latest
  214. sections = {"movies":"MOVIES","series":"SERIES","kids":"KIDS","documentary":"DOCUMENTS"}
  215. nosaukums = {"movies":"Flmas","series":"Seriāli","kids":"Bērnu","documentary":"Dokumentalās"}
  216. #availability = {"new":"jaunākās","last":"pēdējā iespēja"}
  217. sort = OrderedDict([("latest","jaunākais"),("title","pēc nosaukuma"),("popular","pēc popularitātes"),("year","pēc gada")])
  218. for s in sort:
  219. if data in ("movies","series"):
  220. title = "%s - %s"%(nosaukums[data],sort[s])
  221. data2 = "%s/next?sections[]=%s&sort[]=%s"%(data,sections[data],s)
  222. content.append((title,self.name+"::"+data2,self.img,title))
  223. else:
  224. title = "%s filmas - %s"%(nosaukums[data],sort[s])
  225. data2 = "%s/next?sections[]=%s&cat[]=MOVIE&sort[]=%s"%(data,sections[data],s)
  226. content.append((title,self.name+"::"+data2,self.img,title))
  227. title = "%s seriāli - %s"%(nosaukums[data],sort[s])
  228. data2 = "%s/next?sections[]=%s&cat[]=SERIES&sort[]=%s"%(data,sections[data],s)
  229. content.append((title,self.name+"::"+data2,self.img,title))
  230. # Pievienojam žanru sarakstu
  231. result = re.findall(r'name="genres\[\]" value="([^"]+)">.+?class="">([^<]+)</label>', r, re.DOTALL)
  232. for item in result:
  233. s = "latest"
  234. genre = item[1].replace("&amp;","&")
  235. title = "%s: %s"%(nosaukums[data],genre)
  236. data2 = "%s/next?sections[]=%s&genres[]=%s&sort[]=%s"%(data,sections[data],item[0],s)
  237. content.append((title,self.name+"::"+data2,self.img,title))
  238. return content
  239. ### Filmu/seriālu/sēriju saraksts ###
  240. elif clist in ("movies","series","kids","documentary") and plist[1] == "next":
  241. url = "https://viaplay.lv/tdi/"+data
  242. r = self._http_request(url)
  243. if clist == "series" and "season" in qs:
  244. result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<h3 class="is-size-h6">([^<]+)</h3>.*?<p>([^<]+).+?</p>.+?<p class="promo-notice">([^<]+)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
  245. for item in result:
  246. vid = item[0]
  247. data2 = item[1].replace("https://viaplay.lv/","")
  248. img = item[2]
  249. ep = item[3]
  250. title= item[4]
  251. seas = item[5]
  252. desc = item[6]
  253. desc2 = item[7]
  254. title = "%s - %s%s"%(title,seas,ep)
  255. desc = "%s\n%s\n%s"%(title,desc2,desc)
  256. content.append((title,self.name+"::"+data2,img,desc))
  257. else: # filmas
  258. result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<p>([^<]+)</p>.+?<p class="promo-notice">([^<]+).+?<p class="is-strong detail">(.+?)</p>.+?<p class="info">([^<]+)</p>', r, re.DOTALL)
  259. for item in result:
  260. vid = item[0]
  261. data2 = item[1].replace("https://viaplay.lv/","")
  262. img = item[2]
  263. title = item[3]
  264. year = item[4]
  265. year = year.replace("\n","").replace("\t","")
  266. title = title +"(%s)"%year
  267. desc= item[5]
  268. genre = re.findall(">([^<]+)<", item[6], re.DOTALL)
  269. genre = ("".join(genre)).replace("&amp;","&")
  270. desc2 = item[7]
  271. desc = "%s\n%s\n%s"%(genre,desc2,desc)
  272. content.append((title,self.name+"::"+data2, img,desc))
  273. m = re.search(r"data\('href', 'https://viaplay\.lv/tdi/([^']+)'\)", r, re.DOTALL)
  274. if m:
  275. data2 = m.group(1)
  276. content.append(("Next page",self.name+"::"+data2,img,"Next page"))
  277. return content
  278. ### Seriāls ###
  279. elif clist == "series" and len(plist)==2:
  280. url = "https://viaplay.lv/"+data
  281. r = self._http_request(url)
  282. result = re.findall(r'<li>.*?<a class="tdi" href="https://viaplay\.lv/([^"]+)" data-related-ancestor="\.js-tdi-items-filter-and-items">([^<]+)</a>.*?</li>', r, re.DOTALL)
  283. for item in result:
  284. title = item[1]
  285. data2 = item[0]
  286. data2 = data2.replace("series/","series/next/")
  287. data2 = data2+"&sort[]=ord"
  288. #series/littlest-pet-shop?season=t6821
  289. #series/next/peppa-pig?season=t8430
  290. # &sort[]=ord
  291. if "availability=" in data2: continue
  292. content.append((title,self.name+"::"+data2,self.img,title)) #TODO bilde
  293. return content
  294. def is_video(self,data):
  295. source,data,path,plist,clist,params,qs = self.parse_data(data)
  296. if clist in ("movies","documentary","kids") and len(plist)>1 and plist[1]<>"next":
  297. return True
  298. elif clist == "series" and len(plist)>1 and plist[1] == "episode":
  299. return True
  300. else:
  301. return False
  302. def get_streams(self, data):
  303. print "[viaplay] get_streams:", data
  304. if not self.is_video(data):
  305. return []
  306. source,data,path,plist,clist,params,qs = self.parse_data(data)
  307. if not self.is_logedin():
  308. self.login()
  309. if not self.is_logedin():
  310. raise Exception("Could not login to viaplay.lv, check username/password in options")
  311. streams = []
  312. url = "https://viaplay.lv/"+data
  313. r = self._http_request(url)
  314. if clist in ("series","livestream"): # TODO nerāda overtime u.c.
  315. m = re.search(r'<h1 class="is-bottom-sticked is-size-h2">(.+?)</h1>.*?<h2 class="is-size-h4">.*?<p class="is-size-h6 is-strong is-bottom-sticked">(.+?)<div class="toggler-content">\s+<p>(.+?)</p>', r, re.DOTALL)
  316. if not m:
  317. raise Exception("Problem getting video information")
  318. title = m.group(1).replace("\n"," ").replace("\t","").strip()
  319. title = re.sub("<[^>]+>","",title).strip()
  320. desc2 = m.group(2).replace("\n"," ").replace("\t","").strip()
  321. desc2 = re.sub("<[^>]+>","",desc2).strip()
  322. desc = m.group(3)
  323. desc = "%s\n%s"%(desc2,desc)
  324. vid = re.search('data-productid="(\w+)"',r).group(1)
  325. else:
  326. m = re.search(r'<h1 class="is-strong is-bottom-sticked is-size-h2" jnp-id="(\w+)">([^<]+)</h1>.*?<h2 class="is-strong is-size-h4">([^<]+)</h2>.*?<p class="is-size-h6 is-strong is-bottom-sticked">(.+?)<div class="toggler-content">\s+<p>(.+?)</p>', r, re.DOTALL)
  327. if not m:
  328. raise Exception("Problem getting video information")
  329. title = m.group(2).strip()
  330. title2 = m.group(3).strip()
  331. title = "%s | %s"%(title,title2)
  332. desc = m.group(5).strip()
  333. desc2 = m.group(4).strip()
  334. desc2 = re.sub("<[^>]+>","",desc2)
  335. desc2 = desc2.replace("\n"," ").replace("\t","")
  336. desc = "%s\n%s"%(desc2,desc)
  337. vid = m.group(1)
  338. js = self.get_video_info(vid)
  339. #for m in re.finditer(r"lang: '(?P<lang>\w+)',\s+src: '(?P<url>[^']+)',\s+type: '(?P<mime>[^']+)',\s+drm: \[(?P<drm>.+?)\]\s*\}", r, re.DOTALL):
  340. if not js:
  341. return []
  342. tracks = js["tracks"]
  343. #if not tracks["HLS"]:
  344. # raise Exception("Encrypted DASH playing not yet implemented")
  345. captions = []
  346. llist = ["fr","en","ru","lv"]
  347. for st in js["plugins"]["settings"]["subtitles"]:
  348. sub = {}
  349. sub["url"] = st["src"]
  350. sub["lang"] = st["srclang"]
  351. sub["name"] = st["label"]
  352. sub["type"] = "vtt"
  353. sub["order"] = llist.index(sub["lang"])*10 if sub["lang"] in llist else 0
  354. captions.append(sub)
  355. captions = sorted(captions,key=lambda item: item["order"],reverse=True)
  356. for s in tracks["HLS"] if tracks["HLS"] else tracks["DASH"] :
  357. stype = "DASH" if "dash" in s["type"] else "HLS"
  358. if "drm" in s: ###
  359. # TODO, encrypted stream
  360. raise Exception("Can not play DRM protected stream!\nOnly local and Russian content available without DRM")
  361. continue
  362. url = s["src"]
  363. #urlp = util.streamproxy_encode(s["src"])
  364. stream = util.item()
  365. stream["url"]=url
  366. stream["resolver"] = "viaplay"
  367. stream["lang"]=s["lang"]
  368. stream["quality"]="variant"
  369. stream["bitrate"]= "1000000"
  370. stream["name"]= title
  371. stream["desc"]=desc
  372. stream["type"]=stype
  373. stream["subs"] = captions
  374. print url
  375. if stype=="DASH": streams.append(stream)
  376. if stype == "HLS": # izvelkam individuālos strimus
  377. r = requests.get(url)
  378. result = re.findall("#EXT-X-STREAM-INF:BANDWIDTH=(\d+),RESOLUTION=(\d+x\d+)\n(\w+.m3u8)", r.content)
  379. if not result:
  380. continue
  381. for s2 in result:
  382. ### TODO vajag lietot cookie ar tokenu no playlista requesta
  383. if "set-cookie" in r.headers:
  384. headers = {"Cookie":r.headers["set-cookie"]}
  385. else:
  386. headers={}
  387. #url2 = re.sub(r"(http.*://.+/)\w+.m3u8", r"\1"+s2[2], url)
  388. url2 = "/".join(url.split("/")[:-1])+"/"+s2[2]
  389. #r2 = requests.get(url2,headers=headers)
  390. #if "set-cookie" in r2.headers:
  391. #headers = {"Cookie":r2.headers["set-cookie"]}
  392. #else:
  393. #headers={}
  394. #url2p=util.streamproxy_encode(url2,headers)
  395. stream = util.item()
  396. stream["url"]=url2
  397. stream["lang"]=s["lang"]
  398. stream["quality"]="%s"%(s2[1])
  399. stream["name"]= title
  400. stream["desc"]=desc
  401. stream["bitrate"]=s2[0]
  402. stream["type"]="DASH" if "dash" in s["type"] else "HLS"
  403. streams.append(stream)
  404. ### TODO - sakārtot sarakstu, lai pirmais ir labakais video
  405. qlist = ["","512","640","758","1024","variant"]
  406. llist = ["lt","et","fr","en","ru","lv"]
  407. for s in streams:
  408. lv = llist.index(s["lang"])*10000000 if s["lang"] in llist else 0
  409. #qv=qlist.index(s["quality"]) if s["quality"] in qlist else 0
  410. qv = int(s["bitrate"]) if s["bitrate"] else 0
  411. s["order"] = lv+qv
  412. #print s["lang"],s["quality"],s["bitrate"],s["order"]
  413. streams = sorted(streams,key=lambda item: item["order"],reverse=True)
  414. return streams
  415. def call(self, data,params = None, headers=None):
  416. if not headers: headers = self.headers
  417. #if not lang: lang = self.country
  418. url = "https://viaplay.lv/tdi/" + data
  419. content = self._http_request(url, params, headers)
  420. return content
  421. if __name__ == "__main__":
  422. if len(sys.argv)>1:
  423. data= sys.argv[1]
  424. else:
  425. data = "kids/child-and-karlson"
  426. c = Source()
  427. print "login: %s"%c.login()
  428. if "/" in data:
  429. streams = c.get_streams(data)
  430. util.play_video(streams)
  431. else:
  432. vinfo = c.get_video_info(data)
  433. if "HLS" in vinfo["tracks"] and vinfo["tracks"]["HLS"]:
  434. url = vinfo["tracks"]["HLS"][0]["src"]
  435. urlp = util.streamproxy_encode(url)
  436. util.player(urlp)
  437. else:
  438. print "No HLS stream"
  439. sys.exit()
  440. r = requests.get("https://viaplay.lv/movies?sections[]=MOVIES")
  441. result = re.findall(r'<div id="product-(\w+)".+?<a href="([^"]+)">.+?<img data-srcset="([^ ]+).+?alt="([^"]+)">.+?<p class="promo-notice">([^<]+)<', r.content, re.DOTALL)
  442. for item in result:
  443. vid = item[0]
  444. url = item[1]
  445. img = item[2]
  446. title = item[3]
  447. desc= item[4]
  448. print "\n%s (%s):"%(title,vid)
  449. vinfo = c.get_video_info(vid)
  450. if "HLS" in vinfo["tracks"]:
  451. for s in vinfo["tracks"]["HLS"]:
  452. print "HLS %s: \n%s"%(s["lang"],s["src"])
  453. if "DASH" in vinfo["tracks"]:
  454. for s in vinfo["tracks"]["DASH"]:
  455. print "DASH %s: \n%s"%(s["lang"],s["src"])
  456. #except Exception,ex:
  457. #print ex.message
  458. #content = c.get_content(data)
  459. #for item in content:
  460. # print item
  461. pass