@mr-quin/dango-manifests 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,42 +6,42 @@ This package is data, not code. There is no `index.ts`: consumers import each ma
6
6
 
7
7
  ## Shipped manifests
8
8
 
9
- | Id | Endpoint | Notes |
10
- | -------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
- | `builtin:dandanplay` | `baseUrl` (default `api.dandanplay.net`) | Unified DDP source. Default official; optional `appId`/`appSecret` signing, `auth` headers, or none (proxy). `baseUrl` overrides the endpoint (proxy / self-hosted). |
12
- | `builtin:bilibili` | `api.bilibili.com` | Parallel media_bangumi + media_ft search; xml + protobuf danmaku variants. |
13
- | `builtin:tencent` | `pbaccess.video.qq.com` + `dm.video.qq.com` | POST bodies, page-cursor episode pagination via forEach `breakOn`, two-phase danmaku (segment index then per-segment fetch). |
14
- | `builtin:hanjutv` | `hxqapi.hiyun.tv` + `hxqapi.zmdcq.com` | Korean-drama source; search, detail-driven episodes, per-segment danmaku. |
15
- | `builtin:mango` | `*.mgtv.com` + `*.hitv.com` | Mango TV; source=imgo search, two-stage showlist episodes, per-minute CDN danmaku shards. |
16
- | `builtin:migu` | `*.migu.cn` + `*.miguvideo.com` | Migu Video; content-info lookup, episodes list, segmented danmaku. |
17
- | `builtin:youku` | `*.youku.com` + `log.mmstat.com` | Youku; HTML-stripped search, openapi episodes, signed per-minute danmaku POSTs (cna guid + \_m_h5_tk token). |
18
- | `builtin:iqiyi` | `*.iqiyi.com` + `mesh.if.iqiyi.com` | iQIYI; /v\_ watch-page search, signed base_info episodes, zlib-deflated XML bullet shards. |
19
- | `builtin:aiyifan` | `yfsp.tv` + `rankv21.tripdata.app` | Aiyifan; homepage-scraped pub/priv keys sign each JSON request; getBarrage danmaku. |
20
- | `builtin:bahamut` | `api.gamer.com.tw` | Bahamut Anime (Traditional Chinese); single danmu.php fetch, time in tenths of a second. |
21
- | `builtin:maiduidui` | `mob.mddcloud.com.cn` | Maiduidui; nested search, listVodSactions episodes, per-minute vodBarrage shards. |
22
- | `builtin:renren` | `api.gorafie.com` + `static-dm.qwdjapp.com` | Renren (foreign drama); array-rooted danmaku with CSV `p` strings. |
23
- | `builtin:sohu` | `*.sohu.com` | Sohu TV; site=1 search, album episodes, paginated dmListAll danmaku (decimal/hex color handling). |
9
+ | Id | Endpoint | Notes |
10
+ | ------------ | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | `dandanplay` | `baseUrl` (default `api.dandanplay.net`) | Unified DDP source. Default official; optional `appId`/`appSecret` signing, `auth` headers, or none (proxy). `baseUrl` overrides the endpoint (proxy / self-hosted). |
12
+ | `bilibili` | `api.bilibili.com` | Parallel media_bangumi + media_ft search; xml + protobuf danmaku variants. |
13
+ | `tencent` | `pbaccess.video.qq.com` + `dm.video.qq.com` | POST bodies, page-cursor episode pagination via forEach `breakOn`, two-phase danmaku (segment index then per-segment fetch). |
14
+ | `hanjutv` | `hxqapi.hiyun.tv` + `hxqapi.zmdcq.com` | Korean-drama source; search, detail-driven episodes, per-segment danmaku. |
15
+ | `mango` | `*.mgtv.com` + `*.hitv.com` | Mango TV; source=imgo search, two-stage showlist episodes, per-minute CDN danmaku shards. |
16
+ | `migu` | `*.migu.cn` + `*.miguvideo.com` | Migu Video; content-info lookup, episodes list, segmented danmaku. |
17
+ | `youku` | `*.youku.com` + `log.mmstat.com` | Youku; HTML-stripped search, openapi episodes, signed per-minute danmaku POSTs (cna guid + \_m_h5_tk token). |
18
+ | `iqiyi` | `*.iqiyi.com` + `mesh.if.iqiyi.com` | iQIYI; /v\_ watch-page search, signed base_info episodes, zlib-deflated XML bullet shards. |
19
+ | `aiyifan` | `yfsp.tv` + `rankv21.tripdata.app` | Aiyifan; homepage-scraped pub/priv keys sign each JSON request; getBarrage danmaku. |
20
+ | `bahamut` | `api.gamer.com.tw` | Bahamut Anime (Traditional Chinese); single danmu.php fetch, time in tenths of a second. |
21
+ | `maiduidui` | `mob.mddcloud.com.cn` | Maiduidui; nested search, listVodSactions episodes, per-minute vodBarrage shards. |
22
+ | `renren` | `api.gorafie.com` + `static-dm.qwdjapp.com` | Renren (foreign drama); array-rooted danmaku with CSV `p` strings. |
23
+ | `sohu` | `*.sohu.com` | Sohu TV; site=1 search, album episodes, paginated dmListAll danmaku (decimal/hex color handling). |
24
24
 
