diff --git a/py/libvio.py b/py/libvio.py new file mode 100644 index 00000000..b2537f04 --- /dev/null +++ b/py/libvio.py @@ -0,0 +1,513 @@ +# -*- coding: utf-8 -*- +# by @Qist +""" +LibVio (libvio.run) - 免费在线观影 +""" +import re +import json +import requests +from urllib.parse import quote +from base.spider import Spider + + +class Spider(Spider): + def getName(self): + return "LibVio" + + def init(self, extend=""): + self.host = 'https://www.libvio.run' + self.header = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'Referer': self.host + '/', + 'Origin': self.host, + } + self.timeout = 20 + self.session = requests.Session() + self.session.headers.update(self.header) + + def _safe_get(self, url, max_retries=3): + for attempt in range(max_retries): + try: + resp = self.session.get(url, timeout=self.timeout, verify=False) + resp.encoding = 'utf-8' + return resp + except: + import time + time.sleep(1) + return None + + def _parse_videos(self, html): + videos = [] + seen = set() + pattern = re.compile( + r'href="/detail/(\d+)\.html"[^>]+title="([^"]*)"[^>]+data-original="([^"]*)"[^>]*>.*?' + r'([^<]*).*?' + r'([^<]*)', + re.DOTALL + ) + for m in pattern.finditer(html): + vid = m.group(1) + if vid in seen: + continue + seen.add(vid) + vod_name = m.group(2) + vod_pic = m.group(3) + vod_remarks = m.group(4).strip() + score = m.group(5).strip() + if score and score != '0.0': + vod_remarks = vod_remarks + '/' + score if vod_remarks else score + videos.append({ + 'vod_id': vid, + 'vod_name': vod_name, + 'vod_pic': vod_pic, + 'vod_remarks': vod_remarks, + }) + return videos + + def isVideoFormat(self, url): + pass + + def manualVideoCheck(self): + pass + + def destroy(self): + pass + + def homeContent(self, filter): + try: + result = {'class': [], 'list': []} + classes = [ + {'type_name': '电影', 'type_id': '1'}, + {'type_name': '剧集', 'type_id': '2'}, + {'type_name': '国剧', 'type_id': '13'}, + {'type_name': '动作片', 'type_id': '6'}, + {'type_name': '喜剧片', 'type_id': '7'}, + {'type_name': '爱情片', 'type_id': '8'}, + {'type_name': '科幻片', 'type_id': '9'}, + {'type_name': '恐怖片', 'type_id': '10'}, + {'type_name': '剧情片', 'type_id': '11'}, + {'type_name': '战争片', 'type_id': '12'}, + {'type_name': '动画片', 'type_id': '23'}, + {'type_name': '纪录片', 'type_id': '21'}, + {'type_name': '港台剧', 'type_id': '14'}, + {'type_name': '日韩剧', 'type_id': '15'}, + {'type_name': '欧美剧', 'type_id': '16'}, + {'type_name': '泰国剧', 'type_id': '24'}, + {'type_name': '综艺', 'type_id': '3'}, + {'type_name': '番剧', 'type_id': '4'}, + ] + result['class'] = classes + + # 获取首页推荐视频 + resp = self._safe_get(self.host + '/') + if resp and resp.status_code == 200: + result['list'] = self._parse_videos(resp.text)[:10] + + filter_cfg = { + '1': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "泰国", "v": "泰国"}, + {"n": "英国", "v": "英国"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '6': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '7': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '8': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '9': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '10': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '11': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '12': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '23': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "日本", "v": "日本"}, + {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '21': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "中国台湾", "v": "中国台湾"}, + {"n": "美国", "v": "美国"}, {"n": "日本", "v": "日本"}, + {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '2': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国台湾", "v": "中国台湾"}, {"n": "中国香港", "v": "中国香港"}, + {"n": "韩国", "v": "韩国"}, {"n": "日本", "v": "日本"}, + {"n": "美国", "v": "美国"}, {"n": "泰国", "v": "泰国"}, + {"n": "英国", "v": "英国"}, {"n": "新加坡", "v": "新加坡"}, + {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '13': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '14': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国香港", "v": "中国香港"}, + {"n": "中国台湾", "v": "中国台湾"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '15': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '16': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "美国", "v": "美国"}, + {"n": "英国", "v": "英国"}, {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '24': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "泰国", "v": "泰国"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '3': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "中国香港", "v": "中国香港"}, {"n": "韩国", "v": "韩国"}, + {"n": "日本", "v": "日本"}, {"n": "美国", "v": "美国"}, + {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + '4': [ + {"key": "area", "name": "地区", "value": [ + {"n": "全部", "v": ""}, {"n": "中国大陆", "v": "中国大陆"}, + {"n": "日本", "v": "日本"}, {"n": "美国", "v": "美国"}, + {"n": "其他", "v": "其他"}, + ]}, + {"key": "by", "name": "排序", "value": [ + {"n": "最新", "v": "time"}, {"n": "人气", "v": "hits"}, + {"n": "评分", "v": "score"}, + ]}, + ], + } + result['filters'] = filter_cfg + return result + except Exception as e: + print(f"Error in homeContent: {str(e)}") + return {"class": [], "list": []} + + def homeVideoContent(self): + try: + resp = self._safe_get(self.host + '/') + if not resp or resp.status_code != 200: + return {} + videos = self._parse_videos(resp.text) + return {'list': videos[:30]} + except Exception as e: + print(f"Error in homeVideoContent: {str(e)}") + return {} + + def categoryContent(self, tid, pg, filter, extend): + try: + url = f"{self.host}/show/{tid}--------{pg}---.html" + resp = self._safe_get(url) + if not resp or resp.status_code != 200: + return {'list': [], 'page': int(pg), 'pagecount': 1, 'limit': 0, 'total': 0} + html = resp.text + videos = self._parse_videos(html) + pagecount_match = re.search(r'(\d+)/(\d+)', html) + pagecount = int(pagecount_match.group(2)) if pagecount_match else 999 + last_page_match = re.search(r'class="page-link"[^>]*href="[^"]*-(\d+)---\.html"[^>]*>尾页', html) + if last_page_match: + pagecount = int(last_page_match.group(1)) + return { + 'list': videos, + 'page': int(pg), + 'pagecount': pagecount, + 'limit': len(videos), + 'total': pagecount * len(videos) if videos else 0, + } + except Exception as e: + print(f"Error in categoryContent: {str(e)}") + return {'list': [], 'page': int(pg), 'pagecount': 1, 'limit': 0, 'total': 0} + + def detailContent(self, ids): + try: + vid = ids[0] + url = f"{self.host}/detail/{vid}.html" + resp = self._safe_get(url) + if not resp or resp.status_code != 200: + return {'list': []} + html = resp.text + + vod_name = '' + h1_match = re.search(r']*class="title"[^>]*>([^<]+)', html) + if h1_match: + vod_name = h1_match.group(1).strip() + + vod_pic = '' + thumb_match = re.search(r'class="stui-content__thumb[^"]*"[^>]*>.*?data-original="([^"]+)"', html, re.DOTALL) + if thumb_match: + vod_pic = thumb_match.group(1) + if not vod_pic: + thumb_match2 = re.search(r'data-original="(https?://[^"]+)"', html) + if thumb_match2: + vod_pic = thumb_match2.group(1) + + meta_items = re.findall(r'([^<]+)', html) + type_name = '' + vod_area = '' + vod_year = '' + for item in meta_items: + item = item.strip() + if re.match(r'^\d{4}$', item): + vod_year = item + elif any(k in item for k in ['大陆', '香港', '台湾', '美国', '韩国', '日本', '泰国', '英国', '新加坡', '其他']): + vod_area = item + elif ',' in item or ',' in item: + type_name = item + + vod_actor = '' + vod_director = '' + actor_match = re.search(r'主演[::](.*?)', html) + if actor_match: + vod_actor = actor_match.group(1).strip().rstrip('…') + director_match = re.search(r'导演[::](.*?)', html) + if director_match: + vod_director = director_match.group(1).strip().rstrip('…') + + vod_content = '' + content_match = re.search(r']*>([^<]+)', html) + if content_match: + vod_content = content_match.group(1).strip() + if not vod_content: + sketch_match = re.search(r'([^<]+)', html) + if sketch_match: + vod_content = sketch_match.group(1).strip() + + vod = { + 'vod_id': vid, + 'vod_name': vod_name, + 'vod_pic': vod_pic, + 'vod_remarks': '', + 'vod_year': vod_year, + 'vod_area': vod_area, + 'vod_director': vod_director, + 'vod_actor': vod_actor, + 'vod_content': vod_content, + 'type_name': type_name, + } + + play_from_list = [] + play_url_list = [] + + sections = re.split(r'

