diff --git a/apps/tools.js b/apps/tools.js index 9f7d1c5..e707a25 100644 --- a/apps/tools.js +++ b/apps/tools.js @@ -83,7 +83,14 @@ import { truncateString, urlTransformShortLink } from "../utils/common.js"; -import { checkAndRemoveFile, deleteFolderRecursive, getMediaFilesAndOthers, mkdirIfNotExists } from "../utils/file.js"; +import { extractKeyframes } from "../utils/ffmpeg-util.js"; +import { + checkAndRemoveFile, + deleteFolderRecursive, + getMediaFilesAndOthers, + mkdirIfNotExists, + readCurrentDir +} from "../utils/file.js"; import GeneralLinkAdapter from "../utils/general-link-adapter.js"; import { LagrangeAdapter } from "../utils/lagrange-adapter.js"; import { contentEstimator } from "../utils/link-share-summary-util.js"; @@ -2459,6 +2466,21 @@ export class tools extends plugin { await uploadTDL(path, this.isOverseasServer(), this.proxyAddr); e.reply("✈️ 已发送一份到您的小飞机收藏夹了!"); }) + } else if (e.msg.startsWith("预览视频")) { + // 预览视频逻辑 + const keyframesPath = this.getCurDownloadPath(e) + "keyframes"; + await mkdirIfNotExists(keyframesPath); + await extractKeyframes(path, keyframesPath); + const keyframes = await readCurrentDir(keyframesPath); + // logger.info(keyframes); + e.reply(Bot.makeForwardMsg(keyframes.map(keyframe => { + return { + message: segment.image(keyframesPath + "/" + keyframe), + nickname: e.sender.card || e.user_id, + user_id: e.user_id, + }; + }))) + return; } // 正常发送视频 if (videoSize > videoSizeLimit) { diff --git a/utils/ffmpeg-util.js b/utils/ffmpeg-util.js new file mode 100644 index 0000000..180cba4 --- /dev/null +++ b/utils/ffmpeg-util.js @@ -0,0 +1,23 @@ +import path from 'path'; +import { exec } from 'child_process'; + +// 写一个执行ffmpeg提取视频关键帧的函数,例如:ffmpeg -i input.mp4 -vf "select=eq(pict_type\,I)" -vsync drop -vframes 5 -qscale:v 2 keyframes\keyframe_%03d.jpg +export async function extractKeyframes(inputFilePath, outputFolderPath, frameCount = 20) { + return new Promise((resolve, reject) => { + // 创建输出文件夹路径 + const outputFilePattern = path.join(outputFolderPath, 'keyframe_%03d.jpg'); + + // 构建FFmpeg命令 + const ffmpegCommand = `ffmpeg -i "${inputFilePath}" -vf "select=eq(pict_type\\,I)" -vsync drop -vframes ${frameCount} -qscale:v 2 "${outputFilePattern}"`; + + // 执行FFmpeg命令 + exec(ffmpegCommand, (error, stdout, stderr) => { + if (error) { + reject(`[R插件][ffmpeg工具]执行FFmpeg命令时出错: ${ stderr }`); + } else { + logger.info(`[R插件][ffmpeg工具]关键帧成功提取到 ${ outputFolderPath }`); + resolve(outputFolderPath); + } + }); + }); +}