From 2b796e33feb645e5037037cc219ea542d888f148 Mon Sep 17 00:00:00 2001 From: linyuchen Date: Tue, 12 Mar 2024 08:32:51 +0800 Subject: [PATCH 1/2] test: try to send video element --- icon.jpg | Bin 0 -> 42457 bytes src/ntqqapi/constructor.ts | 93 +++++++++++++++++++++++++++------ src/ntqqapi/hook.ts | 5 ++ src/ntqqapi/types.ts | 50 ++++++++++-------- src/onebot11/action/SendMsg.ts | 2 +- 5 files changed, 112 insertions(+), 38 deletions(-) create mode 100644 icon.jpg diff --git a/icon.jpg b/icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..67ca0dad9fd0ac2964870c168090f40abbe3fc52 GIT binary patch literal 42457 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 z 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 literal 0 HcmV?d00001 diff --git a/src/ntqqapi/constructor.ts b/src/ntqqapi/constructor.ts index 94b75a4..eb52616 100644 --- a/src/ntqqapi/constructor.ts +++ b/src/ntqqapi/constructor.ts @@ -1,15 +1,18 @@ import { AtType, - ElementType, PicType, SendArkElement, + ElementType, + PicType, + SendArkElement, SendFaceElement, SendFileElement, SendPicElement, SendPttElement, SendReplyElement, - SendTextElement + SendTextElement, + SendVideoElement } from "./types"; import {NTQQApi} from "./ntcall"; -import {encodeSilk, isGIF} from "../common/utils"; +import {encodeSilk, isGIF, log} from "../common/utils"; import * as fs from "node:fs"; @@ -57,7 +60,7 @@ export class SendMsgElementConstructor { static async pic(picPath: string): Promise { const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(picPath, ElementType.PIC); - if (fileSize === 0){ + if (fileSize === 0) { throw "文件异常,大小为0"; } const imageSize = await NTQQApi.getImageSize(picPath); @@ -84,15 +87,11 @@ export class SendMsgElementConstructor { }; } - static async file(filePath: string, showPreview: boolean = false, fileName: string = ""): Promise { + static async file(filePath: string, fileName: string = ""): Promise { let picHeight = 0; let picWidth = 0; - if (showPreview) { - picHeight = 1024; - picWidth = 768; - } const {md5, fileName: _fileName, path, fileSize} = await NTQQApi.uploadFile(filePath, ElementType.FILE); - if (fileSize === 0){ + if (fileSize === 0) { throw "文件异常,大小为0"; } let element: SendFileElement = { @@ -102,23 +101,87 @@ export class SendMsgElementConstructor { fileName: fileName || _fileName, "filePath": path, "fileSize": (fileSize).toString(), - picHeight, - picWidth } } return element; } - static video(filePath: string, fileName: string=""): Promise { - return SendMsgElementConstructor.file(filePath, true, fileName); + static async video(filePath: string, fileName: string = ""): Promise { + const {md5, fileName: _fileName, path, fileSize} = await NTQQApi.uploadFile(filePath, ElementType.VIDEO); + if (fileSize === 0) { + throw "文件异常,大小为0"; + } + log("上传视频", md5, path, fileSize, fileName || _fileName) + let thumbPath = new Map() + thumbPath.set(0, "E:\\SystemDocuments\\QQ\\721011692\\nt_qq\\nt_data\\Video\\2024-03\\Thumb\\8950eb327e26c01e69d4a0fab7e2b159_0.png") + let element: SendVideoElement = { + elementType: ElementType.VIDEO, + elementId: "", + videoElement: { + fileName: fileName || _fileName, + filePath: path, + videoMd5: md5, + "thumbMd5": "9eee9e9a07b193cbaf4846522b0197b4", + fileTime: 15, + thumbPath: thumbPath, + "thumbSize": 368286, + "fileFormat": 2, + "thumbWidth": 540, + "thumbHeight": 960, + // "busiType": 0, + // "subBusiType": 0, + // fileUuid: md5, + fileSize: "" + fileSize, + "transferStatus": 0, + "progress": 0, + "invalidState": 0, + // "fileUuid": "3051020100043630340201000204169df3d602037a1afd020440f165b4020465f02cb304108950eb327e26c01e69d4a0fab7e2b15802037a1db902010004140000000866696c65747970650000000431303031", + "fileSubId": "", + "fileBizId": null, + "originVideoMd5": "", + "import_rich_media_context": null, + "sourceVideoCodecFormat": 0 + } + } + return element; + log("video element", element) + let e = { + "elementType": 5, + "elementId": "", + "videoElement": { + "filePath": "E:\\SystemDocuments\\QQ\\721011692\\nt_qq\\nt_data\\Video\\2024-03\\Ori\\8950eb327e26c01e69d4a0fab7e2b158.mp4", + "fileName": "8950eb327e26c01e69d4a0fab7e2b158.mp4", + "videoMd5": "8950eb327e26c01e69d4a0fab7e2b158", + "thumbMd5": "9eee9e9a07b193cbaf4846522b0197b4", + "fileTime": 15, + "thumbSize": 368286, + "fileFormat": 2, + "fileSize": "2084867", + "thumbWidth": 540, + "thumbHeight": 960, + "busiType": 0, + "subBusiType": 0, + "thumbPath": thumbPath, + "transferStatus": 0, + "progress": 0, + "invalidState": 0, + "fileUuid": "3051020100043630340201000204169df3d602037a1afd020440f165b4020465f02cb304108950eb327e26c01e69d4a0fab7e2b15802037a1db902010004140000000866696c65747970650000000431303031", + "fileSubId": "", + "fileBizId": null, + "originVideoMd5": "", + "import_rich_media_context": null, + "sourceVideoCodecFormat": 0 + } + } + return e as SendVideoElement } static async ptt(pttPath: string): Promise { const {converted, path: silkPath, duration} = await encodeSilk(pttPath); // log("生成语音", silkPath, duration); const {md5, fileName, path, fileSize} = await NTQQApi.uploadFile(silkPath, ElementType.PTT); - if (fileSize === 0){ + if (fileSize === 0) { throw "文件异常,大小为0"; } if (converted) { diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index 860924f..ee2cc57 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -224,6 +224,10 @@ registerReceiveHook<{ msgList: Array }>(ReceiveCmd.NEW_MSG, (payload continue } for (const msgElement of message.elements) { + if (msgElement.videoElement) { + log("收到视频消息", msgElement.videoElement) + log("視頻缩略图", msgElement.videoElement.thumbPath.get(0)); + } setTimeout(() => { const picPath = msgElement.picElement?.sourcePath const pttPath = msgElement.pttElement?.filePath @@ -235,6 +239,7 @@ registerReceiveHook<{ msgList: Array }>(ReceiveCmd.NEW_MSG, (payload if (aioOpGrayTipElement){ tempGroupCodeMap[aioOpGrayTipElement.peerUid] = aioOpGrayTipElement.fromGrpCodeOfTmpChat; } + // log("需要清理的文件", pathList); for (const path of pathList) { if (path) { diff --git a/src/ntqqapi/types.ts b/src/ntqqapi/types.ts index 8d0b1ed..e7aea8a 100644 --- a/src/ntqqapi/types.ts +++ b/src/ntqqapi/types.ts @@ -71,6 +71,7 @@ export enum ElementType { PIC = 2, FILE = 3, PTT = 4, + VIDEO = 5, FACE = 6, REPLY = 7, ARK = 10, @@ -167,11 +168,16 @@ export interface FileElement { } export interface SendFileElement { - elementType: ElementType.FILE, + elementType: ElementType.FILE elementId: "", fileElement: FileElement } +export interface SendVideoElement { + elementType: ElementType.VIDEO + elementId: "", + videoElement: VideoElement +} export interface SendArkElement { elementType: ElementType.ARK, elementId: "", @@ -180,7 +186,7 @@ export interface SendArkElement { } export type SendMessageElement = SendTextElement | SendPttElement | - SendPicElement | SendReplyElement | SendFaceElement | SendFileElement | SendArkElement + SendPicElement | SendReplyElement | SendFaceElement | SendFileElement | SendVideoElement | SendArkElement export enum AtType { notAt = 0, @@ -258,26 +264,26 @@ export interface FaceElement { export interface VideoElement { "filePath": string, "fileName": string, - "videoMd5": string, - "thumbMd5": string - "fileTime": 87, // second - "thumbSize": 314235, // byte - "fileFormat": 2, // 2表示mp4? - "fileSize": string, // byte - "thumbWidth": number, - "thumbHeight": number, - "busiType": 0, // 未知 - "subBusiType": 0, // 未知 - "thumbPath": Map, - "transferStatus": 0, // 未知 - "progress": 0, // 下载进度? - "invalidState": 0, // 未知 - "fileUuid": string, // 可以用于下载链接? - "fileSubId": "", - "fileBizId": null, - "originVideoMd5": "", - "import_rich_media_context": null, - "sourceVideoCodecFormat": 0 + "videoMd5"?: string, + "thumbMd5"?: string + "fileTime"?: number, // second + "thumbSize"?: number, // byte + "fileFormat"?: number, // 2表示mp4? + "fileSize"?: string, // byte + "thumbWidth"?: number, + "thumbHeight"?: number, + "busiType"?: 0, // 未知 + "subBusiType"?: 0, // 未知 + "thumbPath"?: Map, + "transferStatus"?: 0, // 未知 + "progress"?: 0, // 下载进度? + "invalidState"?: 0, // 未知 + "fileUuid"?: string, // 可以用于下载链接? + "fileSubId"?: "", + "fileBizId"?: null, + "originVideoMd5"?: "", + "import_rich_media_context"?: null, + "sourceVideoCodecFormat"?: 0 } export interface TipAioOpGrayTipElement { // 这是什么提示来着? diff --git a/src/onebot11/action/SendMsg.ts b/src/onebot11/action/SendMsg.ts index 4828746..366780b 100644 --- a/src/onebot11/action/SendMsg.ts +++ b/src/onebot11/action/SendMsg.ts @@ -372,7 +372,7 @@ export class SendMsg extends BaseAction { } if (sendMsg.type === OB11MessageDataType.file) { log("发送文件", path, payloadFileName || fileName) - sendElements.push(await SendMsgElementConstructor.file(path, false, payloadFileName || fileName)); + sendElements.push(await SendMsgElementConstructor.file(path, payloadFileName || fileName)); } else if (sendMsg.type === OB11MessageDataType.video) { log("发送视频", path, payloadFileName || fileName) sendElements.push(await SendMsgElementConstructor.video(path, payloadFileName || fileName)); From de6c8a55589d6ebbe698e1b8311ced150750b0f8 Mon Sep 17 00:00:00 2001 From: linyuchen Date: Wed, 13 Mar 2024 04:22:11 +0800 Subject: [PATCH 2/2] feat: send video by videoElement --- src/common/utils.ts | 81 +++++++++++++++++++++- src/ntqqapi/constructor.ts | 110 ++++++++++++++---------------- src/ntqqapi/hook.ts | 1 + src/ntqqapi/types.ts | 2 +- src/onebot11/action/BaseAction.ts | 4 +- src/onebot11/action/SendMsg.ts | 5 -- 6 files changed, 135 insertions(+), 68 deletions(-) diff --git a/src/common/utils.ts b/src/common/utils.ts index c6a1c75..9268cf2 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -4,6 +4,7 @@ import {ConfigUtil} from "./config"; import util from "util"; import {encode, getDuration, isWav} from "silk-wasm"; import fs from 'fs'; +import * as crypto from 'crypto'; import {v4 as uuidv4} from "uuid"; import ffmpeg from "fluent-ffmpeg" @@ -234,9 +235,9 @@ export async function encodeSilk(filePath: string) { } else { const pcm = fs.readFileSync(filePath); let duration = 0; - try{ + try { duration = getDuration(pcm); - }catch (e) { + } catch (e) { log("获取语音文件时长失败", filePath, e.stack) duration = fs.statSync(filePath).size / 1024 / 3 // 每3kb大约1s duration = Math.floor(duration) @@ -256,6 +257,80 @@ export async function encodeSilk(filePath: string) { } } +export async function getVideoInfo(filePath: string) { + const size = fs.statSync(filePath).size; + return new Promise<{ width: number, height: number, time: number, format: string, size: number, filePath: string }>((resolve, reject) => { + ffmpeg.ffprobe(filePath, (err, metadata) => { + if (err) { + reject(err); + } else { + const videoStream = metadata.streams.find(s => s.codec_type === 'video'); + if (videoStream) { + console.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`); + } else { + console.log('未找到视频流信息。'); + } + resolve({ + width: videoStream.width, height: videoStream.height, + time: parseInt(videoStream.duration), + format: metadata.format.format_name, + size, + filePath + }); + } + }); + }) +} + +export async function encodeMp4(filePath: string) { + let videoInfo = await getVideoInfo(filePath); + log("视频信息", videoInfo) + if (videoInfo.format.indexOf("mp4") === -1) { + log("视频需要转换为MP4格式", filePath) + // 转成mp4 + const newPath: string = await new Promise((resolve, reject) => { + const newPath = filePath + ".mp4" + ffmpeg(filePath) + .toFormat('mp4') + .on('error', (err) => { + reject(`转换视频格式失败: ${err.message}`); + }) + .on('end', () => { + log('视频转换为MP4格式完成'); + resolve(newPath); // 返回转换后的文件路径 + }) + .save(newPath); + }); + return await getVideoInfo(newPath) + } + return videoInfo +} + export function isNull(value: any) { return value === undefined || value === null; -} \ No newline at end of file +} + + +export function calculateFileMD5(filePath: string): Promise { + return new Promise((resolve, reject) => { + // 创建一个流式读取器 + const stream = fs.createReadStream(filePath); + const hash = crypto.createHash('md5'); + + stream.on('data', (data: Buffer) => { + // 当读取到数据时,更新哈希对象的状态 + hash.update(data); + }); + + stream.on('end', () => { + // 文件读取完成,计算哈希 + const md5 = hash.digest('hex'); + resolve(md5); + }); + + stream.on('error', (err: Error) => { + // 处理可能的读取错误 + reject(err); + }); + }); +} diff --git a/src/ntqqapi/constructor.ts b/src/ntqqapi/constructor.ts index eb52616..28ce031 100644 --- a/src/ntqqapi/constructor.ts +++ b/src/ntqqapi/constructor.ts @@ -12,8 +12,9 @@ import { SendVideoElement } from "./types"; import {NTQQApi} from "./ntcall"; -import {encodeSilk, isGIF, log} from "../common/utils"; -import * as fs from "node:fs"; +import {calculateFileMD5, encodeSilk, getVideoInfo, isGIF, log, sleep} from "../common/utils"; +import {promises as fs} from "node:fs"; +import ffmpeg from "fluent-ffmpeg" export class SendMsgElementConstructor { @@ -88,8 +89,6 @@ export class SendMsgElementConstructor { } static async file(filePath: string, fileName: string = ""): Promise { - let picHeight = 0; - let picWidth = 0; const {md5, fileName: _fileName, path, fileSize} = await NTQQApi.uploadFile(filePath, ElementType.FILE); if (fileSize === 0) { throw "文件异常,大小为0"; @@ -108,13 +107,44 @@ export class SendMsgElementConstructor { } static async video(filePath: string, fileName: string = ""): Promise { - const {md5, fileName: _fileName, path, fileSize} = await NTQQApi.uploadFile(filePath, ElementType.VIDEO); + let {fileName: _fileName, path, fileSize, md5} = await NTQQApi.uploadFile(filePath, ElementType.VIDEO); if (fileSize === 0) { throw "文件异常,大小为0"; } - log("上传视频", md5, path, fileSize, fileName || _fileName) + // const videoInfo = await encodeMp4(path); + // path = videoInfo.filePath + // md5 = videoInfo.md5; + // fileSize = videoInfo.size; + // log("上传视频", md5, path, fileSize, fileName || _fileName) + const pathLib = require("path"); + let thumb = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`) + thumb = pathLib.dirname(thumb) + // log("thumb 目录", thumb) + const videoInfo = await getVideoInfo(path); + // log("视频信息", videoInfo) + const createThumb = new Promise((resolve, reject) => { + const thumbFileName = `${md5}_0.png` + ffmpeg(filePath) + .on("end", () => { + }) + .on("error", (err) => { + reject(err); + }) + .screenshots({ + timestamps: [0], + filename: thumbFileName, + folder: thumb, + size: videoInfo.width + "x" + videoInfo.height + }).on("end", () => { + resolve(pathLib.join(thumb, thumbFileName)); + }); + }) let thumbPath = new Map() - thumbPath.set(0, "E:\\SystemDocuments\\QQ\\721011692\\nt_qq\\nt_data\\Video\\2024-03\\Thumb\\8950eb327e26c01e69d4a0fab7e2b159_0.png") + const _thumbPath = await createThumb; + const thumbSize = (await fs.stat(_thumbPath)).size; + // log("生成缩略图", _thumbPath) + thumbPath.set(0, _thumbPath) + const thumbMd5 = await calculateFileMD5(_thumbPath); let element: SendVideoElement = { elementType: ElementType.VIDEO, elementId: "", @@ -122,59 +152,26 @@ export class SendMsgElementConstructor { fileName: fileName || _fileName, filePath: path, videoMd5: md5, - "thumbMd5": "9eee9e9a07b193cbaf4846522b0197b4", - fileTime: 15, + thumbMd5, + fileTime: videoInfo.time, thumbPath: thumbPath, - "thumbSize": 368286, - "fileFormat": 2, - "thumbWidth": 540, - "thumbHeight": 960, - // "busiType": 0, - // "subBusiType": 0, - // fileUuid: md5, + thumbSize, + thumbWidth: videoInfo.width, + thumbHeight: videoInfo.height, fileSize: "" + fileSize, - "transferStatus": 0, - "progress": 0, - "invalidState": 0, - // "fileUuid": "3051020100043630340201000204169df3d602037a1afd020440f165b4020465f02cb304108950eb327e26c01e69d4a0fab7e2b15802037a1db902010004140000000866696c65747970650000000431303031", - "fileSubId": "", - "fileBizId": null, - "originVideoMd5": "", - "import_rich_media_context": null, - "sourceVideoCodecFormat": 0 + // fileUuid: "", + // transferStatus: 0, + // progress: 0, + // invalidState: 0, + // fileSubId: "", + // fileBizId: null, + // originVideoMd5: "", + // fileFormat: 2, + // import_rich_media_context: null, + // sourceVideoCodecFormat: 2 } } return element; - log("video element", element) - let e = { - "elementType": 5, - "elementId": "", - "videoElement": { - "filePath": "E:\\SystemDocuments\\QQ\\721011692\\nt_qq\\nt_data\\Video\\2024-03\\Ori\\8950eb327e26c01e69d4a0fab7e2b158.mp4", - "fileName": "8950eb327e26c01e69d4a0fab7e2b158.mp4", - "videoMd5": "8950eb327e26c01e69d4a0fab7e2b158", - "thumbMd5": "9eee9e9a07b193cbaf4846522b0197b4", - "fileTime": 15, - "thumbSize": 368286, - "fileFormat": 2, - "fileSize": "2084867", - "thumbWidth": 540, - "thumbHeight": 960, - "busiType": 0, - "subBusiType": 0, - "thumbPath": thumbPath, - "transferStatus": 0, - "progress": 0, - "invalidState": 0, - "fileUuid": "3051020100043630340201000204169df3d602037a1afd020440f165b4020465f02cb304108950eb327e26c01e69d4a0fab7e2b15802037a1db902010004140000000866696c65747970650000000431303031", - "fileSubId": "", - "fileBizId": null, - "originVideoMd5": "", - "import_rich_media_context": null, - "sourceVideoCodecFormat": 0 - } - } - return e as SendVideoElement } static async ptt(pttPath: string): Promise { @@ -185,8 +182,7 @@ export class SendMsgElementConstructor { throw "文件异常,大小为0"; } if (converted) { - fs.unlink(silkPath, () => { - }); + fs.unlink(silkPath).then(); } return { elementType: ElementType.PTT, diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index ee2cc57..ec5738f 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -28,6 +28,7 @@ export enum ReceiveCmd { FRIEND_REQUEST = "nodeIKernelBuddyListener/onBuddyReqChange", SELF_STATUS = 'nodeIKernelProfileListener/onSelfStatusChanged', CACHE_SCAN_FINISH = "nodeIKernelStorageCleanListener/onFinishScan", + MEDIA_UPLOAD_COMPLETE = "nodeIKernelMsgListener/onRichMediaUploadComplete", } interface NTQQApiReturnData extends Array { diff --git a/src/ntqqapi/types.ts b/src/ntqqapi/types.ts index e7aea8a..6b5e46f 100644 --- a/src/ntqqapi/types.ts +++ b/src/ntqqapi/types.ts @@ -283,7 +283,7 @@ export interface VideoElement { "fileBizId"?: null, "originVideoMd5"?: "", "import_rich_media_context"?: null, - "sourceVideoCodecFormat"?: 0 + "sourceVideoCodecFormat"?: number } export interface TipAioOpGrayTipElement { // 这是什么提示来着? diff --git a/src/onebot11/action/BaseAction.ts b/src/onebot11/action/BaseAction.ts index 09b3752..05ab409 100644 --- a/src/onebot11/action/BaseAction.ts +++ b/src/onebot11/action/BaseAction.ts @@ -22,7 +22,7 @@ class BaseAction { return OB11Response.ok(resData); } catch (e) { log("发生错误", e) - return OB11Response.error(e.toString(), 200); + return OB11Response.error(e?.toString() || e?.stack?.toString() || "未知错误,可能操作超时", 200); } } @@ -36,7 +36,7 @@ class BaseAction { return OB11Response.ok(resData, echo); } catch (e) { log("发生错误", e) - return OB11Response.error(e.toString(), 1200, echo) + return OB11Response.error(e.stack?.toString() || e.toString(), 1200, echo) } } diff --git a/src/onebot11/action/SendMsg.ts b/src/onebot11/action/SendMsg.ts index 366780b..d58f0ac 100644 --- a/src/onebot11/action/SendMsg.ts +++ b/src/onebot11/action/SendMsg.ts @@ -157,14 +157,9 @@ export class SendMsg extends BaseAction { } // log("send msg:", peer, sendElements) const {sendElements, deleteAfterSentFiles} = await this.createSendElements(messages, group) - try { const returnMsg = await this.send(peer, sendElements, deleteAfterSentFiles) deleteAfterSentFiles.map(f => fs.unlink(f, () => {})); return {message_id: returnMsg.msgShortId} - } catch (e) { - log("发送消息失败", e.stack.toString()) - throw (e.toString()) - } } protected convertMessage2List(message: OB11MessageMixType) {