feat:添加预览视频指令,视频关键帧提取功能

- 此提交引入了一项新功能,允许使用FFmpeg从视频中提取关键帧。
- `extractKeyframes` 函数已被添加到 `ffmpeg-util.js` 以处理提取过程。
- `tools.js` 文件已更新以包含新功能,使用户能够预览视频的关键帧。
- `readCurrentDir` 函数已从 `file.js` 导入,以读取关键帧目录的内容。
This commit is contained in:
zhiyu1998 2024-09-02 22:36:45 +08:00
parent 5205f76c48
commit a38ef04d27
2 changed files with 46 additions and 1 deletions

View File

@ -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) {

23
utils/ffmpeg-util.js Normal file
View File

@ -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);
}
});
});
}