Example #1
0
    async def get_60s_bullets(self, vid: str, tokens: dict, min_at: int):
        """获取一分钟的弹幕"""
        app_key = "24679788"
        api = "https://acs.youku.com/h5/mopen.youku.danmu.list/1.0/"
        timestamp = str(int(time.time() * 1000))
        msg = {
            "ctime": timestamp,
            "ctype": 10004,
            "cver": "v1.0",
            "guid": tokens["cna"],
            "mat": min_at,
            "mcount": 1,
            "pid": 0,
            "sver": "3.1.0",
            "type": 1,
            "vid": vid
        }
        # 将 msg 转换为 base64 后作为 msg 的一个键值对
        msg_b64 = b64encode(json.dumps(msg, separators=(',', ':')))
        sign = md5(msg_b64 + "MkmC9SoIw6xCkSKHhJ7b5D2r51kBiREr")  # 计算签名
        msg.update({"msg": msg_b64, "sign": sign})
        timestamp = str(int(time.time() * 1000))
        data = json.dumps(msg, separators=(',', ':'))
        sign = md5(f"{tokens['_m_h5_tk'][:32]}&{timestamp}&{app_key}&{data}")

        params = {
            "jsv": "2.5.6",
            "appKey": app_key,
            "t": timestamp,
            "sign": sign,
            "api": "mopen.youku.danmu.list",
            "v": "1.0",
            "type": "originaljson",
            "dataType": "jsonp",
            "timeout": "20000",
            "jsonpIncPrefix": "utility"
        }
        self.session.cookie_jar.update_cookies(tokens)
        headers = {"Referer": "https://v.youku.com"}
        resp = await self.post(api,
                               params=params,
                               data={"data": data},
                               headers=headers)
        data = await resp.json(content_type=None)
        comments = data["data"]["result"]  # 带转义的 json 串
        comments = json.loads(comments)["data"]["result"]  # 返回的数据层层套娃 :(

        result = DanmakuData()
        for comment in comments:
            properties = json.loads(comment["propertis"])  # 弹幕的属性(官方拼写错误)
            color = properties["color"]
            position = properties["pos"]
            # size = properties["size"]
            result.append_bullet(time=comment["playat"] // 1000,
                                 pos=position,
                                 color=color,
                                 message=comment["content"])
        return result
Example #2
0
    async def parse(self, raw_url: str):
        # 加密算法 Smali 位置
        # .class final Lorg/daimhim/zzzfun/data/remote/HttpRequestManager$getVideoPlayInfo$2;
        # .source "HttpRequestManager.kt"
        # .method public final invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
        # .line 460 ~ .line 463
        secret_key = "zan109drdddzz"
        now = int(time.time() * 1000)  # 13 位时间戳
        sing = md5(secret_key + str(now))

        # 接口随 App 更新变化
        play_api = "http://service-agbhuggw-1259251677.gz.apigw.tencentcs.com/android/video/112play"
        payload = {
            "playid": raw_url,
            "userid": "",
            "apptoken": "",
            "sing": sing,
            "map": now
        }
        resp = await self.post(play_api,
                               data=payload,
                               headers={"User-Agent": "okhttp/3.12.0"})
        if not resp or resp.status != 200:
            return ""
        data = await resp.json(content_type=None)
        if not data["data"]:
            return ""
        real_url = data["data"]["videoplayurl"]
        if "alicdn" in real_url or "zzzhls" in real_url:
            # m3u8 格式, 该资源解析后访问一次立刻失效, 内部视频片段不会立刻失效
            return AnimeInfo(real_url, volatile=True)
        return AnimeInfo(real_url)
Example #3
0
 def get_signed_url(url: str) -> str:
     """计算 URL 的签名"""
     # 加密算法见: https://www.libvio.com/static/img/load.html
     # 代码使用 sojson v6 进行混淆
     path = urlparse(url).path
     t = format(int(time.time()) + 300, 'x')  # 时间戳的十六进制表示
     key = "y4nZpZYXK7SOr3wWlvyD0RTl8ti61IbeVFTjpLQv21hPKKTy"
     sign = md5(key + path + t).lower()
     return f"{url}?sign={sign}&t={t}"
Example #4
0
    async def parse(self, raw_url: str):
        play_id, play_vid = raw_url.split("|")
        if play_vid.startswith("http"):
            return play_vid  # 不用处理了

        headers = {
            "Origin": "https://web.age-spa.com:8443",
            "Referer": "https://web.age-spa.com:8443/"
        }
        api = "https://api.agefans.app/v2/_getplay"
        resp = await self.get(api, headers=headers)
        if not resp or resp.status != 200:
            return ""
        data = await resp.json(content_type=None)
        # 参数 kp 算法见 https://vip.cqkeb.com/agefans/js/chunk-3a9344fa.3f1985c3.js
        play_key = "agefans3382-getplay-1719"
        timestamp = data["ServerTime"]
        kp = md5(
            str(timestamp) + "{|}" + play_id + "{|}" + play_vid + "{|}" +
            play_key)
        next_api = data["Location"]
        params = {
            "playid": play_id,
            "vid": play_vid,
            "kt": timestamp,
            "kp": kp
        }
        resp = await self.get(next_api, params=params, headers=headers)
        if not resp or resp.status != 200:
            return ""
        data = await resp.json(content_type=None)
        v_url, p_url = data["vurl"], data["purlf"]
        if v_url or p_url:
            url = p_url + v_url
            url = url.split("?url=")[-1]
            return url
        return ""
Example #5
0
    async def parse(self, raw_url: str):
        play_id, play_vid = raw_url.split("|")
        if play_vid.startswith("http"):
            return play_vid  # 不用处理了

        api = "https://api.agefans.app/v2/_getplay"
        resp = await self.get(api)
        if not resp or resp.status != 200:
            return ""

        data = await resp.json(content_type=None)
        next_api = data.get("Location")
        if not next_api:
            return ""

        # 参数 kp 算法见 https://vip.cqkeb.com/agefans/js/chunk-3a9344fa.3f1985c3.js
        play_key = "agefans3382-getplay-1719"
        timestamp = data["ServerTime"]
        kp = md5(
            str(timestamp) + "{|}" + play_id + "{|}" + play_vid + "{|}" +
            play_key)
        params = {
            "playid": play_id,
            "vid": play_vid,
            "kt": timestamp,
            "kp": kp
        }
        resp = await self.get(next_api, params=params)
        if not resp or resp.status != 200:
            return ""
        data = await resp.json(content_type=None)
        p_url = data.get("purlf", "")
        v_url = data.get("vurl", "")
        url = p_url + v_url
        if not url:
            return ""
        return url.split("?url=")[-1]