jianpian.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. /*
  2. * @File : jianpian.js
  3. * @Author : jade
  4. * @Date : 2024/1/15 10:32
  5. * @Email : jadehh@1ive.com
  6. * @Software : Samples
  7. * @Desc : 完成荐片所有功能(添加弹幕)
  8. */
  9. import {Spider} from "./spider.js";
  10. import {_, load} from "../lib/cat.js";
  11. import {VodDetail, VodShort} from "../lib/vod.js";
  12. import * as Utils from "../lib/utils.js";
  13. class JianPianSpider extends Spider {
  14. constructor() {
  15. super();
  16. this.siteUrl = "http://api2.rinhome.com"
  17. // this.siteUrl = "https://ownjpykxttjzuhy.jiesiwa.com"
  18. }
  19. getName() {
  20. return "🌼┃荐片┃🌼"
  21. }
  22. getAppName() {
  23. return "荐片"
  24. }
  25. getJSName() {
  26. return "jianpian"
  27. }
  28. getType() {
  29. return 3
  30. }
  31. getHeader() {
  32. return {
  33. "User-Agent": "jianpian-android/360",
  34. "JPAUTH": "y261ow7kF2dtzlxh1GS9EB8nbTxNmaK/QQIAjctlKiEv",
  35. "Referer": "www.jianpianapp.com"
  36. }
  37. }
  38. async spiderInit(inReq=null) {
  39. if (inReq !== null){
  40. this.jsBase = await js2Proxy(inReq,"img",this.getHeader());
  41. }else{
  42. this.jsBase = await js2Proxy(true, this.siteType, this.siteKey, 'img/', this.getHeader());
  43. }
  44. }
  45. async init(cfg) {
  46. await super.init(cfg);
  47. this.danmuStaus = true
  48. await this.spiderInit(null)
  49. }
  50. async parseVodShortListFromJson(data_list) {
  51. let vod_list = [];
  52. for (const data of data_list) {
  53. let vodShort = new VodShort();
  54. vodShort.vod_id = data["id"]
  55. if (data["path"] !== undefined) {
  56. if (!this.catOpenStatus) {
  57. vodShort.vod_pic = data["path"] + "@Referer=www.jianpianapp.com@User-Agent=jianpian-version353@JPAUTH=y261ow7kF2dtzlxh1GS9EB8nbTxNmaK/QQIAjctlKiEv"
  58. } else {
  59. vodShort.vod_pic = this.jsBase + Utils.base64Encode(data["path"])
  60. }
  61. } else {
  62. if (!this.catOpenStatus) {
  63. vodShort.vod_pic = data["thumbnail"] + "@Referer=www.jianpianapp.com@User-Agent=jianpian-version353@JPAUTH=y261ow7kF2dtzlxh1GS9EB8nbTxNmaK/QQIAjctlKiE"
  64. } else {
  65. vodShort.vod_pic = this.jsBase + Utils.base64Encode(data["thumbnail"])
  66. }
  67. }
  68. vodShort.vod_name = data["title"]
  69. if (this.catOpenStatus) {
  70. vodShort.vod_remarks = `评分:${data["score"]}`
  71. } else {
  72. if (data["playlist"] !== undefined) {
  73. vodShort.vod_remarks = `评分:${data["score"]}` + " " + data["playlist"]["title"]
  74. } else {
  75. vodShort.vod_remarks = `评分:${data["score"]}`
  76. }
  77. }
  78. vod_list.push(vodShort)
  79. }
  80. return vod_list
  81. }
  82. objToList(list, key, split_value = "*") {
  83. let value_list = []
  84. for (const dic of list) {
  85. value_list.push(dic[key])
  86. }
  87. return value_list.join(split_value)
  88. }
  89. async parseVodDetailfromJson(obj) {
  90. let vodDetail = new VodDetail();
  91. vodDetail.vod_id = obj["id"]
  92. vodDetail.vod_year = obj["year"]["title"]
  93. vodDetail.vod_pic = this.jsBase + Utils.base64Encode(obj["thumbnail"])
  94. vodDetail.type_name = obj["category"][0]["title"]
  95. vodDetail.vod_name = obj["title"]
  96. vodDetail.vod_content = obj["description"]
  97. vodDetail.vod_area = obj["area"]["title"]
  98. vodDetail.vod_director = this.objToList(obj["directors"], "name")
  99. vodDetail.vod_actor = this.objToList(obj["actors"], "name")
  100. vodDetail.vod_remarks = "评分:" + obj["score"]
  101. let playKeyList = [{"btbo_downlist": "btbo"}, {"xunlei_downlist": "迅雷"}, {"m3u8_downlist": "m3u8"}, {"new_ftp_list": "new_ftp"}, {"new_m3u8_list": "new_m3u8"}]
  102. let playlist = {}
  103. let urlList = []
  104. for (const dic of playKeyList) {
  105. let key = Object.keys(dic)[0]
  106. let value = Object.values(dic)[0]
  107. if (obj[key].length > 0) {
  108. let url_str_list = []
  109. for (const dic of obj[key]) {
  110. url_str_list.push(dic["title"] + "$" + dic["url"])
  111. }
  112. if (urlList.indexOf(url_str_list.join("#")) === -1) {
  113. urlList.push(url_str_list.join("#"))
  114. playlist[value] = url_str_list.join("#")
  115. } else {
  116. await this.jadeLog.warning(`key为:${key},播放链接重复,无需保存`)
  117. }
  118. }
  119. }
  120. vodDetail.vod_play_url = _.values(playlist).join('$$$');
  121. vodDetail.vod_play_from = _.keys(playlist).join('$$$');
  122. return vodDetail
  123. }
  124. async setClasses() {
  125. let type_name_list = ["全部", "电影", "电视剧", "动漫", "综艺"]
  126. let type_id_list = ["0", "1", "2", "3", "4"]
  127. for (let i = 0; i < type_name_list.length; i++) {
  128. let type_name = type_name_list[i]
  129. let type_id = type_id_list[i]
  130. this.classes.push({"type_name": type_name, "type_id": type_id})
  131. }
  132. }
  133. async setFilterObj() {
  134. this.filterObj = {
  135. "0": [{
  136. "key": "area", "name": "地區", "value": [{
  137. "n": "全部", "v": "0"
  138. }, {
  139. "n": "国产", "v": "1"
  140. }, {
  141. "n": "中国香港", "v": "3"
  142. }, {
  143. "n": "中国台湾", "v": "6"
  144. }, {
  145. "n": "美国", "v": "5"
  146. }, {
  147. "n": "韩国", "v": "18"
  148. }, {
  149. "n": "日本", "v": "2"
  150. }]
  151. }, {
  152. "key": "year", "name": "年份", "value": [{
  153. "n": "全部", "v": "0"
  154. }, {
  155. "n": "2024", "v": "119"
  156. }, {
  157. "n": "2023", "v": "153"
  158. }, {
  159. "n": "2022", "v": "101"
  160. }, {
  161. "n": "2021", "v": "118"
  162. }, {
  163. "n": "2020", "v": "16"
  164. }, {
  165. "n": "2019", "v": "7"
  166. }, {
  167. "n": "2018", "v": "2"
  168. }, {
  169. "n": "2017", "v": "3"
  170. }, {
  171. "n": "2016", "v": "22"
  172. }]
  173. }, {
  174. "key": "by", "name": "排序", "value": [{
  175. "n": "热门", "v": "hot"
  176. }, {
  177. "n": "更新", "v": "updata"
  178. }, {
  179. "n": "评分", "v": "rating"
  180. }]
  181. }], "1": [{
  182. "key": "area", "name": "地區", "value": [{
  183. "n": "全部", "v": "0"
  184. }, {
  185. "n": "国产", "v": "1"
  186. }, {
  187. "n": "中国香港", "v": "3"
  188. }, {
  189. "n": "中国台湾", "v": "6"
  190. }, {
  191. "n": "美国", "v": "5"
  192. }, {
  193. "n": "韩国", "v": "18"
  194. }, {
  195. "n": "日本", "v": "2"
  196. }]
  197. }, {
  198. "key": "year", "name": "年份", "value": [{
  199. "n": "全部", "v": "0"
  200. }, {
  201. "n": "2024", "v": "119"
  202. }, {
  203. "n": "2023", "v": "153"
  204. }, {
  205. "n": "2022", "v": "101"
  206. }, {
  207. "n": "2021", "v": "118"
  208. }, {
  209. "n": "2020", "v": "16"
  210. }, {
  211. "n": "2019", "v": "7"
  212. }, {
  213. "n": "2018", "v": "2"
  214. }, {
  215. "n": "2017", "v": "3"
  216. }, {
  217. "n": "2016", "v": "22"
  218. }]
  219. }, {
  220. "key": "by", "name": "排序", "value": [{
  221. "n": "热门", "v": "hot"
  222. }, {
  223. "n": "更新", "v": "updata"
  224. }, {
  225. "n": "评分", "v": "rating"
  226. }]
  227. }], "2": [{
  228. "key": "area", "name": "地區", "value": [{
  229. "n": "全部", "v": "0"
  230. }, {
  231. "n": "国产", "v": "1"
  232. }, {
  233. "n": "中国香港", "v": "3"
  234. }, {
  235. "n": "中国台湾", "v": "6"
  236. }, {
  237. "n": "美国", "v": "5"
  238. }, {
  239. "n": "韩国", "v": "18"
  240. }, {
  241. "n": "日本", "v": "2"
  242. }]
  243. }, {
  244. "key": "year", "name": "年份", "value": [{
  245. "n": "全部", "v": "0"
  246. }, {
  247. "n": "2024", "v": "119"
  248. }, {
  249. "n": "2023", "v": "153"
  250. }, {
  251. "n": "2022", "v": "101"
  252. }, {
  253. "n": "2021", "v": "118"
  254. }, {
  255. "n": "2020", "v": "16"
  256. }, {
  257. "n": "2019", "v": "7"
  258. }, {
  259. "n": "2018", "v": "2"
  260. }, {
  261. "n": "2017", "v": "3"
  262. }, {
  263. "n": "2016", "v": "22"
  264. }]
  265. }, {
  266. "key": "by", "name": "排序", "value": [{
  267. "n": "热门", "v": "hot"
  268. }, {
  269. "n": "更新", "v": "updata"
  270. }, {
  271. "n": "评分", "v": "rating"
  272. }]
  273. }], "3": [{
  274. "key": "area", "name": "地區", "value": [{
  275. "n": "全部", "v": "0"
  276. }, {
  277. "n": "国产", "v": "1"
  278. }, {
  279. "n": "中国香港", "v": "3"
  280. }, {
  281. "n": "中国台湾", "v": "6"
  282. }, {
  283. "n": "美国", "v": "5"
  284. }, {
  285. "n": "韩国", "v": "18"
  286. }, {
  287. "n": "日本", "v": "2"
  288. }]
  289. }, {
  290. "key": "year", "name": "年份", "value": [{
  291. "n": "全部", "v": "0"
  292. }, {
  293. "n": "2024", "v": "119"
  294. }, {
  295. "n": "2023", "v": "153"
  296. }, {
  297. "n": "2022", "v": "101"
  298. }, {
  299. "n": "2021", "v": "118"
  300. }, {
  301. "n": "2020", "v": "16"
  302. }, {
  303. "n": "2019", "v": "7"
  304. }, {
  305. "n": "2018", "v": "2"
  306. }, {
  307. "n": "2017", "v": "3"
  308. }, {
  309. "n": "2016", "v": "22"
  310. }]
  311. }, {
  312. "key": "by", "name": "排序", "value": [{
  313. "n": "热门", "v": "hot"
  314. }, {
  315. "n": "更新", "v": "updata"
  316. }, {
  317. "n": "评分", "v": "rating"
  318. }]
  319. }], "4": [{
  320. "key": "area", "name": "地區", "value": [{
  321. "n": "全部", "v": "0"
  322. }, {
  323. "n": "国产", "v": "1"
  324. }, {
  325. "n": "中国香港", "v": "3"
  326. }, {
  327. "n": "中国台湾", "v": "6"
  328. }, {
  329. "n": "美国", "v": "5"
  330. }, {
  331. "n": "韩国", "v": "18"
  332. }, {
  333. "n": "日本", "v": "2"
  334. }]
  335. }, {
  336. "key": "year", "name": "年份", "value": [{
  337. "n": "全部", "v": "0"
  338. }, {
  339. "n": "2024", "v": "119"
  340. }, {
  341. "n": "2023", "v": "153"
  342. }, {
  343. "n": "2022", "v": "101"
  344. }, {
  345. "n": "2021", "v": "118"
  346. }, {
  347. "n": "2020", "v": "16"
  348. }, {
  349. "n": "2019", "v": "7"
  350. }, {
  351. "n": "2018", "v": "2"
  352. }, {
  353. "n": "2017", "v": "3"
  354. }, {
  355. "n": "2016", "v": "22"
  356. }]
  357. }, {
  358. "key": "by", "name": "排序", "value": [{
  359. "n": "热门", "v": "hot"
  360. }, {
  361. "n": "更新", "v": "updata"
  362. }, {
  363. "n": "评分", "v": "rating"
  364. }]
  365. }]
  366. }
  367. }
  368. async setHomeVod() {
  369. let content = await this.fetch(this.siteUrl + "/api/tag/hand?code=unknown601193cf375db73d&channel=wandoujia", null, this.getHeader())
  370. if (!_.isEmpty(content)) {
  371. let content_json = JSON.parse(content)
  372. let data_list = content_json["data"][0]["video"]
  373. this.homeVodList = await this.parseVodShortListFromJson(data_list)
  374. }
  375. }
  376. async setCategory(tid, pg, filter, extend) {
  377. let cateId = extend["cateId"] ?? tid
  378. let area = extend["area"] ?? "0";
  379. let year = extend["year"] ?? "0";
  380. let by = extend["by"] ?? "hot";
  381. this.limit = 24
  382. let categoryUrl = this.siteUrl + `/api/crumb/list?area=${area}&category_id=${cateId}&page=${pg}&type=0&limit=24&sort=${by}&year=${year}`
  383. await this.jadeLog.debug(`分类URL:${categoryUrl}`)
  384. let content = await this.fetch(categoryUrl, null, this.getHeader())
  385. if (!_.isEmpty(content)) {
  386. let content_json = JSON.parse(content)
  387. let data = content_json["data"]
  388. this.vodList = await this.parseVodShortListFromJson(data)
  389. }
  390. }
  391. async setDetail(id) {
  392. let url = this.siteUrl + "/api/node/detail?channel=wandoujia&token=&id=" + id;
  393. let content = await this.fetch(url, null, this.getHeader())
  394. if (!_.isEmpty(content)) {
  395. let content_json = JSON.parse(content);
  396. let data_list = content_json["data"]
  397. this.vodDetail = await this.parseVodDetailfromJson(data_list)
  398. }
  399. }
  400. async setSearch(wd, quick) {
  401. let url = this.siteUrl + "/api/video/search?page=1" + "&key=" + wd;
  402. const content = await this.fetch(url, null, this.getHeader());
  403. if (!_.isEmpty(content)) {
  404. let content_json = JSON.parse(content)
  405. let data_list = content_json["data"]
  406. this.vodList = await this.parseVodShortListFromJson(data_list)
  407. }
  408. }
  409. async setPlay(flag, id, flags) {
  410. await this.jadeLog.debug(`播放链接为:${id}`)
  411. this.playUrl = id
  412. }
  413. }
  414. let spider = new JianPianSpider()
  415. async function init(cfg) {
  416. await spider.init(cfg)
  417. }
  418. async function home(filter) {
  419. return await spider.home(filter)
  420. }
  421. async function homeVod() {
  422. return await spider.homeVod()
  423. }
  424. async function category(tid, pg, filter, extend) {
  425. return await spider.category(tid, pg, filter, extend)
  426. }
  427. async function detail(id) {
  428. return await spider.detail(id)
  429. }
  430. async function play(flag, id, flags) {
  431. return await spider.play(flag, id, flags)
  432. }
  433. async function search(wd, quick) {
  434. return await spider.search(wd, quick)
  435. }
  436. async function proxy(segments, headers) {
  437. return await spider.proxy(segments, headers)
  438. }
  439. export function __jsEvalReturn() {
  440. return {
  441. init: init,
  442. home: home,
  443. homeVod: homeVod,
  444. category: category,
  445. detail: detail,
  446. play: play,
  447. proxy: proxy,
  448. search: search,
  449. };
  450. }
  451. export {spider}