25
25
  ## Layout
26
26
 
27
27
  ```
28
28
  src/
29
29
  manifests/
30
- builtin-aiyifan.json
31
- builtin-bahamut.json
32
- builtin-bilibili.json
33
- builtin-dandanplay.json
34
- builtin-hanjutv.json
35
- builtin-iqiyi.json
36
- builtin-maiduidui.json
37
- builtin-mango.json
38
- builtin-migu.json
39
- builtin-renren.json
40
- builtin-sohu.json
41
- builtin-tencent.json
42
- builtin-youku.json
30
+ aiyifan.json
31
+ bahamut.json
32
+ bilibili.json
33
+ dandanplay.json
34
+ hanjutv.json
35
+ iqiyi.json
36
+ maiduidui.json
37
+ mango.json
38
+ migu.json
39
+ renren.json
40
+ sohu.json
41
+ tencent.json
42
+ youku.json
43
43
  __tests__/
44
- builtin-*.test.ts # per-manifest pipeline tests
44
+ *.test.ts # per-manifest pipeline tests
45
45
  fixtures/ # captured representative responses
46
46
  mockFetcher.ts # shared test fetcher (string + Uint8Array bodies)
47
47
  scripts/
@@ -52,7 +52,7 @@ scripts/
52
52
 
53
53
  ```ts
54
54
  import { ManifestRunner, zManifest } from '@mr-quin/dango'
55
- import builtinDandanplay from '@mr-quin/dango-manifests/manifests/builtin-dandanplay.json' with { type: 'json' }
55
+ import builtinDandanplay from '@mr-quin/dango-manifests/manifests/dandanplay.json' with { type: 'json' }
56
56
 
57
57
  const manifest = zManifest.parse(builtinDandanplay)
58
58
  const runner = new ManifestRunner(manifest, { fetcher })
@@ -66,9 +66,46 @@ const danmaku = await runner.runDanmaku({
66
66
  })
