jianpian.js 15 KB

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