feat: add playerContent with multi-mode play parsing

Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
Harold
2026-04-20 13:10:31 +08:00
co-authored by Claude Opus 4.7
parent 6de6d19da1
commit 103e342a1b
2 changed files with 97 additions and 0 deletions
+42
View File
@@ -211,3 +211,45 @@ class TestJingyuSpider(unittest.TestCase):
self.assertEqual(len(result["list"]), 1)
self.assertEqual(result["list"][0]["vod_name"], "繁花")
self.assertNotIn("pagecount", result)
def test_player_direct_parse_type_0(self):
play_id = "线路一@@direct@@http://parse.com,http://video.m3u8,token+t1,1,0"
result = self.spider.playerContent("线路一", play_id, {})
self.assertEqual(result["parse"], 0)
self.assertEqual(result["url"], "http://video.m3u8")
def test_player_prefix_parse_type_2(self):
play_id = "线路二@@direct@@http://parse.com,http://video.m3u8,token+t1,1,2"
result = self.spider.playerContent("线路二", play_id, {})
self.assertEqual(result["parse"], 1)
self.assertEqual(result["url"], "http://parse.comhttp://video.m3u8")
def test_player_vod_parse_default(self):
play_id = "线路三@@direct@@http://parse.com,http://video.m3u8,token+t1,1,1"
inner = json.dumps({"url": "http://decrypted.m3u8"})
encrypted_inner = self.spider._aes_encrypt(json.dumps({"json": inner}))
class FakeRsp:
status_code = 200
encoding = "utf-8"
def json(self):
return {"data": encrypted_inner}
self.spider.post = lambda url, **kwargs: FakeRsp()
self.spider.host = "http://test.com"
result = self.spider.playerContent("线路三", play_id, {})
self.assertEqual(result["parse"], 0)
self.assertEqual(result["url"], "http://decrypted.m3u8")
def test_player_fetch_parse_player_parse_type_2(self):
play_id = "线路四@@direct@@,http://video.m3u8,token+t1,2,1"
class FakeFetchRsp:
def json(self):
return {"url": "http://fetched.m3u8"}
self.spider.fetch = lambda url, **kwargs: FakeFetchRsp()
self.spider.host = "http://test.com"
result = self.spider.playerContent("线路四", play_id, {})
self.assertEqual(result["parse"], 0)
self.assertEqual(result["url"], "http://fetched.m3u8")
+55
View File
@@ -352,3 +352,58 @@ class Spider(BaseSpider):
"vod_remarks": f"{i.get('vod_year', '')} {i.get('vod_class', '')}".strip(),
} for i in filtered]
return {"list": items, "page": int(pg), "limit": 90, "total": 999999}
def playerContent(self, flag, id, vipFlags):
try:
parts = id.split("@@")
if len(parts) < 3:
return {"parse": 0, "jx": 0, "url": ""}
payload = parts[2]
arr = payload.split(",")
if len(arr) < 5:
return {"parse": 0, "jx": 0, "url": ""}
parse_api = arr[0]
kurl = arr[1]
token = arr[2].replace("token+", "") if arr[2].startswith("token+") else arr[2]
player_parse_type = arr[3]
parse_type = arr[4]
try:
from urllib.parse import unquote
kurl = unquote(kurl)
except Exception:
pass
header = {"User-Agent": "Dalvik/2.1.0 (Linux; Android 14)"}
if parse_type == "0":
return {"parse": 0, "jx": 0, "url": kurl, "header": header}
if parse_type == "2":
return {"parse": 1, "jx": 1, "url": parse_api + kurl, "header": header}
if player_parse_type == "2":
try:
rsp = self.fetch(parse_api + kurl, headers={"User-Agent": self.ua}, timeout=10, verify=False)
fetched = rsp.json()
if fetched.get("url"):
return {"parse": 0, "jx": 0, "url": fetched["url"]}
except Exception:
pass
encrypted_url = self._aes_encrypt(kurl)
res = self._api_post("vodParse", {
"parse_api": parse_api,
"url": encrypted_url,
"player_parse_type": player_parse_type,
"token": token,
})
if not res or not res.get("json"):
return {"parse": 0, "jx": 0, "url": ""}
inner = json.loads(res["json"])
return {"parse": 0, "jx": 0, "url": inner.get("url", "")}
except Exception as e:
self.log(f"播放解析失败: {e}")
return {"parse": 0, "jx": 0, "url": ""}