67
67
  ```
68
68
 
69
+ ## CDN consumption
70
+
71
+ A host can discover and fetch manifests over a CDN without bundling this package at build time. jsDelivr and unpkg serve the published package files, so a host reads `catalog.json` for the index, then fetches each entry's `file` path.
72
+
73
+ ```
74
+ https://cdn.jsdelivr.net/npm/@mr-quin/dango-manifests@<version>/catalog.json
75
+ https://cdn.jsdelivr.net/npm/@mr-quin/dango-manifests@<version>/<file>
76
+ ```
77
+
78
+ `catalog.json` is generated from the manifests on disk and ships with the package:
79
+
80
+ ```jsonc
81
+ {
82
+ "packageVersion": "0.4.0",
83
+ "manifests": [
84
+ {
85
+ "id": "bilibili",
86
+ "name": "Bilibili",
87
+ "version": "0.4.0",
88
+ "apiVersion": 1,
89
+ "file": "src/manifests/bilibili.json",
90
+ },
91
+ // ...
92
+ ],
93
+ }
94
+ ```
95
+
96
+ Each `file` is the in-package path to fetch, e.g.:
97
+
98
+ ```
99
+ https://cdn.jsdelivr.net/npm/@mr-quin/dango-manifests@0.4.0/src/manifests/bilibili.json
100
+ ```
101
+
102
+ unpkg works the same way (`https://unpkg.com/@mr-quin/dango-manifests@<version>/...`). Pin a `<version>` for reproducibility; omit it to track the latest published release.
103
+
104
+ `catalog.json` is regenerated as part of `bun run build`; `bun run check` fails if the committed copy is stale (run `bun run catalog` and commit the result).
105
+
69
106
  ## Routing notes
70
107
 
71
- **DanDanPlay** (`builtin:dandanplay`) is one manifest for every DDP endpoint over the `/api/v2` paths. `baseUrl` (config) defaults to the official `api.dandanplay.net`; point it at a proxy or self-hosted server to override. Auth is picked by config: `appId` + `appSecret` sign each request (`X-Signature: Base64(SHA256(appId + timestamp + path + appSecret))`, secret never sent); else `auth.enabled` + `auth.headers` attach custom headers; else no auth (for a proxy that signs server-side). The official API is just the case with no `baseUrl` and credentials set.
108
+ **DanDanPlay** (`dandanplay`) is one manifest for every DDP endpoint over the `/api/v2` paths. `baseUrl` (config) defaults to the official `api.dandanplay.net`; point it at a proxy or self-hosted server to override. Auth is picked by config: `appId` + `appSecret` sign each request (`X-Signature: Base64(SHA256(appId + timestamp + path + appSecret))`, secret never sent); else `auth.enabled` + `auth.headers` attach custom headers; else no auth (for a proxy that signs server-side). The official API is just the case with no `baseUrl` and credentials set.
72
109
 
73
110
  **Bilibili** and **Tencent** call their public APIs directly. Both rely on `rewriteHeaders` for `Origin` / `Referer`, which a browser host's `FetchLike` applies via a request-header rewrite mechanism such as `chrome.declarativeNetRequest`. The smoke script merges those headers in directly since Node fetch lets you set them.
74
111
 
@@ -86,7 +123,7 @@ The smoke fetcher keeps a per-host cookie jar so bilibili's anti-bot wall lets u
86
123
 
87
124
  ## Adding a new manifest
88
125
 
89
- 1. Drop the JSON file in `src/manifests/`. Use `id: 'builtin:<source>'`.
126
+ 1. Drop the JSON file in `src/manifests/`. Use `id: '<source>'`.
90
127
  2. Capture representative responses from the source's API to `src/__tests__/fixtures/`.
91
128
  3. Write a per-manifest test that:
92
129
  - Parses the manifest against `zManifest` (catches schema drift)
@@ -107,5 +144,5 @@ Manifests in this package are vetted at PR review time and shipped as built-ins.
107
144
  | `bun test` | bun test, fixture-backed pipeline tests |
108
145
  | `bun run smoke <source>` | Live end-to-end test against the real API (manual, **not CI**) |
109
146
  | `bun run type-check` | tsc --noEmit |
