diff --git a/icon.jpg b/icon.jpg new file mode 100644 index 0000000..67ca0da Binary files /dev/null and b/icon.jpg differ 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));