|
@@ -0,0 +1,236 @@
|
|
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
|
+
|
|
23
|
+try:
|
|
24
|
+ from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
|
25
|
+ requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
|
26
|
+except:
|
|
27
|
+ pass
|
|
28
|
+#import resolver
|
|
29
|
+try:
|
|
30
|
+ import util
|
|
31
|
+except:
|
|
32
|
+ sys.path.insert(0,'..')
|
|
33
|
+ import util
|
|
34
|
+
|
|
35
|
+headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
|
|
36
|
+
|
|
37
|
+class Source(SourceBase):
|
|
38
|
+
|
|
39
|
+ def __init__(self, country="",cfg_path=None):
|
|
40
|
+ self.hidden = True # nerāda menu nestrādājošos avotus
|
|
41
|
+ self.name = "filmas"
|
|
42
|
+ self.title = "Filmas.lv"
|
|
43
|
+ self.img = "filmas.png"
|
|
44
|
+ self.desc = "Filmas.lv - Latvijas filmas"
|
|
45
|
+ self.headers = headers2dict("""
|
|
46
|
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
|
|
47
|
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
|
48
|
+Accept-Language: en-US,en;q=0.5
|
|
49
|
+Accept-Encoding: gzip, deflate, br
|
|
50
|
+""")
|
|
51
|
+ self.headers2 = headers2dict("""
|
|
52
|
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
|
|
53
|
+X-Requested-With: XMLHttpRequest
|
|
54
|
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
|
55
|
+""")
|
|
56
|
+ self.url = "https://www.filmas.lv/"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+ ######### Entry point ########
|
|
60
|
+ def get_content(self, data):
|
|
61
|
+ print "[filmas] get_content:", data
|
|
62
|
+ source, data, path, plist, clist, params, qs = self.parse_data(data)
|
|
63
|
+ content = []
|
|
64
|
+ content.append(("..return", "back","","Return back"))
|
|
65
|
+
|
|
66
|
+ if clist=="home":
|
|
67
|
+ content.extend([
|
|
68
|
+ ("Meklēt", "filmas::filmu-katalogs/?mn={0}&tab=movies&sub_tab=movies-search","","Meklēt"),
|
|
69
|
+ ("Visas", "filmas::filmu-katalogs/?tab=movies&sub_tab=movies-view-2","","Visur skatam visas filmas"),
|
|
70
|
+ ("Spēlfilmas", "filmas::filmu-katalogs/?tab=movies&sub_tab=movies-view-2&mp20=112","","Visur skatamās spēlfilmas"),
|
|
71
|
+ ("Animācijas filmas", "filmas::filmu-katalogs/?tab=movies&sub_tab=movies-view-2&mp20=113","","Visur skatamās animācijas filmas"),
|
|
72
|
+ ("Dokumentalās filmas", "filmas::filmu-katalogs/?tab=movies&sub_tab=movies-view-2&mp20=111","","Visur skatamās dokumentalās filmas"),
|
|
73
|
+ ("Kinohronikas", "filmas::filmu-katalogs/?tab=movies&sub_tab=movies-view-2&mp20=150","","Visur skatamās kinohronikas") ,
|
|
74
|
+ ])
|
|
75
|
+ return content
|
|
76
|
+
|
|
77
|
+ elif clist=="filmu-katalogs":
|
|
78
|
+ r=self.call(data)
|
|
79
|
+ result = re.findall(r'<a href="/(movie/\d+)">.+?<img src="/([^"]+)">.+?Pieejama.+?<div class="katalogs-filma-teksts">\s*(.+?)\s*<span style="font-weight:normal; ">\((\d+)\)</span>', r, re.DOTALL)
|
|
80
|
+ for item in result:
|
|
81
|
+ title = item[2]+'(%s)'%item[3]
|
|
82
|
+ data2 = item[0]
|
|
83
|
+ img = self.url + item[1].replace("thumbs_m/","")
|
|
84
|
+ desc = title
|
|
85
|
+ content.append((title,self.name+"::"+data2,img,desc))
|
|
86
|
+ m = re.search(r"<a class='pagenum' href='(\?tab=movies&sub_tab=movies-view-2[^']+)'>></a>", r, re.DOTALL)
|
|
87
|
+ if m:
|
|
88
|
+ data2 = "filmu-katalogs/"+m.group(1)
|
|
89
|
+ content.append(("Next page",self.name+"::"+data2, "","Next page"))
|
|
90
|
+ return content
|
|
91
|
+
|
|
92
|
+ ### kaut kas neparedzets ###
|
|
93
|
+ else:
|
|
94
|
+ return content
|
|
95
|
+
|
|
96
|
+ def is_video(self,data):
|
|
97
|
+ source,data,path,plist,clist,params,qs = self.parse_data(data)
|
|
98
|
+ if clist=="movie":
|
|
99
|
+ return True
|
|
100
|
+ else:
|
|
101
|
+ return False
|
|
102
|
+
|
|
103
|
+ def call(self, data,params=None,headers=None,lang=""):
|
|
104
|
+ if not headers: headers = self.headers
|
|
105
|
+ url = self.url+data
|
|
106
|
+ result = self._http_request(url,params,headers=headers)
|
|
107
|
+ return result
|
|
108
|
+
|
|
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
|
+
|
|
120
|
+ ### Main playlist ###
|
|
121
|
+ hid = re.search('src: "/lmdb/hls/playlist/(\w+).m3u8"', r.content).group(1)
|
|
122
|
+ url = "https://www.filmas.lv/lmdb/hls/playlist/%s.m3u8"%hid
|
|
123
|
+ headers = headers2dict("""
|
|
124
|
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
|
|
125
|
+Accept: */*
|
|
126
|
+Accept-Language: en-US,en;q=0.5
|
|
127
|
+Accept-Encoding: gzip, deflate, br
|
|
128
|
+Referer: https://www.filmas.lv/movie/%s/
|
|
129
|
+ """%mid)
|
|
130
|
+ r = requests.get(url, headers=headers, verify=False, cookies={"phpsessid":phpsessid} )
|
|
131
|
+ filmassession = r.cookies["filmassession"]
|
|
132
|
+ result = re.findall(r'#EXT-X-STREAM-INF:PROGRAM-ID=(\d+),BANDWIDTH=(\d+),RESOLUTION=(.+?),CODECS="(.+?)"\n(.+?)$', r.content, re.IGNORECASE | re.MULTILINE)
|
|
133
|
+ title = url.split("/")[-1].split(".")[0]
|
|
134
|
+
|
|
135
|
+ ### Initial key requests
|
|
136
|
+ url = "https://www.filmas.lv/lmdb/hls/key/request/%s?%s"%(mid,int(time.time()))
|
|
137
|
+ r=requests.get(url,headers=headers,cookies = {"filmassession":filmassession}, verify=False )
|
|
138
|
+ filmassession = r.cookies["filmassession"]
|
|
139
|
+
|
|
140
|
+ ### Metada ###
|
|
141
|
+ url = "https://www.filmas.lv/charts/api/api/?method=search_movie&query=%s"%mid
|
|
142
|
+ r = requests.get(url, headers=headers, verify=False)
|
|
143
|
+ if not "error" in r.content:
|
|
144
|
+ title = r.json()["nodes"][0]["name"]
|
|
145
|
+ img = self.url+r.json()["nodes"][0]["image"]
|
|
146
|
+ desc = r.json()["nodes"][0]["plot"]
|
|
147
|
+ else:
|
|
148
|
+ img = desc = ""
|
|
149
|
+
|
|
150
|
+ for h in result:
|
|
151
|
+ url = h[4]
|
|
152
|
+
|
|
153
|
+ ### Key request ###
|
|
154
|
+ headers["Origin"] = "https://www.filmas.lv"
|
|
155
|
+ r=requests.get(url,headers=headers, verify=False)
|
|
156
|
+ url_key = re.search('#EXT-X-KEY:METHOD=AES-128,URI="(.+?)"', r.content, re.IGNORECASE | re.MULTILINE).group(1)
|
|
157
|
+ r=requests.get(url_key,headers=headers, cookies={"filmassession":filmassession,"PHPSESSID":phpsessid}, verify=False)
|
|
158
|
+ key = r.content if not "error" in r.content else ""
|
|
159
|
+
|
|
160
|
+ stream = util.item()
|
|
161
|
+ stream["name"] = title
|
|
162
|
+ stream["url"] = url
|
|
163
|
+ stream["img"] = img
|
|
164
|
+ stream["desc"] = desc
|
|
165
|
+ stream["headers"] = {"key":binascii.b2a_hex(key)}
|
|
166
|
+ stream["quality"] = h[2]
|
|
167
|
+ stream["order"] = int(h[1])
|
|
168
|
+ stream["resolver"] = "filmas"
|
|
169
|
+ streams.append(stream)
|
|
170
|
+
|
|
171
|
+ return sorted(streams,key=lambda item: item["order"],reverse=True)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+def download_hls(url, title, download_dir="", headers=None, overwrite=True):
|
|
175
|
+ UA = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0"
|
|
176
|
+ if not headers:
|
|
177
|
+ headers = {"User-Agent" : UA}
|
|
178
|
+ key = headers["key"] if "key" in headers else ""
|
|
179
|
+ if not "User-Agent" in headers:
|
|
180
|
+ headers["User-Agent"] = UA
|
|
181
|
+ tsname = os.path.join(download_dir,title+".ts")
|
|
182
|
+ if not os.path.exists(tsname) or overwrite:
|
|
183
|
+ tsfile = open(tsname,"wb")
|
|
184
|
+ print "Downloading ", tsname
|
|
185
|
+ try:
|
|
186
|
+ r=requests.get(url,headers=headers, verify=False)
|
|
187
|
+ except Exception as e:
|
|
188
|
+ print "Got Exception: ", str(e)
|
|
189
|
+ import traceback
|
|
190
|
+ traceback.print_exc()
|
|
191
|
+ sys.exit()
|
|
192
|
+ ts_list = re.findall(r"#EXTINF:([\d\.]+),\n(.+?)$", r.content, re.IGNORECASE | re.MULTILINE)
|
|
193
|
+ for ts in ts_list:
|
|
194
|
+ url2 = ts[1]
|
|
195
|
+ #print "Downloading ", url2
|
|
196
|
+ #fname = os.path.join(download_dir,url2.split("/")[-1])
|
|
197
|
+ r = requests.get(url2, headers=headers, verify=False)
|
|
198
|
+ content = r.content
|
|
199
|
+ if key:
|
|
200
|
+ from Crypto.Cipher import AES
|
|
201
|
+ key2 = binascii.a2b_hex(key)
|
|
202
|
+ iv = content[:16]
|
|
203
|
+ d = AES.new(key2, AES.MODE_CBC, iv)
|
|
204
|
+ content = d.decrypt(content[16:])
|
|
205
|
+ #with open(fname,"wb") as f:
|
|
206
|
+ #f.write(content)
|
|
207
|
+ tsfile.write(content)
|
|
208
|
+ #lfile.write("file '%s'"%fname)
|
|
209
|
+ #lfile.close()
|
|
210
|
+ tsfile.close()
|
|
211
|
+ from subprocess import call
|
|
212
|
+ cmd = [r"ffmpeg.exe","-i", tsname.encode(sys.getfilesystemencoding()), "-c","copy", os.path.join(download_dir,title+".mp4").encode(sys.getfilesystemencoding())]
|
|
213
|
+ ret = call(cmd)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+if __name__ == "__main__":
|
|
217
|
+ #url = "http://localhost:88/https%3A//as2.filmas.lv/FilmasLV/508D4024A83FDC1AA61D727DE5046D12/index-f3-v1-a1.m3u8?~key=4cb5c12b2aaa3d2cf211583cc9add2dd"
|
|
218
|
+ #download_hls(url, "video", "")
|
|
219
|
+
|
|
220
|
+ c = Source()
|
|
221
|
+ if len(sys.argv)>1:
|
|
222
|
+ data= sys.argv[1]
|
|
223
|
+ else:
|
|
224
|
+ data = "movie/3112/"
|
|
225
|
+ if "movie" in data:
|
|
226
|
+ if data.startswith("http"):
|
|
227
|
+ data = data.replace("https://www.filmas.lv/","")
|
|
228
|
+ streams = c.get_streams(data)
|
|
229
|
+ #for s in streams:
|
|
230
|
+ s = streams[0]
|
|
231
|
+ download_hls(s["url"],"%s %s"%(s["name"],s["quality"]),"",s["headers"])
|
|
232
|
+ else:
|
|
233
|
+ content = c.get_content(data)
|
|
234
|
+ for item in content:
|
|
235
|
+ print item
|
|
236
|
+ pass
|