110
- | `bun run lint` | oxlint |
111
- | `bun run build` | Compile with tsc |
147
+ | `bun run catalog` | Regenerate `catalog.json` from the manifests on disk |
148
+ | `bun run catalog:check` | Fail if the committed `catalog.json` is stale |
package/catalog.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "packageVersion": "0.4.0",
3
+ "manifests": [
4
+ {
5
+ "id": "aiyifan",
6
+ "name": "Aiyifan",
7
+ "version": "0.4.0",
8
+ "apiVersion": 1,
9
+ "file": "src/manifests/aiyifan.json"
10
+ },
11
+ {
12
+ "id": "bahamut",
13
+ "name": "Bahamut",
14
+ "version": "0.4.0",
15
+ "apiVersion": 1,
16
+ "file": "src/manifests/bahamut.json"
17
+ },
18
+ {
19
+ "id": "bilibili",
20
+ "name": "Bilibili",
21
+ "version": "0.4.0",
22
+ "apiVersion": 1,
23
+ "file": "src/manifests/bilibili.json"
24
+ },
25
+ {
26
+ "id": "dandanplay",
27
+ "name": "DanDanPlay",
28
+ "version": "0.4.0",
29
+ "apiVersion": 1,
30
+ "file": "src/manifests/dandanplay.json"
31
+ },
32
+ {
33
+ "id": "hanjutv",
34
+ "name": "Hanjutv",
35
+ "version": "0.4.0",
36
+ "apiVersion": 1,
37
+ "file": "src/manifests/hanjutv.json"
38
+ },
39
+ {
40
+ "id": "iqiyi",
41
+ "name": "iQIYI",
42
+ "version": "0.4.0",
43
+ "apiVersion": 1,
44
+ "file": "src/manifests/iqiyi.json"
45
+ },
46
+ {
47
+ "id": "maiduidui",
48
+ "name": "Maiduidui",
49
+ "version": "0.4.0",
50
+ "apiVersion": 1,
51
+ "file": "src/manifests/maiduidui.json"
52
+ },
53
+ {
54
+ "id": "mango",
55
+ "name": "Mango TV",
56
+ "version": "0.4.0",
57
+ "apiVersion": 1,
58
+ "file": "src/manifests/mango.json"
59
+ },
60
+ {
61
+ "id": "migu",
62
+ "name": "Migu Video",
63
+ "version": "0.4.0",
64
+ "apiVersion": 1,
65
+ "file": "src/manifests/migu.json"
66
+ },
67
+ {
68
+ "id": "renren",
69
+ "name": "Renren",
70
+ "version": "0.4.0",
71
+ "apiVersion": 1,
72
+ "file": "src/manifests/renren.json"
73
+ },
74
+ {
75
+ "id": "sohu",
76
+ "name": "Sohu",
77
+ "version": "0.4.0",
78
+ "apiVersion": 1,
79
+ "file": "src/manifests/sohu.json"
80
+ },
81
+ {
82
+ "id": "tencent",
83
+ "name": "Tencent Video",
84
+ "version": "0.4.0",
85
+ "apiVersion": 1,
86
+ "file": "src/manifests/tencent.json"
87
+ },
88
+ {
89
+ "id": "youku",
90
+ "name": "Youku",
91
+ "version": "0.4.0",
92
+ "apiVersion": 1,
93
+ "file": "src/manifests/youku.json"
94
+ }
95
+ ]
96
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mr-quin/dango-manifests",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Built-in dango manifests for danmaku sources",
5
5
  "author": "Mr-Quin",
6
6
  "license": "MIT",
@@ -17,15 +17,18 @@
17
17
  "./manifests/*.json": "./src/manifests/*.json"
18
18
  },
19
19
  "files": [
20
- "src/manifests"
20
+ "src/manifests",
21
+ "catalog.json"
21
22
  ],
22
23
  "scripts": {
23
24
  "type-check": "tsc -p tsconfig.json",
24
25
  "test": "bun test",
26
+ "catalog": "bun run scripts/gen-catalog.ts",
27
+ "catalog:check": "bun run scripts/gen-catalog.ts --check",
25
28
  "smoke": "bun run scripts/smoke-test.ts"
26
29
  },
27
30
  "devDependencies": {
28
31
  "@bufbuild/protobuf": "^2",
29
- "@mr-quin/dango": "0.1.0"
32
+ "@mr-quin/dango": "workspace:*"
30
33
  }
