├── .dockerignore
├── .gitignore
├── .idea
├── .gitignore
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── danmaku.iml
├── inspectionProfiles
│ └── Project_Default.xml
├── jsLibraryMappings.xml
├── jsLinters
│ └── eslint.xml
├── modules.xml
└── vcs.xml
├── Dockerfile
├── README.md
├── app.js
├── bin
└── www
├── fly.toml
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── public
├── favicons
│ └── favicon-16x16.png
└── robots.txt
├── routes
├── api
│ ├── base.js
│ ├── bilibili.js
│ ├── iqiyi.js
│ ├── mgtv.js
│ ├── tencentvideo.js
│ ├── utils.js
│ └── youku.js
└── danmaku.js
├── s.yaml
├── test
└── App.test.js
├── utils
├── db.js
└── memory.js
└── views
├── danmaku-xml.ejs
├── danmaku.ejs
├── error.ejs
└── utils
└── header.ejs
/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 | .dockerignore
3 | node_modules
4 | .git
5 | db
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.toptal.com/developers/gitignore/api/node,webstorm,visualstudiocode
2 | # Edit at https://www.toptal.com/developers/gitignore?templates=node,webstorm,visualstudiocode
3 |
4 | ### Node ###
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 | lerna-debug.log*
12 | .pnpm-debug.log*
13 |
14 | # Diagnostic reports (https://nodejs.org/api/report.html)
15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16 |
17 | # Runtime data
18 | pids
19 | *.pid
20 | *.seed
21 | *.pid.lock
22 |
23 | # Directory for instrumented libs generated by jscoverage/JSCover
24 | lib-cov
25 |
26 | # Coverage directory used by tools like istanbul
27 | coverage
28 | *.lcov
29 |
30 | # nyc test coverage
31 | .nyc_output
32 |
33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
34 | .grunt
35 |
36 | # Bower dependency directory (https://bower.io/)
37 | bower_components
38 |
39 | # node-waf configuration
40 | .lock-wscript
41 |
42 | # Compiled binary addons (https://nodejs.org/api/addons.html)
43 | build/Release
44 |
45 | # Dependency directories
46 | node_modules/
47 | jspm_packages/
48 |
49 | # Snowpack dependency directory (https://snowpack.dev/)
50 | web_modules/
51 |
52 | # TypeScript cache
53 | *.tsbuildinfo
54 |
55 | # Optional npm cache directory
56 | .npm
57 |
58 | # Optional eslint cache
59 | .eslintcache
60 |
61 | # Optional stylelint cache
62 | .stylelintcache
63 |
64 | # Microbundle cache
65 | .rpt2_cache/
66 | .rts2_cache_cjs/
67 | .rts2_cache_es/
68 | .rts2_cache_umd/
69 |
70 | # Optional REPL history
71 | .node_repl_history
72 |
73 | # Output of 'npm pack'
74 | *.tgz
75 |
76 | # Yarn Integrity file
77 | .yarn-integrity
78 |
79 | # dotenv environment variable files
80 | .env
81 | .env.development.local
82 | .env.test.local
83 | .env.production.local
84 | .env.local
85 |
86 | # parcel-bundler cache (https://parceljs.org/)
87 | .cache
88 | .parcel-cache
89 |
90 | # Next.js build output
91 | .next
92 | out
93 |
94 | # Nuxt.js build / generate output
95 | .nuxt
96 | dist
97 |
98 | # Gatsby files
99 | .cache/
100 | # Comment in the public line in if your project uses Gatsby and not Next.js
101 | # https://nextjs.org/blog/next-9-1#public-directory-support
102 | # public
103 |
104 | # vuepress build output
105 | .vuepress/dist
106 |
107 | # vuepress v2.x temp and cache directory
108 | .temp
109 |
110 | # Docusaurus cache and generated files
111 | .docusaurus
112 |
113 | # Serverless directories
114 | .serverless/
115 |
116 | # FuseBox cache
117 | .fusebox/
118 |
119 | # DynamoDB Local files
120 | .dynamodb/
121 |
122 | # TernJS port file
123 | .tern-port
124 |
125 | # Stores VSCode versions used for testing VSCode extensions
126 | .vscode-test
127 |
128 | # yarn v2
129 | .yarn/cache
130 | .yarn/unplugged
131 | .yarn/build-state.yml
132 | .yarn/install-state.gz
133 | .pnp.*
134 |
135 | ### Node Patch ###
136 | # Serverless Webpack directories
137 | .webpack/
138 |
139 | # Optional stylelint cache
140 |
141 | # SvelteKit build / generate output
142 | .svelte-kit
143 |
144 | ### VisualStudioCode ###
145 | .vscode/*
146 | !.vscode/settings.json
147 | !.vscode/tasks.json
148 | !.vscode/launch.json
149 | !.vscode/extensions.json
150 | !.vscode/*.code-snippets
151 |
152 | # Local History for Visual Studio Code
153 | .history/
154 |
155 | # Built Visual Studio Code Extensions
156 | *.vsix
157 |
158 | ### VisualStudioCode Patch ###
159 | # Ignore all local history of files
160 | .history
161 | .ionide
162 |
163 | ### WebStorm ###
164 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
165 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
166 |
167 | # User-specific stuff
168 | .idea/**/workspace.xml
169 | .idea/**/tasks.xml
170 | .idea/**/usage.statistics.xml
171 | .idea/**/dictionaries
172 | .idea/**/shelf
173 |
174 | # AWS User-specific
175 | .idea/**/aws.xml
176 |
177 | # Generated files
178 | .idea/**/contentModel.xml
179 |
180 | # Sensitive or high-churn files
181 | .idea/**/dataSources/
182 | .idea/**/dataSources.ids
183 | .idea/**/dataSources.local.xml
184 | .idea/**/sqlDataSources.xml
185 | .idea/**/dynamic.xml
186 | .idea/**/uiDesigner.xml
187 | .idea/**/dbnavigator.xml
188 |
189 | # Gradle
190 | .idea/**/gradle.xml
191 | .idea/**/libraries
192 |
193 | # Gradle and Maven with auto-import
194 | # When using Gradle or Maven with auto-import, you should exclude module files,
195 | # since they will be recreated, and may cause churn. Uncomment if using
196 | # auto-import.
197 | # .idea/artifacts
198 | # .idea/compiler.xml
199 | # .idea/jarRepositories.xml
200 | # .idea/modules.xml
201 | # .idea/*.iml
202 | # .idea/modules
203 | # *.iml
204 | # *.ipr
205 |
206 | # CMake
207 | cmake-build-*/
208 |
209 | # Mongo Explorer plugin
210 | .idea/**/mongoSettings.xml
211 |
212 | # File-based project format
213 | *.iws
214 |
215 | # IntelliJ
216 | out/
217 |
218 | # mpeltonen/sbt-idea plugin
219 | .idea_modules/
220 |
221 | # JIRA plugin
222 | atlassian-ide-plugin.xml
223 |
224 | # Cursive Clojure plugin
225 | .idea/replstate.xml
226 |
227 | # SonarLint plugin
228 | .idea/sonarlint/
229 |
230 | # Crashlytics plugin (for Android Studio and IntelliJ)
231 | com_crashlytics_export_strings.xml
232 | crashlytics.properties
233 | crashlytics-build.properties
234 | fabric.properties
235 |
236 | # Editor-based Rest Client
237 | .idea/httpRequests
238 |
239 | # Android studio 3.1+ serialized cache file
240 | .idea/caches/build_file_checksums.ser
241 |
242 | ### WebStorm Patch ###
243 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
244 |
245 | # *.iml
246 | # modules.xml
247 | # .idea/misc.xml
248 | # *.ipr
249 |
250 | # Sonarlint plugin
251 | # https://plugins.jetbrains.com/plugin/7973-sonarlint
252 | .idea/**/sonarlint/
253 |
254 | # SonarQube Plugin
255 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
256 | .idea/**/sonarIssues.xml
257 |
258 | # Markdown Navigator plugin
259 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
260 | .idea/**/markdown-navigator.xml
261 | .idea/**/markdown-navigator-enh.xml
262 | .idea/**/markdown-navigator/
263 |
264 | # Cache file creation bug
265 | # See https://youtrack.jetbrains.com/issue/JBR-2257
266 | .idea/$CACHE_FILE$
267 |
268 | # CodeStream plugin
269 | # https://plugins.jetbrains.com/plugin/12206-codestream
270 | .idea/codestream.xml
271 |
272 | # Azure Toolkit for IntelliJ plugin
273 | # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
274 | .idea/**/azureSettings.xml
275 |
276 | # End of https://www.toptal.com/developers/gitignore/api/node,webstorm,visualstudiocode
277 | upload
278 |
279 | .s
280 | db
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # 默认忽略的文件
2 | /shelf/
3 | /workspace.xml
4 | # 基于编辑器的 HTTP 客户端请求
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/danmaku.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/jsLinters/eslint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16.18.0-alpine
2 | ENV TZ Asia/Shanghai
3 |
4 | RUN apk add tzdata sqlite sqlite-dev && cp /usr/share/zoneinfo/${TZ} /etc/localtime \
5 | && echo ${TZ} > /etc/timezone \
6 | && apk del tzdata
7 |
8 | LABEL fly_launch_runtime="nodejs"
9 | WORKDIR /app
10 | COPY ./package.json /app
11 | RUN npm install --production && npm prune --production
12 | COPY . /app
13 | ENV NODE_ENV production
14 |
15 | CMD [ "npm", "run", "start" ]
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # danmaku
2 | 用于解析转换各大视频网站(芒果TV,腾讯视频,优酷视频,爱奇艺视频,哔哩哔哩)弹幕
3 |
4 | # 依赖
5 | - chai: 断言库
6 | - mocha: 测试框架
7 | - ejs: 模板引擎
8 | - express: web框架
9 |
10 | # 运行此项目
11 | ``` sh
12 | npm install # 安装依赖
13 | npm run dev # 本地运行
14 | npm run test # 单元测试
15 | ```
16 |
17 | # 部署到fly.io
18 | ``` sh
19 | curl -L https://fly.io/install.sh | sh #linux
20 | iwr https://fly.io/install.ps1 -useb | iex #windows
21 | export FLYCTL_INSTALL="/home/codespace/.fly"
22 | export PATH="$FLYCTL_INSTALL/bin:$PATH"
23 | flyctl auth login
24 | flyctl deploy
25 | ```
26 |
27 | # 性能提升
28 | 相比于旧版的Python项目,Node对于异步并发的处理能力更强。
29 | Express框架的性能也比Python的Django要好很多。
30 |
31 | # fly.io常用命令
32 | ``` sh
33 | flyctl status
34 | flyctl scale count 0
35 | flyctl regions add sea
36 | flyctl regions remove hkg
37 | flyctl config env
38 | flyctl secrets set DEBUG=true
39 | flyctl ssh console
40 | flyctl checks list
41 | flyctl ssh sftp get /app/db/danmaku.db
42 | ```
43 |
44 | # Node常用工具
45 | ```bash
46 | npm outdated
47 | npm update
48 | ```
49 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | const createError = require("http-errors");
2 | const express = require("express");
3 | const path = require("path");
4 | const cookieParser = require("cookie-parser");
5 | const logger = require("morgan");
6 | const compression = require('compression');
7 | // 引入环境变量
8 | require("dotenv")
9 | .config();
10 |
11 | // 引入一个个路由模块
12 | const danmakuRouter = require("./routes/danmaku");
13 | const app = express();
14 | // 启用gzip压缩
15 | app.use(compression());
16 |
17 | // view engine setup
18 | app.set("views", path.join(__dirname, "views"));
19 | app.set("view engine", "ejs");
20 | app.set("trust proxy", true);
21 |
22 | app.use(logger("dev"));
23 | app.use(express.json());
24 | app.use(express.urlencoded({ extended: false, validate: { trustProxy: false } }));
25 | app.use(cookieParser());
26 | // 加载静态资源
27 | app.use(express.static(path.join(__dirname, "public"), {maxAge: 86400*1000 }));
28 | app.use(express.static(path.join(__dirname,"db")))
29 | app.use("/assets", [
30 | express.static(__dirname + "/node_modules/jquery/dist/",{maxAge: 86400*1000}),
31 | express.static(__dirname + "/node_modules/bootstrap/dist/",{maxAge: 86400*1000}),
32 | express.static(__dirname + "/node_modules/axios/dist/",{maxAge: 86400*1000}),
33 | express.static(__dirname + "/node_modules/leancloud-storage/dist",{maxAge: 86400*1000}),
34 | ]);
35 |
36 | // 加载路由
37 | app.use("/", danmakuRouter);
38 |
39 | // catch 404 and forward to error handler
40 | app.use(function (req, res, next) {
41 | next(createError(404));
42 | });
43 |
44 | // error handler
45 | app.use(function (err, req, res) {
46 | // set locals, only providing error in development
47 | res.locals.message = err.message;
48 | res.locals.error = req.app.get("env") === "development" ? err : {};
49 |
50 | // render the error page
51 | res.status(err.status || 500);
52 | res.render("error");
53 | });
54 |
55 | module.exports = app;
56 |
--------------------------------------------------------------------------------
/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 | const app = require('../app');
7 | const debug = require('debug')('danmaku:server');
8 | const http = require('http');
9 |
10 | /**
11 | * Get port from environment and store in Express.
12 | */
13 | const port = normalizePort(process.env.PORT || '3000');
14 | app.set('port', port);
15 |
16 | /**
17 | * Create HTTP server.
18 | */
19 | const server = http.createServer(app);
20 |
21 | /**
22 | * Listen on provided port, on all network interfaces.
23 | */
24 |
25 | server.listen(port, () => {
26 | console.log(`Listening on port ${port}`);
27 | console.log(`visit: http://localhost:${port}`);
28 | });
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | const port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | const bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | const addr = server.address();
86 | const bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/fly.toml:
--------------------------------------------------------------------------------
1 | # fly.toml app configuration file generated for lyz05-danmaku on 2024-01-11T19:54:43+08:00
2 | #
3 | # See https://fly.io/docs/reference/configuration/ for information about how to use this file.
4 | #
5 |
6 | app = "lyz05-danmaku"
7 | primary_region = "sea"
8 | kill_signal = "SIGINT"
9 | kill_timeout = "5s"
10 |
11 | [experimental]
12 | auto_rollback = true
13 |
14 | [build]
15 |
16 | [env]
17 | PORT = "8080"
18 |
19 | [http_service]
20 | internal_port = 8080
21 | force_https = true
22 | auto_stop_machines = true
23 | auto_start_machines = true
24 | min_machines_running = 0
25 | processes = ["app"]
26 |
27 | [[vm]]
28 | cpu_kind = "shared"
29 | cpus = 1
30 | memory_mb = 512
31 |
32 | [mounts]
33 | source="danmaku"
34 | destination="/app/db"
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "danmaku",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node --expose-gc --max-old-space-size=200 ./bin/www",
7 | "dev": "nodemon --expose-gc --max-old-space-size=200 ./bin/www",
8 | "test": "nyc -a mocha --recursive",
9 | "deploy": "flyctl deploy",
10 | "logs": "flyctl logs"
11 | },
12 | "dependencies": {
13 | "ali-oss": "^6.17.1",
14 | "axios": "^1.2.1",
15 | "bootstrap": "^3.4.1",
16 | "chai": "^4.3.7",
17 | "chai-http": "^4.3.0",
18 | "compression": "^1.7.4",
19 | "cookie": "^0.5.0",
20 | "cookie-parser": "~1.4.4",
21 | "debug": "^4.3.4",
22 | "dotenv": "^16.0.3",
23 | "ejs": "^3.1.8",
24 | "express": "~4.18.2",
25 | "express-rate-limit": "^7.1.5",
26 | "filesize": "^10.0.5",
27 | "got": "^11.8.2",
28 | "http-errors": "~1.6.3",
29 | "jquery": "^3.6.1",
30 | "js-yaml": "^4.1.0",
31 | "leancloud-storage": "^4.13.4",
32 | "lib-qqwry": "^1.2.0",
33 | "moment": "^2.29.4",
34 | "morgan": "~1.9.1",
35 | "multer": "^1.4.5-lts.1",
36 | "node-cron": "^3.0.2",
37 | "node-telegram-bot-api": "^0.60.0",
38 | "openai": "^3.2.1",
39 | "pako": "^1.0.11",
40 | "querystring": "^0.2.1",
41 | "sqlite3": "^5.1.7",
42 | "whacko": "^0.19.1",
43 | "xml-js": "^1.6.11"
44 | },
45 | "devDependencies": {
46 | "eslint-config-airbnb-base": "^15.0.0",
47 | "eslint-plugin-import": "^2.26.0",
48 | "mocha": "^10.1.0",
49 | "nodemon": "^2.0.20",
50 | "nyc": "^15.1.0"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/public/favicons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lyz05/danmaku/d49fe39d79ce8b565d41f008b4286620d41b7207/public/favicons/favicon-16x16.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # robots.txt generated at http://www.w3cschool.cn/
2 | User-agent: *
3 | Disallow:
4 | Crawl-delay: 120
5 | Disallow: /cgi-bin/
6 |
--------------------------------------------------------------------------------
/routes/api/base.js:
--------------------------------------------------------------------------------
1 | //引入API组件
2 | const Bilibili = require("./bilibili");
3 | const Mgtv = require("./mgtv");
4 | const Tencentvideo = require("./tencentvideo");
5 | const Youku = require("./youku");
6 | const Iqiyi = require("./iqiyi");
7 | // 实例化API组件
8 | const bilibili = new Bilibili();
9 | const mgtv = new Mgtv();
10 | const tencentvideo = new Tencentvideo();
11 | const youku = new Youku();
12 | const iqiyi = new Iqiyi();
13 |
14 | //TODO 优化代码
15 | module.exports = { bilibili, mgtv, tencentvideo, youku, iqiyi };
16 |
--------------------------------------------------------------------------------
/routes/api/bilibili.js:
--------------------------------------------------------------------------------
1 | const urlmodule = require("url");
2 | const axios = require("axios");
3 |
4 | function Bilibili() {
5 | this.name = "B站";
6 | this.domain = "bilibili.com";
7 | this.example_urls = [
8 | "https://www.bilibili.com/video/av170001",
9 | "https://www.bilibili.com/video/av170001?p=2",
10 | "https://www.bilibili.com/video/BV17x411w7KC?p=3",
11 | "https://www.bilibili.com/bangumi/play/ep691614"
12 | ];
13 |
14 | this.resolve = async (url) => {
15 | // 相关API
16 | const api_video_info = "https://api.bilibili.com/x/web-interface/view";
17 | const api_epid_cid = "https://api.bilibili.com/pgc/view/web/season";
18 | const q = urlmodule.parse(url, true);
19 | const path = q.pathname.split("/");
20 | // 普通投稿视频
21 | if (url.indexOf("video/") !== -1) {
22 | // 获取视频分P信息
23 | const p = q.query.p || 1;
24 | // 判断是否为旧版av号
25 | let params;
26 | if (url.indexOf("BV") !== -1) {
27 | params = {"bvid": path[2]};
28 | } else {
29 | params = {"aid": path[2].substring(2)};
30 | }
31 | const response = await axios.get(api_video_info, {params});
32 | if (response.data.code !== 0) {
33 | this.error_msg = "获取普通投稿视频信息失败!"+response.data.message;
34 | return;
35 | }
36 | this.title = response.data.data.title;
37 | const subtitle = response.data.data.pages[p - 1].part;
38 | this.title = this.title + "-" + subtitle;
39 | const cid = response.data.data.pages[p - 1].cid;
40 | return [`https://comment.bilibili.com/${cid}.xml`];
41 | } // 番剧
42 | else if (url.indexOf("bangumi/") !== -1 && url.indexOf("ep") !== -1) {
43 | const epid = path.slice(-1)[0];
44 | const params = {"ep_id": epid.slice(2)};
45 | const response = await axios.get(api_epid_cid, {params});
46 | if (response.data.code !== 0) {
47 | this.error_msg = "获取番剧视频信息失败!";
48 | return;
49 | }
50 | for (let i = 0; i < response.data.result.episodes.length; i++) {
51 | if (response.data.result.episodes[i].id == params.ep_id) {
52 | this.title = response.data.result.episodes[i].share_copy;
53 | const cid = response.data.result.episodes[i].cid;
54 | return [`https://comment.bilibili.com/${cid}.xml`];
55 | }
56 | }
57 | } else {
58 | this.error_msg = "不支持的B站视频网址,仅支持普通视频(av,bv)、剧集视频(ep)";
59 | }
60 |
61 | };
62 |
63 | this.work = async (url) => {
64 | const urls = await this.resolve(url);
65 | if (!this.error_msg) {
66 | this.url = urls[0];
67 | }
68 | return {
69 | title: this.title,
70 | url: this.url,
71 | msg: this.error_msg? this.error_msg: "ok"
72 | };
73 | };
74 | }
75 |
76 | module.exports = Bilibili;
77 |
78 | if(!module.parent) {
79 | const b = new Bilibili();
80 | b.work(b.example_urls[0]).then(() => {
81 | console.log(b.content);
82 | console.log(b.title);
83 | });
84 | }
85 |
--------------------------------------------------------------------------------
/routes/api/iqiyi.js:
--------------------------------------------------------------------------------
1 | const axios = require("axios");
2 | const pako = require("pako");
3 | const {
4 | time_to_second,
5 | content_template,
6 | } = require("./utils");
7 | const memory = require("../../utils/memory");
8 |
9 | //资源消耗大 256M内存扛不住
10 | function Iqiyi() {
11 | this.name = "爱奇艺";
12 | this.domain = "iqiyi.com";
13 | this.example_urls = [
14 | "https://www.iqiyi.com/v_19rr1lm35o.html", //api lens 11
15 | "http://www.iqiyi.com/v_1qzx9b00hs4.html?vfm=m_331_dbdy", //api lens 25
16 | "https://www.iqiyi.com/v_19rr1lm35o.html",
17 | ];
18 |
19 | this.resolve = async (url) => {
20 | const res = await axios({
21 | url: url,
22 | method: "get",
23 | headers: {
24 | "Accept-Encoding": "gzip,deflate,compress"
25 | }
26 | });
27 | const data = res.data;
28 | const result = data.match(/
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------