From 19e1ad13a840f5d6ccdb4d92d421ed0a44816f64 Mon Sep 17 00:00:00 2001 From: zhiyu1998 Date: Fri, 25 Nov 2022 22:27:33 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20=E5=A2=9E=E5=8A=A0=E5=93=94?= =?UTF-8?q?=E5=93=A9=E5=93=94=E5=93=A9=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/tools.js | 95 +++++++++++++++++++++++++++++++++-------------- utils/bilibili.js | 91 +++++++++++++++++++++++++++++++++++++++++++++ utils/file.js | 30 +++++++++++++++ 3 files changed, 189 insertions(+), 27 deletions(-) create mode 100644 utils/bilibili.js create mode 100644 utils/file.js diff --git a/apps/tools.js b/apps/tools.js index 4190cf0..24fa1a0 100644 --- a/apps/tools.js +++ b/apps/tools.js @@ -5,7 +5,9 @@ import { segment } from "oicq"; // 其他库 import md5 from "md5"; import axios from "axios"; -import path from 'path' +import _ from 'lodash' +import { mkdirsSync } from '../utils/file.js' +import { downloadBFile, getDownloadUrl, mergeFileToMp4 } from '../utils/bilibili.js' export class tools extends plugin { constructor () { @@ -27,6 +29,10 @@ export class tools extends plugin { reg: "(.*)(www.tiktok.com)", fnc: "tiktok", }, + { + reg: "(.*)(bilibili.com)", + fnc: "bili", + }, ], }); this.defaultPath = `./data/rcmp4/` @@ -90,6 +96,34 @@ export class tools extends plugin { return true } + // bilibi解析 + async bili (e) { + const urlRex = /(http:|https:)\/\/www.bilibili.com\/[A-Za-z\d._?%&+\-=\/#]*/g; + const url = urlRex.exec(e.msg.trim())[0] + + const path = `${ this.defaultPath }${ this.e.group_id || this.e.user_id }/temp` + // 待优化 + if (fs.existsSync(`${ path }.mp4`)) { + console.log("视频已存在"); + fs.unlinkSync(`${ path }.mp4`); + } + e.reply('识别:哔哩哔哩,解析中...') + await getDownloadUrl(url) + .then(data => { + this.downBili(path, data.videoUrl, data.audioUrl) + .then(data => { + e.reply(segment.video(`${ path }.mp4`)) + }) + .catch(data => { + e.reply('解析失败,请重试一下') + }); + }) + .catch(err => { + e.reply('解析失败,请重试一下') + }); + return true + } + // 请求参数 async douyinRequest (url) { const params = { @@ -112,10 +146,10 @@ export class tools extends plugin { }); } - // 根URL据下载视频 / 音频 + // 工具:根URL据下载视频 / 音频 async downloadVideo (url) { if (!fs.existsSync(this.defaultPath)) { - this.mkdirsSync(this.defaultPath); + mkdirsSync(this.defaultPath); } const target = this.defaultPath + `${ this.e.group_id || this.e.user_id }/temp.mp4` // 待优化 @@ -140,29 +174,36 @@ export class tools extends plugin { }); } - // 同步递归创建文件夹 - mkdirsSync (dirname) { - if (fs.existsSync(dirname)) { - return true; - } else { - if (this.mkdirsSync(path.dirname(dirname))) { - fs.mkdirSync(dirname); - return true; - } - } - } - - // 递归创建目录 异步方法 - mkdirs (dirname, callback) { - fs.exists(dirname, function (exists) { - if (exists) { - callback(); - } else { - // console.log(path.dirname(dirname)); - this.mkdirs(path.dirname(dirname), function () { - fs.mkdir(dirname, callback); - }); - } - }); + // 工具:下载哔哩哔哩 + async downBili (title, videoUrl, audioUrl) { + return Promise.all([ + downloadBFile( + videoUrl, + title + '-video.m4s', + _.throttle( + value => + console.log('download-progress', { + type: 'video', + data: value, + }), + 1000, + ), + ), + downloadBFile( + audioUrl, + title + '-audio.m4s', + _.throttle( + value => + console.log('download-progress', { + type: 'audio', + data: value, + }), + 1000, + ), + ), + ]) + .then(data => { + return mergeFileToMp4(data[0].fullFileName, data[1].fullFileName, title + '.mp4'); + }) } } diff --git a/utils/bilibili.js b/utils/bilibili.js new file mode 100644 index 0000000..e2d388e --- /dev/null +++ b/utils/bilibili.js @@ -0,0 +1,91 @@ +import fs from "node:fs"; +import axios from 'axios' +import child_process from 'node:child_process' + +function downloadBFile (url, fullFileName, progressCallback) { + return axios + .get(url, { + responseType: 'stream', + headers: { + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36', + referer: 'https://www.bilibili.com', + }, + }) + .then(({ data, headers }) => { + let currentLen = 0; + const totalLen = headers['content-length']; + + return new Promise((resolve, reject) => { + data.on('data', ({ length }) => { + currentLen += length; + progressCallback?.(currentLen / totalLen); + }); + + data.pipe( + fs.createWriteStream(fullFileName).on('finish', () => { + resolve({ + fullFileName, + totalLen, + }); + }), + ); + }); + }); +} + +function getDownloadUrl (url) { + return axios + .get(url, { + headers: { + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36', + referer: 'https://www.bilibili.com', + }, + }) + .then(({ data }) => { + const info = JSON.parse( + data.match(/