31
34
  }
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:aiyifan",
3
+ "id": "aiyifan",
4
4
  "name": "Aiyifan",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "爱壹帆"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": ["www.yfsp.tv", "rankv21.tripdata.app", "m10.yfsp.tv"],
7
12
  "search": {
8
13
  "inputs": ["q"],
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:bahamut",
3
+ "id": "bahamut",
4
4
  "name": "Bahamut",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "巴哈姆特"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": ["api.gamer.com.tw"],
7
12
  "search": {
8
13
  "inputs": ["q"],
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:bilibili",
3
+ "id": "bilibili",
4
4
  "name": "Bilibili",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "B站",
8
+ "configSchema.properties.danmakuFormat.title": "弹幕格式",
9
+ "configSchema.properties.danmakuFormat.description": "xml 是旧版接口,最多约 3000 条弹幕;protobuf 分页返回全部弹幕",
10
+ "cookieSet.title": "登录B站"
11
+ }
12
+ },
13
+ "version": "0.4.0",
6
14
  "hosts": ["api.bilibili.com"],
7
15
  "urlMatch": [
8
16
  {
@@ -1,8 +1,27 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:dandanplay",
3
+ "id": "dandanplay",
4
4
  "name": "DanDanPlay",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "弹弹play",
8
+ "configSchema.properties.baseUrl.title": "基础地址",
9
+ "configSchema.properties.baseUrl.description": "弹弹play(或兼容)API 的根地址。默认为官方 https://api.dandanplay.net。指向代理或自建服务器即可覆盖。",
10
+ "configSchema.properties.appId.title": "应用 ID",
11
+ "configSchema.properties.appId.description": "弹弹play 开放平台的 App ID。使用官方 API 时需填写;由代理在服务端签名时可留空。",
12
+ "configSchema.properties.appSecret.title": "应用密钥",
13
+ "configSchema.properties.appSecret.description": "弹弹play 开放平台的 App Secret,用于对官方 API 的请求进行签名。",
14
+ "configSchema.properties.auth.title": "鉴权",
15
+ "configSchema.properties.auth.description": "随每个请求发送的自定义请求头(如 token)。未设置 appId/appSecret 时用于替代签名,例如对接自建的兼容服务器。",
16
+ "configSchema.properties.auth.properties.enabled.title": "启用鉴权请求头",
17
+ "configSchema.properties.auth.properties.headers.title": "请求头",
18
+ "configSchema.properties.auth.properties.headers.items.properties.key.title": "请求头名称",
19
+ "configSchema.properties.auth.properties.headers.items.properties.value.title": "值",
20
+ "configSchema.properties.chConvert.title": "中文转换",
21
+ "configSchema.properties.chConvert.description": "0 = 不转换,1 = 转为简体,2 = 转为繁体"
22
+ }
23
+ },
24
+ "version": "0.4.0",
6
25
  "hosts": ["*"],
