1+ /*
2+ @header ({
3+ '类型': '影视',
4+ lang: 'ds'
5+ })
6+ */
7+
8+ // 官方推荐安全的参数分割符合: *
9+ var rule = {
10+ title : 'Zero影视' ,
11+ host : 'http://ldys.sq1005.top' ,
12+ url : '/api/v1/app/screen/screenMovie' ,
13+ searchUrl : '/api/v1/app/search/searchMovie#keywords=**;post' ,
14+ searchable : 2 ,
15+ quickSearch : 1 ,
16+ filterable : 1 ,
17+ headers : {
18+ 'HOST' : 'ldys.sq1005.top' ,
19+ 'User-Agent' : 'okhttp/4.12.0' ,
20+ 'client' : 'app' ,
21+ 'deviceType' : 'Android' ,
22+ 'Referer' : ''
23+ } ,
24+ class_parse : async ( ) => {
25+ let { HOST } = this ;
26+ let html = await request ( HOST + '/api/v1/app/screen/screenType' , {
27+ headers : rule . headers ,
28+ method : 'POST'
29+ } ) ;
30+
31+ let content = JSON . parse ( html ) ;
32+ let classes = [ ] ;
33+ let filterObj = { } ;
34+
35+ content . data . forEach ( mainCate => {
36+ classes . push ( {
37+ type_id : mainCate . id ,
38+ type_name : mainCate . name
39+ } ) ;
40+
41+ let filters = [ ] ;
42+ mainCate . children . forEach ( subCate => {
43+ let filterType = '' ;
44+ switch ( subCate . name ) {
45+ case '类型' :
46+ filterType = 'type' ;
47+ break ;
48+ case '地区' :
49+ filterType = 'area' ;
50+ break ;
51+ case '年份' :
52+ filterType = 'year' ;
53+ break ;
54+ }
55+
56+ let filter = {
57+ key : filterType ,
58+ name : subCate . name ,
59+ value : subCate . children . map ( item => ( {
60+ n : item . name ,
61+ v : item . name
62+ } ) ) ,
63+ init : subCate . children [ 0 ] . name
64+ } ;
65+ filters . push ( filter ) ;
66+ } ) ;
67+
68+ // 统一添加排序筛选器
69+ filters . push ( {
70+ key : 'sort' ,
71+ name : '排序' ,
72+ init : 'HOT' ,
73+ value : [ {
74+ n : '最新' ,
75+ v : 'NEWEST'
76+ } ,
77+ {
78+ n : '热门' ,
79+ v : 'HOT'
80+ } ,
81+ {
82+ n : '收藏' ,
83+ v : 'COLLECT'
84+ }
85+ ]
86+ } ) ;
87+
88+ filterObj [ mainCate . id ] = filters ;
89+ } ) ;
90+
91+ log ( 'classes:' , classes )
92+ return {
93+ class : classes ,
94+ filters : filterObj ,
95+ }
96+ } ,
97+
98+ 预处理 : async ( ) => {
99+ let dd = getdid ( ) ;
100+ let token = await gettk ( rule . host , dd ) ;
101+ rule . headers [ 'deviceId' ] = dd ;
102+ rule . headers [ 'token' ] = token ;
103+ log ( "rule.headers>>>>>" , rule . headers ) ;
104+ rule . privateKey = `MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCquQQ5r6+yJI8CDFkXRp8vUsdD45ov8EP12ooLs56ca2DQXaSNGS9910bAPVA9chkp0mKIvKqjAsHz5Tl9EeNPblarGEeJUIxpxZtiSqNTpvtiD/TjhpzuHYic7RAfQ/h7p/ypE8ymU42pYjsB5t26Mv6XgkLV+jzrSf73HlCuS0iMyLmt6zz3Mw9izM13EpB8iFLtfbbYymycKTx4RAmPQLwhNGex/AlUIYxXP4R2yyaa4W6mEtc6aME2QuzJFxPgP3HJ9NBx/LWVn4skxWjZ7zg+VRQRHnjyVaSLu3Z5gN5ITWCyE32qaHJa6WBahZj5jWhRyAG1bQ+xKJa8lBL5AgMBAAECggEAUwv9SjJ0PSwbhNuM2w23kcWquROWhYtTA91zGY4esehqB/IFgb2mpIh8Gje5OKqwIu/8jpd4SiOlRYdUF8sD0DfUYRZGdj2AkFNX6tBz8tVfo6wvbB6naA1lzzBij1L5JO3qsjS3cJFkb+kg2yP66AC2Z+0tpfk8eRhdtshAZwfcd1DEGt1uAvYL1eaUK9HRvpt9lPeGcHERDl2hBd4uyaF0K1O+zF9y59nYbTySWPxRZq3sFEE85xRMlstD7YZi7W2gKvMFRD4/FKmrZ3m7aKJRITtyKOyyPcYmepNv3Qv7kk59Pg38n2WWQ0Ra/bCH3E48YNCnQvZMpitkTfJhoQKBgQDbnROOYTP8OTJ6f/qhoGjxeO3x1VOaOp8l0x7b0SCfoqNGS0Cyiqj72BmJtPMPqSTjn6MmNzqbg1KOdhXyzNozs+i5ccW1M56j96mr5I/Z0FpE3oyIHNfDDBlf9M8YQqEF9oYxniYYft9oapO7cRQkHER6qpvnHTavwlv4m78CXwKBgQDHAjs2YlpKDdI1lcbZJCc7TwtH+Pd2bUki8YXafWNcPhITQHbOZjr310eK1QJC6GJncjkOqbX7yv3ivvTO35FZTQhuA1xEG1P00FG8bE0tHYPIwQHi9y0eA5cieMdo8E6XYria1mw/3fqSQEsfZyJlR32JQIoGAipM8iO1X2nZpwKBgDkMFIhnt5lNQk+P7wsNIDWZtDWdtJnboHuy29E+Abt2A/O+mI/IdRz2hau/1WO8DFkUnszOi+rZshhPlGP90rCbi1igtTrcrdjp/KkqNjPea5R4OwkgdOu1uOG0NheXNzzVTQaWjk7Opjn5dWa7eP/oV+GFb/oZHJuLYVizHGsBAoGADA7rjZEKDYCm4w5PPSr+oY5ZjaPdQrS+gLqHtMRyN82fBMGcMUdqfUfzEstzVqCEDeaS5HuOBlK3bXzKkppjUTjksN3NQmcxgBz7RuJ9DqXCLXDcb2cwuafYCYOt+YLOEEgwDVm+t2P44dG5e46hO+fICH/7nP+WlpD5buz4GfMCgYB57r3g/6hi9WUDnfc7ZAzWMqR0EhJVYKYy+KFEtdIPzhkkIHq5RASe88E9kzoGoZFdb3tIjvGZWcHerirrqWkMsuQtP/Qi0zjieid5tAPj+r4kbiCVTw0E0jnmPBzGInQi7lpeTTKnG1fbyS5lBS+WmHfIuzpECgCkxhaT+LJJkg==` ;
105+ rule . publicKey = `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoYt0BP77U+DM08BiI/QbSRIfxijXo85BTPqIM1Ow8BNwhLETzRIZ+dEwdWDbydG/PspgBAfRpGaYVdJYtvaC2JnoO8+Ik6qMWojfEJxSFLa0Pb0A892tun4gsxoEMjcreZ+YGyaBxAfqX0BSMfdrOgIYaZQjYrw9TRLlUT31QoQIDAQAB` ;
106+ rule . options = {
107+ block : true ,
108+ long : 2 ,
109+ type : 1
110+ } ;
111+ } ,
112+
113+ 一级 : $js . toString ( async ( ) => {
114+ let params = {
115+ condition : {
116+ sreecnTypeEnum : 'NEWEST' ,
117+ typeId : MY_CATE
118+ } ,
119+ pageNum : MY_PAGE ,
120+ pageSize : 40
121+ } ;
122+ let data = JSON . parse ( await request ( HOST + '/api/v1/app/screen/screenMovie' , {
123+ headers : rule . headers ,
124+ body : params ,
125+ method : 'POST'
126+ } ) ) . data ;
127+
128+ let d = data . records . map ( item => ( {
129+ title : item . name ,
130+ desc : item . totalEpisode ,
131+ pic_url : item . cover ,
132+ url : HOST + '/api/v1/app/play/movieDesc' + '*' + item . id + '*' + item . typeId
133+ } ) ) ;
134+ return setResult ( d ) ;
135+ } ) ,
136+
137+ 二级 : $js . toString ( async ( ) => {
138+ console . log ( "input>>>>>" + input ) ;
139+ console . log ( "MY_URL>>>>>" + MY_URL ) ;
140+ let [ url , id , typeId ] = MY_URL . split ( '*' ) ;
141+ console . log ( "id>>>>>" + id ) ;
142+ console . log ( "typeId>>>>>" + typeId ) ;
143+
144+ // 获取详情信息
145+ let detailParams = {
146+ "id" : parseInt ( id ) ,
147+ "typeId" : typeId
148+ } ;
149+
150+ let detailRes = await request ( HOST + '/api/v1/app/play/movieDesc' , {
151+ headers : rule . headers ,
152+ body : detailParams ,
153+ method : "POST"
154+ } ) ;
155+ let detail = JSON . parse ( detailRes ) . data ;
156+ log ( "movieDesc:" + JSON . stringify ( detail ) ) ;
157+
158+ // 获取播放列表
159+ let playParams = {
160+ "key" : RSA . encode ( JSON . stringify ( {
161+ "id" : parseInt ( id ) ,
162+ "source" : 0 ,
163+ "typeId" : typeId
164+ } ) , rule . publicKey , rule . options )
165+ } ;
166+
167+ let playDataRes = await request ( HOST + '/api/v1/app/play/movieDetails' , {
168+ headers : rule . headers ,
169+ body : playParams ,
170+ method : "POST"
171+ } ) ;
172+
173+ let playData = JSON . parse ( playDataRes ) . data ;
174+
175+ let decryptedData = JSON . parse ( await RSA . decode ( playData , rule . privateKey , rule . options ) ) ;
176+ log ( "movieDetails:" , decryptedData ) ;
177+
178+ // 处理播放列表
179+ let playMap = { } ;
180+ for ( const player of decryptedData . moviePlayerList ) {
181+ let episodeParams = {
182+ "key" : RSA . encode ( JSON . stringify ( {
183+ "id" : parseInt ( id ) ,
184+ "source" : 0 ,
185+ "typeId" : typeId ,
186+ "playerId" : player . id
187+ } ) , rule . publicKey , rule . options )
188+ } ;
189+
190+ let episodeRes = await request ( HOST + '/api/v1/app/play/movieDetails' , {
191+ headers : rule . headers ,
192+ body : episodeParams ,
193+ method : "POST"
194+ } ) ;
195+
196+ let episodeData = JSON . parse ( episodeRes ) . data ;
197+
198+ let decryptedEpisode = JSON . parse ( RSA . decode ( episodeData , rule . privateKey , rule . options ) ) ;
199+ log ( 'decryptedEpisode:' , decryptedEpisode )
200+ playMap [ player . id ] = decryptedEpisode . episodeList . map ( ep => {
201+ let param = {
202+ id,
203+ typeId,
204+ playerId : player . id ,
205+ episodeId : ep . id
206+ } ;
207+ return ep . episode + '$' + btoa ( unescape ( encodeURIComponent ( JSON . stringify ( param ) ) ) ) ;
208+ } ) . join ( '#' ) ;
209+ }
210+
211+ VOD = {
212+ vod_name : detail . name ,
213+ vod_pic : detail . cover ,
214+ vod_year : detail . year ,
215+ vod_area : detail . area ,
216+ vod_remarks : detail . totalEpisode ,
217+ vod_actor : detail . star ,
218+ vod_content : detail . introduce ,
219+ vod_play_from : decryptedData . moviePlayerList . map ( p => p . moviePlayerName ) . join ( '$$$' ) ,
220+ vod_play_url : Object . values ( playMap ) . join ( '$$$' )
221+ } ;
222+ return VOD
223+ } ) ,
224+
225+ 搜索 : $js . toString ( async ( ) => {
226+ let params = {
227+ condition : {
228+ value : KEY
229+ } ,
230+ pageNum : MY_PAGE ,
231+ pageSize : 40
232+ } ;
233+ let data = JSON . parse ( await request ( HOST + '/api/v1/app/search/searchMovie' , {
234+ headers : rule . headers ,
235+ body : params ,
236+ method : 'POST'
237+ } ) ) . data ;
238+ log ( "data>>>>>" + data )
239+ let d = data . records . map ( item => ( {
240+ title : item . name ,
241+ desc : item . totalEpisode ,
242+ pic_url : item . cover ,
243+ url : HOST + '/api/v1/app/play/movieDesc' + '*' + item . id + '*' + item . typeId
244+ } ) ) ;
245+ return setResult ( d ) ;
246+ } ) ,
247+
248+ play_parse : true ,
249+ lazy : $js . toString ( async ( ) => {
250+ let param = JSON . parse ( base64Decode ( input ) ) ;
251+ log ( "param>>>>>" + JSON . stringify ( param ) ) ;
252+ log ( "id>>>>>" + param . id ) ;
253+ let urlParams = {
254+ "key" : RSA . encode ( JSON . stringify ( {
255+ "id" : param . id ,
256+ "source" : 0 ,
257+ "typeId" : param . typeId ,
258+ "playerId" : param . playerId ,
259+ "episodeId" : param . episodeId
260+ } ) , rule . publicKey , rule . options )
261+ } ;
262+
263+ const postData = await request ( `${ HOST } /api/v1/app/play/movieDetails` , {
264+ headers : rule . headers ,
265+ body : urlParams ,
266+ method : 'POST'
267+ } ) ;
268+
269+ const encryptedUrl = JSON . parse ( postData ) . data ;
270+ const playerUrl = JSON . parse ( RSA . decode ( encryptedUrl , rule . privateKey , rule . options ) ) . url ;
271+ log ( "playerUrl>>>>>" + playerUrl ) ;
272+
273+ const getResponse = await request ( HOST + '/api/v1/app/play/analysisMovieUrl?playerUrl=' + encodeURIComponent ( playerUrl ) + '&playerId=' + param . playerId , {
274+ headers : rule . headers
275+ } ) ;
276+ log ( "getResponse>>>>>" , getResponse ) ;
277+
278+ const player = JSON . parse ( getResponse ) . data ;
279+ log ( "player>>>>>" + player ) ;
280+ return {
281+ parse : 0 ,
282+ url : player
283+ } ;
284+ } ) ,
285+ }
286+
287+ async function gettk ( HOST , dd ) {
288+ let res = JSON . parse ( await request ( HOST + '/api/v1/app/user/visitorInfo' , {
289+ headers : {
290+ 'HOST' : 'ldys.sq1005.top' ,
291+ 'User-Agent' : 'okhttp/4.12.0' ,
292+ 'client' : 'app' ,
293+ 'deviceType' : 'Android' ,
294+ 'Referer' : '' ,
295+ 'deviceId' : dd
296+ }
297+ } ) ) ;
298+ return res . data . token ;
299+ }
300+
301+ function getdid ( ) {
302+ let did = getItem ( 'ldid' ) ;
303+ if ( ! did ) {
304+ const hex = '0123456789abcdef' ;
305+ did = Array . from ( {
306+ length : 16
307+ } , ( ) => hex [ Math . floor ( Math . random ( ) * 16 ) ] ) . join ( '' ) ;
308+ setItem ( 'ldid' , did ) ;
309+ }
310+ return did ;
311+ }
0 commit comments