', html) + for section in sections[1:]: + h3_end = section.find('

') + if h3_end < 0: + continue + source_name = section[:h3_end].strip() + + playlist_match = re.search(r'class="stui-content__playlist[^"]*"[^>]*>(.*?)', section[h3_end:], re.DOTALL) + if playlist_match: + playlist_html = playlist_match.group(1) + episodes = re.findall(r']+href="(/w/[^"]+)"[^>]*>([^<]*)', playlist_html) + if episodes: + play_from_list.append(source_name) + ep_urls = [] + for ep_href, ep_name in episodes: + play_url = f"{self.host}{ep_href}" + ep_urls.append(f"{ep_name}${play_url}") + play_url_list.append('#'.join(ep_urls)) + else: + netdisk_items = re.findall(r']+class="netdisk-item"[^>]+href="([^"]+)"[^>]*>.*?([^<]*)', section[h3_end:], re.DOTALL) + if netdisk_items: + play_from_list.append(source_name) + ep_urls = [] + for netdisk_url, text in netdisk_items: + ep_name = text.strip() if text.strip() else '网盘下载' + ep_urls.append(f"{ep_name}${netdisk_url}") + play_url_list.append('#'.join(ep_urls)) + + vod['vod_play_from'] = '$$$'.join(play_from_list) + vod['vod_play_url'] = '$$$'.join(play_url_list) + + return {'list': [vod]} + except Exception as e: + print(f"Error in detailContent: {str(e)}") + return {"list": []} + + def searchContent(self, key, quick, pg="1"): + try: + encoded_key = quote(key) + url = f"{self.host}/search/{encoded_key}----------{pg}---.html" + resp = self._safe_get(url) + if not resp or resp.status_code != 200: + return {'list': [], 'page': pg} + videos = self._parse_videos(resp.text) + return {'list': videos, 'page': pg} + except Exception as e: + print(f"Error in searchContent: {str(e)}") + return {'list': [], 'page': pg} + + def playerContent(self, flag, id, vipFlags): + try: + resp = self._safe_get(id) + if not resp or resp.status_code != 200: + return {"parse": 1, "url": id} + + html = resp.text + player_match = re.search(r'var player_aaaa=(\{[^}]+\})', html) + if player_match: + try: + player_data = json.loads(player_match.group(1)) + video_url = player_data.get('url', '') + if video_url: + video_url = video_url.replace('\\/', '/') + if video_url.endswith('.mp4') or '.m3u8' in video_url: + headers = dict(self.header) + headers['Referer'] = id + return { + "parse": 0, + "url": video_url, + "header": headers, + "playUrl": "" + } + else: + return { + "parse": 1, + "url": video_url, + "header": dict(self.header), + "playUrl": "" + } + except: + pass + + return {"parse": 1, "url": id} + except Exception as e: + print(f"Error in playerContent: {str(e)}") + return {"parse": 1, "url": id} + + def localProxy(self, param): + return None diff --git a/tools/dianshi.json b/tools/dianshi.json index 22e95f9f..b47a5eb4 100644 --- a/tools/dianshi.json +++ b/tools/dianshi.json @@ -13,7 +13,8 @@ {"key":"闪雷","name":"闪雷┃MP4","type":3,"api":"./lib/drpy2.min.js","ext":"./js/678.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}}, {"key":"fyyy","name":"飞宇影院","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"http://ntfeiyu.com/nt/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$1#电视剧$2#综艺$3#动漫$4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}}, {"key":"cupfox_in","name":"茶杯狐┃cupfox.in","type":3,"api":"./lib/drpy2.min.js","ext":"./js/茶杯狐.js","searchable":1,"quickSearch":1,"filterable":0,"changeable":1,"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}}, -{"key":"italkbbtv","name":"ITalkBB TV","type":3,"api":"./py/ITalkBBTV.py","searchable":1,"quickSearch":1,"filterable":0,"changeable":1}, +{"key": "libvio","name": "libvio|影视","type": 3,"api": "./py/libvio.py","searchable": 1,"quickSearch": 1,"filterable": 0,"changeable": 1}, +{"key":"italkbbtv","name":"ITalkBB|外","type":3,"api":"./py/ITalkBBTV.py","searchable":1,"quickSearch":1,"filterable":0,"changeable":1}, {"key":"qiletv","name":"奇乐影视","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":"./json/奇乐.json","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}}, diff --git a/tools/jsm.json b/tools/jsm.json index aaa65b22..76f8aa7b 100644 --- a/tools/jsm.json +++ b/tools/jsm.json @@ -14,7 +14,8 @@ {"key":"新闪雷","name":"新闪雷┃MP4","type":3,"api":"./lib/drpy2.min.js","ext":"./js/新闪雷.js","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}}, {"key":"fyyy","name":"飞宇影院","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":{"分类url":"http://ntfeiyu.com/nt/{cateId}/area/{area}/by/{by}/class/{class}/lang/{lang}/page/{catePg}/year/{year}.html","分类":"电影$1#电视剧$2#综艺$3#动漫$4"},"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}}, {"key":"cupfox_in","name":"茶杯狐┃cupfox.in","type":3,"api":"./lib/drpy2.min.js","ext":"./js/茶杯狐.js","searchable":1,"quickSearch":1,"filterable":0,"changeable":1,"header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}}, -{"key":"italkbbtv","name":"ITalkBB TV","type":3,"api":"./py/ITalkBBTV.py","searchable":1,"quickSearch":1,"filterable":0,"changeable":1}, +{"key": "libvio","name": "libvio|影视","type": 3,"api": "./py/libvio.py","searchable": 1,"quickSearch": 1,"filterable": 0,"changeable": 1}, +{"key":"italkbbtv","name":"ITalkBB|外","type":3,"api":"./py/ITalkBBTV.py","searchable":1,"quickSearch":1,"filterable":0,"changeable":1}, {"key":"qiletv","name":"奇乐影视","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"ext":"./json/奇乐.json","header":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Edg/136.0.0.0"}}, {"key": "电影天堂","name": "影视 | 电影天堂","type": 1,"api": "http://caiji.dyttzyapi.com/api.php/provide/vod","searchable": 1,"quickSearch": 1,"filterable": 1,"changeable": 1,"playerType":2},