7
26
  "configSchema": {
8
27
  "type": "object",
@@ -15,12 +34,12 @@
15
34
  "appId": {
16
35
  "type": "string",
17
36
  "title": "App ID",
18
- "description": "DanDanPlay open-platform App ID. Required for the official API; omit when using a proxy that signs server-side."
37
+ "description": "DanDanPlay open-platform App ID. Required when using the official API; leave empty when a proxy signs requests server-side."
19
38
  },
20
39
  "appSecret": {
21
40
  "type": "string",
22
41
  "title": "App Secret",
23
- "description": "DanDanPlay open-platform App Secret, used to sign requests. Only feeds the local signature, never sent."
42
+ "description": "DanDanPlay open-platform App Secret. Used to sign requests to the official API."
24
43
  },
25
44
  "auth": {
26
45
  "type": "object",
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:hanjutv",
3
+ "id": "hanjutv",
4
4
  "name": "Hanjutv",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "韩剧TV"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": ["hxqapi.hiyun.tv", "hxqapi.zmdcq.com"],
7
12
  "search": {
8
13
  "inputs": ["q"],
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:iqiyi",
3
+ "id": "iqiyi",
4
4
  "name": "iQIYI",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "爱奇艺"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": [
7
12
  "mesh.if.iqiyi.com",
8
13
  "pcw-api.iq.com",
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:maiduidui",
3
+ "id": "maiduidui",
4
4
  "name": "Maiduidui",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "埋堆堆"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": ["mob.mddcloud.com.cn"],
7
12
  "search": {
8
13
  "inputs": ["q"],
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:mango",
3
+ "id": "mango",
4
4
  "name": "Mango TV",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "芒果TV"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": [
7
12
  "mobileso.bz.mgtv.com",
8
13
  "pcweb.api.mgtv.com",
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:migu",
3
+ "id": "migu",
4
4
  "name": "Migu Video",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "咪咕视频"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": ["jadeite.migu.cn", "v3-sc.miguvideo.com", "webapi.miguvideo.com"],
7
12
  "search": {
8
13
  "inputs": ["q"],
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:renren",
3
+ "id": "renren",
4
4
  "name": "Renren",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "人人"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": ["api.gorafie.com", "static-dm.qwdjapp.com"],
7
12
  "search": {
8
13
  "inputs": ["q"],
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:sohu",
3
+ "id": "sohu",
4
4
  "name": "Sohu",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "搜狐视频"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": ["m.so.tv.sohu.com", "api.tv.sohu.com", "api.danmu.tv.sohu.com"],
7
12
  "search": {
8
13
  "inputs": ["q"],
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:tencent",
3
+ "id": "tencent",
4
4
  "name": "Tencent Video",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "腾讯视频",
8
+ "cookieSet.title": "访问腾讯视频以设置 Cookie"
9
+ }
10
+ },
11
+ "version": "0.4.0",
6
12
  "hosts": ["pbaccess.video.qq.com", "dm.video.qq.com"],
7
13
  "urlMatch": [
8
14
  {
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "apiVersion": 1,
3
- "id": "builtin:youku",
3
+ "id": "youku",
4
4
  "name": "Youku",
5
- "version": "0.2.0",
5
+ "locales": {
6
+ "zh-CN": {
7
+ "name": "优酷"
8
+ }
9
+ },
10
+ "version": "0.4.0",
6
11
  "hosts": [
7
12
  "search.youku.com",
8
13
  "openapi.youku.com",
@@ -29,16 +34,21 @@
29
34
  "inputs": ["showId"],
30
35
  "steps": [
31
36
  {
32
- "type": "http",
33
- "id": "page",
37
+ "type": "forEach",
38
+ "id": "pages",
39
+ "in": "$range(1, 51)",
40
+ "as": "page",
34
41
  "request": {
35
42
  "method": "GET",
36
43
  "url": "'https://openapi.youku.com/v2/shows/videos.json'",
37
- "query": "{ 'client_id': '53e6cc67237fc59a', 'package': 'com.huawei.hwvplayer.youku', 'ext': 'show', 'show_id': showId, 'page': '1', 'count': '100' }"
38
- }
44
+ "query": "{ 'client_id': '53e6cc67237fc59a', 'package': 'com.huawei.hwvplayer.youku', 'ext': 'show', 'show_id': showId, 'page': $string(page), 'count': '100' }"
45
+ },
46
+ "collect": "videos",
47
+ "breakOn": "$count($) < 100",
48
+ "throttleMs": 100
39
49
  }
40
50
  ],
41
- "output": "[page.videos.{ 'providerIds': { 'vid': id }, 'indexedId': id, 'title': title, 'episodeNumber': $number(stage), 'imageUrl': thumbnail_v2 }]"
51
+ "output": "[pages.{ 'providerIds': { 'vid': id }, 'indexedId': id, 'title': title, 'episodeNumber': $number(stage), 'imageUrl': thumbnail_v2 }]"
42
52
  },
43
53
  "danmaku": {
44
54
  "inputs": ["vid"],