refactor: 将各视频站弹幕获取模块改为类实现

This commit is contained in:
lyz05
2025-11-20 17:22:45 +08:00
parent 91668bcd6a
commit 0eef51207d
14 changed files with 307 additions and 306 deletions

7
app.js
View File

@@ -9,8 +9,10 @@ require("dotenv")
.config();
// 引入一个个路由模块
const danmakuRouter = require("./routes/danmaku");
const danmakuRouter = require("./routes/danmaku.mjs").default;
const app = express();
// 加载路由
app.use("/", danmakuRouter);
// 启用gzip压缩
app.use(compression());
@@ -33,8 +35,7 @@ app.use("/assets", [
express.static(__dirname + "/node_modules/leancloud-storage/dist",{maxAge: 86400*1000}),
]);
// 加载路由
app.use("/", danmakuRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {

View File

@@ -1,16 +0,0 @@
//引入API组件
const Bilibili = require("./bilibili");
const Mgtv = require("./mgtv");
const Tencentvideo = require("./tencentvideo");
const Youku = require("./youku");
const Iqiyi = require("./iqiyi");
const Gamer = require("./gamer");
// 实例化API组件
const bilibili = new Bilibili();
const mgtv = new Mgtv();
const tencentvideo = new Tencentvideo();
const youku = new Youku();
const iqiyi = new Iqiyi();
const gamer = new Gamer();
//TODO 优化代码
module.exports = { bilibili, mgtv, tencentvideo, youku, iqiyi, gamer };

54
routes/api/base.mjs Normal file
View File

@@ -0,0 +1,54 @@
export default class BaseSource {
// 构造函数,初始化通用配置
constructor() {
this.name = "";
this.domain = "";
this.example_urls = [];
}
content_template = {
timepoint: 0, // 弹幕发送时间(秒)
ct: 1, // 弹幕类型1-3 为滚动弹幕、4 为底部、5 为顶端、6 为逆向、7 为精确、8 为高级
size: 25, //字体大小25 为中18 为小
color: 16777215, //弹幕颜色RGB 颜色转为十进制后的值16777215 为白色
unixtime: Math.floor(Date.now() / 1000), //Unix 时间戳格式
uid: 0, //发送人的 id
content: "",
}
time_to_second(time) {
const t = time.split(":");
let s = 0;
let m = 1;
while (t.length > 0) {
s += m * parseInt(t.pop(), 10);
m *= 60;
}
return s;
}
// 解析传入的视频网址获取弹幕请求地址Promise数组
async resolve(url) {
throw new Error("Method 'resolve()' must be implemented.");
}
// 请求弹幕资源,返回标准化弹幕内容
async parse(promises) {
throw new Error("Method 'parse()' must be implemented.");
}
// 综合处理入口,返回最终弹幕内容
async work(url) {
const promises = await this.resolve(url);
if (!this.error_msg) {
console.log(this.name, "api lens:", promises.length);
this.content = await this.parse(promises);
}
return {
title: this.title,
content: this.content,
msg: this.error_msg? this.error_msg: "ok"
};
}
}

View File

@@ -1,17 +1,21 @@
const urlmodule = require("url");
const axios = require("axios");
import urlmodule from "url";
import axios from "axios";
import BaseSource from "./base.mjs";
function Bilibili() {
this.name = "B站";
this.domain = "bilibili.com";
this.example_urls = [
"https://www.bilibili.com/video/av170001",
"https://www.bilibili.com/video/av170001?p=2",
"https://www.bilibili.com/video/BV17x411w7KC?p=3",
"https://www.bilibili.com/bangumi/play/ep691614"
];
export default class BilibiliSource extends BaseSource {
constructor() {
super();
this.name = "B站";
this.domain = "bilibili.com";
this.example_urls = [
"https://www.bilibili.com/video/av170001",
"https://www.bilibili.com/video/av170001?p=2",
"https://www.bilibili.com/video/BV17x411w7KC?p=3",
"https://www.bilibili.com/bangumi/play/ep691614"
];
}
this.resolve = async (url) => {
async resolve(url) {
// 相关API
const api_video_info = "https://api.bilibili.com/x/web-interface/view";
const api_epid_cid = "https://api.bilibili.com/pgc/view/web/season";
@@ -60,7 +64,7 @@ function Bilibili() {
};
this.work = async (url) => {
async work(url) {
const urls = await this.resolve(url);
if (!this.error_msg) {
this.url = urls[0];
@@ -73,12 +77,16 @@ function Bilibili() {
};
}
module.exports = Bilibili;
// module.exports = Bilibili;
if(!module.parent) {
const b = new Bilibili();
b.work(b.example_urls[0]).then(() => {
console.log(b.content);
console.log(b.title);
});
}
// if(!module.parent) {
// const b = new Bilibili();
// b.work(b.example_urls[0]).then(() => {
// console.log(b.content);
// console.log(b.title);
// });
// }
// 判断是否直接运行当前文件(跨平台)
// if (fileURLToPath(import.meta.url) === process.argv[1]) {
// console.log("单独运行")
// }

View File

@@ -1,16 +1,20 @@
const urlmodule = require("url");
const axios = require("axios");
const {time_to_second, content_template} = require("./utils");
import urlmodule from "url";
import axios from "axios";
import BaseSource from "./base.mjs";
function Gamer() {
this.name = "巴哈姆特動畫瘋";
this.domain = "gamer.com.tw";
this.example_urls = [
"https://ani.gamer.com.tw/animeVideo.php?sn=41645",
"https://ani.gamer.com.tw/animeVideo.php?sn=41889"
];
export default class GamerSource extends BaseSource {
this.resolve = async (url) => {
constructor() {
super();
this.name = "巴哈姆特動畫瘋";
this.domain = "gamer.com.tw";
this.example_urls = [
"https://ani.gamer.com.tw/animeVideo.php?sn=41645",
"https://ani.gamer.com.tw/animeVideo.php?sn=41889"
];
}
async resolve(url) {
// 相关API
const api_video_info = "https://api.gamer.com.tw/anime/v1/video.php";
const api_danmu = "https://api.gamer.com.tw/anime/v1/danmu.php";
@@ -42,7 +46,7 @@ function Gamer() {
};
this.parse = async (promises) => {
async parse(promises) {
//筛选出成功的请求
let datas = (await Promise.allSettled(promises))
.filter(x => x.status === "fulfilled")
@@ -51,7 +55,7 @@ function Gamer() {
for (let i = 0; i < datas.length; i++) {
const data = datas[i].data;
for (const item of data.danmu) {
const content = JSON.parse(JSON.stringify(content_template));
const content = JSON.parse(JSON.stringify(this.content_template));
content.timepoint = item.time / 10;
content.content = item.text;
content.uid = item.userid;
@@ -63,23 +67,13 @@ function Gamer() {
return contents;
}
this.work = async (url) => {
const promises = await this.resolve(url);
console.log(this.name, "api lens:", promises.length);
this.content = await this.parse(promises);
return {
title: this.title,
content: this.content,
msg: this.error_msg? this.error_msg: "ok"
};
};
}
module.exports = Gamer;
// module.exports = Gamer;
if(!module.parent) {
const g = new Gamer();
g.work(g.example_urls[0]).then(res=>{
console.log(res)
});
}
// if(!module.parent) {
// const g = new Gamer();
// g.work(g.example_urls[0]).then(res=>{
// console.log(res)
// });
// }

View File

@@ -1,21 +1,21 @@
const axios = require("axios");
const pako = require("pako");
const {
time_to_second,
content_template,
} = require("./utils");
const memory = require("../../utils/memory");
import axios from "axios";
import BaseSource from "./base.mjs";
import pako from "pako";
import memory from "../../utils/memory.js";
function Iqiyi() {
this.name = "爱奇艺";
this.domain = "iqiyi.com";
this.example_urls = [
"https://www.iqiyi.com/v_bb6gsxzz78.html",
"https://www.iqiyi.com/v_19rr1lm35o.html",
];
export default class IqiyiSource extends BaseSource {
constructor() {
super();
this.name = "爱奇艺";
this.domain = "iqiyi.com";
this.example_urls = [
"https://www.iqiyi.com/v_bb6gsxzz78.html",
"https://www.iqiyi.com/v_19rr1lm35o.html",
];
}
// 新的tvid获取方法
this.get_tvid = async (url) => {
async get_tvid(url) {
const id = /v_(\w+)/.exec(url)[1];
const api = `https://pcw-api.iq.com/api/decode/${id}?platformId=3&modeCode=intl&langCode=sg`;
const response = await axios.get(api);
@@ -23,13 +23,13 @@ function Iqiyi() {
};
// 获取视频基础信息
this.get_video_info = async (tvid) => {
async get_video_info(tvid) {
const api = `https://pcw-api.iqiyi.com/video/video/baseinfo/${tvid}`;
const response = await axios.get(api);
return response.data.data;
};
this.resolve = async (url) => {
async resolve(url) {
// 1. 获取tvid
const tvid = await this.get_tvid(url);
@@ -68,21 +68,21 @@ function Iqiyi() {
return promises;
};
function extract(xml, tag) {
extract(xml, tag) {
const reg = new RegExp(`<${tag}>(.*?)</${tag}>`, "g");
const res = xml.match(reg)
?.map(x => x.substring(tag.length + 2, x.length - tag.length - 3));
return res || [];
}
this.xml2json = (xml, contents, length) => {
const danmaku = extract(xml, "content");
const showTime = extract(xml, "showTime");
const color = extract(xml, "color");
xml2json(xml, contents, length) {
const danmaku = this.extract(xml, "content");
const showTime = this.extract(xml, "showTime");
const color = this.extract(xml, "color");
const step = Math.ceil(danmaku.length * length / 10000);
for (let i = 0; i < danmaku.length; i += step) {
const content = JSON.parse(JSON.stringify(content_template));
const content = JSON.parse(JSON.stringify(this.content_template));
content.timepoint = showTime[i];
content.color = parseInt(color[i], 16);
content.content = danmaku[i];
@@ -91,7 +91,7 @@ function Iqiyi() {
}
};
this.parse = async (promises) => {
async parse(promises) {
memory();
let datas = (await Promise.allSettled(promises))
.filter(x => x.status === "fulfilled")
@@ -110,25 +110,15 @@ function Iqiyi() {
return contents;
};
this.work = async (url) => {
const promises = await this.resolve(url);
console.log(this.name, "api lens:", promises.length);
this.content = await this.parse(promises);
return {
title: this.title,
content: this.content,
msg: "ok"
};
};
}
module.exports = Iqiyi;
// module.exports = Iqiyi;
if (!module.parent) {
const m = new Iqiyi();
m.work(m.example_urls[0])
.then(() => {
console.log(m.title);
memory();
});
}
// if (!module.parent) {
// const m = new Iqiyi();
// m.work(m.example_urls[0])
// .then(() => {
// console.log(m.title);
// memory();
// });
// }

View File

@@ -1,16 +1,20 @@
const urlmodule = require("url");
const axios = require("axios");
const {time_to_second, content_template} = require("./utils");
import urlmodule from "url";
import axios from "axios";
import BaseSource from "./base.mjs";
function Mgtv() {
this.name = "芒果TV";
this.domain = "mgtv.com";
this.example_urls = [
"https://www.mgtv.com/b/336727/8087768.html",
"https://www.mgtv.com/b/459529/17730031.html" //api lens 90
];
this.resolve = async (url) => {
export default class MgtvSource extends BaseSource {
constructor() {
super();
this.name = "芒果TV";
this.domain = "mgtv.com";
this.example_urls = [
"https://www.mgtv.com/b/336727/8087768.html",
"https://www.mgtv.com/b/459529/17730031.html" //api lens 90
];
}
async resolve(url) {
const api_video_info = "https://pcweb.api.mgtv.com/video/info";
const api_danmaku = "https://galaxy.bz.mgtv.com/rdbarrage";
const q = urlmodule.parse(url, true);
@@ -22,15 +26,15 @@ function Mgtv() {
const time = res.data.data.info.time;
const step = 60 * 1000;
const end_time = time_to_second(time) * 1000;
const end_time = this.time_to_second(time) * 1000;
let promises = [];
for (let i = 0; i < end_time; i += step) {
promises.push(axios({method: "get", url: api_danmaku, params: {vid, cid, time: i}}));
}
return promises;
};
}
this.parse = async (promises) => {
async parse(promises) {
let contents = [];
const results = await Promise.allSettled(promises);
let datas = results.filter(result => result.status === 'fulfilled')
@@ -39,7 +43,7 @@ function Mgtv() {
if (data.data.items === null)
continue;
for (const item of data.data.items) {
const content = JSON.parse(JSON.stringify(content_template));
const content = JSON.parse(JSON.stringify(this.content_template));
content.timepoint = item.time / 1000;
content.content = item.content;
content.uid = item.uid;
@@ -48,29 +52,17 @@ function Mgtv() {
}
// contents = make_response(contents);
return contents;
};
this.work = async (url) => {
const promises = await this.resolve(url);
console.log(this.name,"api lens:", promises.length);
this.content = await this.parse(promises);
return {
title: this.title,
content: this.content,
msg: "ok"
};
};
}
}
module.exports = Mgtv;
// module.exports = Mgtv;
if (!module.parent) {
const m = new Mgtv();
// if (!module.parent) {
// const m = new Mgtv();
m.work(m.example_urls[0]).then(() => {
console.log(m.content);
console.log(m.title);
});
}
// m.work(m.example_urls[0]).then(() => {
// console.log(m.content);
// console.log(m.title);
// });
// }

View File

@@ -1,19 +1,22 @@
const urlmodule = require("url");
const axios = require("axios");
const whacko = require("whacko");
const {content_template} = require("./utils");
import urlmodule from "url";
import axios from "axios";
import BaseSource from "./base.mjs";
import whacko from "whacko";
function Tencentvideo() {
this.name = "腾讯视频";
this.domain = "v.qq.com";
this.example_urls = [
"https://v.qq.com/x/cover/53q0eh78q97e4d1/x00174aq5no.html",//api lens 50
"https://v.qq.com/x/cover/mzc00200fph94nw/l00448ijvve.html",//api lens 91
"https://v.qq.com/x/cover/mzc00200fhhxx8d/h0046u6z1iu.html",//api lens 215 OOM
"https://v.qq.com/x/cover/0s4fa14ciz3ohd0/p0047w54ncc.html",//api lens 297 OOM
];
export default class TencentvideoSource extends BaseSource {
constructor() {
super();
this.name = "腾讯视频";
this.domain = "v.qq.com";
this.example_urls = [
"https://v.qq.com/x/cover/53q0eh78q97e4d1/x00174aq5no.html",//api lens 50
"https://v.qq.com/x/cover/mzc00200fph94nw/l00448ijvve.html",//api lens 91
"https://v.qq.com/x/cover/mzc00200fhhxx8d/h0046u6z1iu.html",//api lens 215 OOM
"https://v.qq.com/x/cover/0s4fa14ciz3ohd0/p0047w54ncc.html",//api lens 297 OOM
];
}
this.resolve = async (url) => {
async resolve(url) {
const api_danmaku_base = "https://dm.video.qq.com/barrage/base/";
const api_danmaku_segment = "https://dm.video.qq.com/barrage/segment/";
const q = urlmodule.parse(url, true);
@@ -43,9 +46,9 @@ function Tencentvideo() {
promises.push(axios.get(`${api_danmaku_segment}${vid}/${item.segment_name}`));
}
return promises;
};
}
this.parse = async (promises) => {
async parse(promises) {
let contents = [];
const results = await Promise.allSettled(promises);
let datas = results.filter(result => result.status === 'fulfilled')
@@ -53,7 +56,7 @@ function Tencentvideo() {
for (const data of datas) {
for (const item of data.barrage_list) {
const content = JSON.parse(JSON.stringify(content_template));
const content = JSON.parse(JSON.stringify(this.content_template));
content.timepoint = item.time_offset / 1000;
if (item.content_style.color) {
const content_style = JSON.stringify(item.content_style.color);
@@ -65,30 +68,17 @@ function Tencentvideo() {
}
// contents = make_response(contents);
return contents;
};
this.work = async (url) => {
const promises = await this.resolve(url);
if (!this.error_msg) {
console.log(this.name, "api lens:", promises.length);
this.content = await this.parse(promises);
}
return {
title: this.title,
content: this.content,
msg: this.error_msg ? this.error_msg : "ok"
};
};
}
}
module.exports = Tencentvideo;
// module.exports = Tencentvideo;
if (!module.parent) {
console.log("main");
const t = new Tencentvideo();
t.work(t.example_urls[0]).then(() => {
console.log(t.content);
console.log(t.title);
});
}
// if (!module.parent) {
// console.log("main");
// const t = new Tencentvideo();
// t.work(t.example_urls[0]).then(() => {
// console.log(t.content);
// console.log(t.title);
// });
// }

View File

@@ -1,22 +0,0 @@
const content_template = {
timepoint: 0, // 弹幕发送时间(秒)
ct: 1, // 弹幕类型1-3 为滚动弹幕、4 为底部、5 为顶端、6 为逆向、7 为精确、8 为高级
size: 25, //字体大小25 为中18 为小
color: 16777215, //弹幕颜色RGB 颜色转为十进制后的值16777215 为白色
unixtime: Math.floor(Date.now() / 1000), //Unix 时间戳格式
uid: 0, //发送人的 id
content: "",
};
function time_to_second(time) {
const t = time.split(":");
let s = 0;
let m = 1;
while (t.length > 0) {
s += m * parseInt(t.pop(), 10);
m *= 60;
}
return s;
}
module.exports = {time_to_second, content_template};

View File

@@ -1,19 +1,22 @@
const urlmodule = require('url');
const axios = require('axios');
const cookie = require('cookie');
const crypto = require('crypto');
const { content_template } = require('./utils');
import urlmodule from "url";
import axios from "axios";
import BaseSource from "./base.mjs";
import cookie from "cookie";
import crypto from "crypto";
function Youku() {
this.name = '优酷';
this.domain = 'v.youku.com';
this.example_urls = [
'https://v.youku.com/v_show/id_XNTE5NjUxNjUyOA==.html',
'https://v.youku.com/v_show/id_XMTc1OTE4ODI5Ng==.html',
'https://v.youku.com/v_show/id_XNTkxNDY2Nzg2MA==.html'
];
export default class YoukuSource extends BaseSource {
constructor() {
super();
this.name = '优酷';
this.domain = 'v.youku.com';
this.example_urls = [
'https://v.youku.com/v_show/id_XNTE5NjUxNjUyOA==.html',
'https://v.youku.com/v_show/id_XMTc1OTE4ODI5Ng==.html',
'https://v.youku.com/v_show/id_XNTkxNDY2Nzg2MA==.html'
];
}
this.get_tk_enc = async () => {
async get_tk_enc() {
const api_url = 'https://acs.youku.com/h5/mtop.com.youku.aplatform.weakget/1.0/?jsv=2.5.1&appKey=24679788';
let cookies = undefined;
// 服务端可能报错:"x-retcode": "FAIL_SYS_INTERNAL_FAULT"
@@ -26,8 +29,8 @@ function Youku() {
targetCookie = Object.assign(targetCookie, cookie.parse(cookieStr));
}
return targetCookie;
};
this.get_cna = async () => {
}
async get_cna() {
const api_url = 'https://log.mmstat.com/eg.js';
const res = await axios.get(api_url);
const cookies = res.headers['set-cookie'];
@@ -36,22 +39,22 @@ function Youku() {
targetCookie = Object.assign(targetCookie, cookie.parse(cookieStr));
}
return targetCookie['cna'];
};
}
const yk_msg_sign = (msg) => {
yk_msg_sign(msg) {
const md5 = crypto.createHash('md5');
return md5.update(msg + 'MkmC9SoIw6xCkSKHhJ7b5D2r51kBiREr')
.digest('hex');
};
}
const yk_t_sign = (token, t, appkey, data) => {
yk_t_sign(token, t, appkey, data) {
const text = [token, t, appkey, data].join('&');
const md5 = crypto.createHash('md5');
return md5.update(text)
.digest('hex');
};
}
const get_vinfos_by_video_id = async (url) => {
async get_vinfos_by_video_id(url) {
const q = urlmodule.parse(url, true);
const path = q.pathname.split('/');
const video_id = path.slice(-1)[0].split('.')[0].slice(3);
@@ -70,9 +73,9 @@ function Youku() {
console.log('video_id:', video_id, 'duration:', duration, 'title:', this.title);
return [video_id, duration];
}
};
}
this.resolve = async (url) => {
async resolve(url) {
const cna = await this.get_cna();
const tk_enc = await this.get_tk_enc();
const headers = {
@@ -81,7 +84,7 @@ function Youku() {
'Referer': 'https://v.youku.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
};
const [vid, duration] = await get_vinfos_by_video_id(url);
const [vid, duration] = await this.get_vinfos_by_video_id(url);
const max_mat = Math.floor(duration / 60) + 1;
let promises = [];
@@ -104,14 +107,14 @@ function Youku() {
const buff = Buffer.from(str, 'utf-8');
const msg_b64encode = buff.toString('base64');
msg['msg'] = msg_b64encode;
msg['sign'] = yk_msg_sign(msg_b64encode);
msg['sign'] = this.yk_msg_sign(msg_b64encode);
const data = JSON.stringify(msg);
const t = Date.now();
const params = {
'jsv': '2.5.6',
'appKey': '24679788',
't': t,
'sign': yk_t_sign(tk_enc['_m_h5_tk'].slice(0, 32), t, '24679788', data),
'sign': this.yk_t_sign(tk_enc['_m_h5_tk'].slice(0, 32), t, '24679788', data),
'api': 'mopen.youku.danmu.list',
'v': '1.0',
'type': 'originaljson',
@@ -125,9 +128,9 @@ function Youku() {
}));
}
return promises;
};
}
this.parse = async (promises) => {
async parse(promises) {
let contents = [];
const results = await Promise.allSettled(promises);
let datas = results.filter(result => result.status === 'fulfilled')
@@ -142,7 +145,7 @@ function Youku() {
// 接口请求情况
// console.log(i, res.ret[0])
for (const danmu of danmus) {
const content = JSON.parse(JSON.stringify(content_template));
const content = JSON.parse(JSON.stringify(this.content_template));
content.timepoint = danmu['playat'] / 1000;
if (danmu.propertis.color) {
content.color = JSON.parse(danmu.propertis).color;
@@ -153,27 +156,17 @@ function Youku() {
}
// contents = make_response(contents);
return contents;
};
}
this.work = async (url) => {
const promises = await this.resolve(url);
console.log(this.name, 'api lens:', promises.length);
this.content = await this.parse(promises);
return {
title: this.title,
content: this.content,
msg: 'ok'
};
};
}
module.exports = Youku;
// module.exports = Youku;
if (!module.parent) {
const b = new Youku();
b.work(b.example_urls[2])
.then(() => {
// console.log(b.content);
console.log(b.title);
});
}
// if (!module.parent) {
// const b = new Youku();
// b.work(b.example_urls[2])
// .then(() => {
// // console.log(b.content);
// console.log(b.title);
// });
// }

View File

@@ -1,18 +1,13 @@
const express = require("express");
const axios = require("axios");
import express from "express";
import axios from "axios";
import { createSourceList } from "./sources.mjs";
import memory from "../utils/memory.js";
import db from "../utils/db.js";
import { inflateRawSync } from "zlib";
const router = express.Router();
const URL = require("url");
const {
bilibili,
mgtv,
tencentvideo,
youku,
iqiyi,
gamer,
} = require("./api/base");
const list = [bilibili, mgtv, tencentvideo, youku, iqiyi, gamer];
const memory = require("../utils/memory");
const db = require("../utils/db");
const list = createSourceList();
const UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
// 返回对象{msg: "ok", title: "标题", content: []}
@@ -81,10 +76,10 @@ async function resolve(req, res) {
// 记录视频信息
db.videoInfoInsert({url,title:ret.title})
//B站视频直接重定向
if (ret.url)
if (ret.url) {
res.redirect(ret.url);
else {
res.set('Cache-Control', 'public, max-age=86400'); // one year
} else {
res.set('Cache-Control', 'public, max-age=86400'); // 缓存一天
res.render("danmaku-xml", { contents: ret.content });
}
}
@@ -131,4 +126,5 @@ router.get("/delete", async function (req, res) {
res.send(`成功请求删除三个月以前的记录,删除情况请查看日志`);
});
module.exports = router;
// module.exports = router;
export default router;

19
routes/sources.mjs Normal file
View File

@@ -0,0 +1,19 @@
import BilibiliSource from "./api/bilibili.mjs";
import MgtvSource from "./api/mgtv.mjs";
import TencentvideoSource from "./api/tencentvideo.mjs";
import YoukuSource from "./api/youku.mjs";
import IqiyiSource from "./api/iqiyi.mjs";
import GamerSource from "./api/gamer.mjs";
export function createSourceList() {
const sourceClasses = [
BilibiliSource,
MgtvSource,
TencentvideoSource,
YoukuSource,
IqiyiSource,
GamerSource
];
return sourceClasses.map(SourceClass => new SourceClass());
}

View File

@@ -1,8 +1,9 @@
let chai = require("chai");
let chaiHttp = require("chai-http");
let app = require("../app");
const { bilibili, mgtv, tencentvideo, youku, iqiyi, gamer } = require("../routes/api/base");
const list = [bilibili, mgtv, tencentvideo, youku, iqiyi, gamer];
import chai from "chai";
import chaiHttp from "chai-http";
import app from "../app.js";
import { createSourceList } from "../routes/sources.mjs";
const list = createSourceList();
chai.should();
chai.use(chaiHttp);
@@ -43,14 +44,15 @@ describe("App", () => {
chai.request(app)
.get("/")
.query({url})
.redirects(0)
.end((err, res) => {
if (err) {
//B站弹幕获取会遇到解压错误
err.code.should.equal("Z_DATA_ERROR")
}
if (res) {
res.should.have.status(200);
res.header["content-type"].should.equal("application/xml; charset=utf-8");
if (name === "B站") {
res.should.redirect;
} else {
res.should.have.status(200);
res.header["content-type"].should.equal("application/xml; charset=utf-8");
}
}
done();
});

View File

@@ -125,24 +125,24 @@ async function deleteAccess() {
}
}
async function main() {
const ret = await deleteAccess();
console.log(ret);
}
// async function main() {
// const ret = await deleteAccess();
// console.log(ret);
// }
if (!module.parent) {
accessInsert({
'ip': '127.0.0.1',
'url': 'https://www.mgtv.com/b/336727/8087768.html',
'UA': 'PostmanRuntime/7.37.3'
});
// if (!module.parent) {
// accessInsert({
// 'ip': '127.0.0.1',
// 'url': 'https://www.mgtv.com/b/336727/8087768.html',
// 'UA': 'PostmanRuntime/7.37.3'
// });
videoInfoInsert({
'url': 'https://www.mgtv.com/b/336727/8087768.html',
'title': '婚前21天'
});
// videoInfoInsert({
// 'url': 'https://www.mgtv.com/b/336727/8087768.html',
// 'title': '婚前21天'
// });
main();
}
// main();
// }
module.exports = { errorInsert, accessInsert, accessCountQuery, videoInfoInsert, hotlistQuery, deleteAccess };