This commit is contained in:
Vaica committed 2026-06-24 20:33:02 +08:00
1 parent 22b52aaf4a
commit 7d187acc65
3 files changed
+54 -18

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";
import "./.next/dev/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
+1 -3
View File
@@ -201,9 +201,7 @@ handlers.help = async (chatId) => {
`├─ 🎙️ 语音消息:自动转文字 + 生成语音播放器`,
`├─ 🎵 MP3 文件:交互式问答生成音乐卡片`,
`├─ 📷 普通图片:直接插入文章`,
`├─ 📷 HEIC 图片(iOS 实况照片):`,
`│ └─ 动态效果无法自动提取`,
`│ └─ 需先转为 GIF/视频再发送`,
`├─ 📷 Live Photo(iOS HEIC):自动转换为视频 + 生成 livephoto 播放器`,
`├─ 🎬 视频/GIF:直接插入文章`,
`└─ 📄 文档:保存到文章目录`,
].join("\n"));
+52 -14
View File
@@ -502,13 +502,14 @@ async function handleAudioEnhanced(chatId: number, fileId: string, fileName?: st
}
// ============================================================
// 新增:处理图片(增强版:支持封面图上传 + 实况照片引导)
// 新增:处理图片(增强版:支持封面图上传 + Live Photo 自动转换)
// ============================================================
async function handlePhotoEnhanced(chatId: number, photos: { file_id: string }[], caption?: string) {
try {
const fs = await import("fs");
const path = await import("path");
const { execSync } = await import("child_process");
const { getSession } = await import("./sessions");
const s = getSession(chatId);
@@ -536,27 +537,64 @@ async function handlePhotoEnhanced(chatId: number, photos: { file_id: string }[]
if (!fs.existsSync(articleDir)) fs.mkdirSync(articleDir, { recursive: true });
const ext = filePath.split(".").pop() || "jpg";
const filename = Date.now() + "-" + largestPhoto.file_id.slice(0, 8) + "." + ext;
fs.writeFileSync(path.join(articleDir, filename), Buffer.from(imgBuffer));
const baseFilename = Date.now() + "-" + largestPhoto.file_id.slice(0, 8);
const filename = baseFilename + "." + ext;
const fullPath = path.join(articleDir, filename);
fs.writeFileSync(fullPath, Buffer.from(imgBuffer));
const imgCaption = caption || "image";
appendContent(chatId, `\n![${imgCaption}](${filename})\n`);
// 只对 HEIC 文件(iOS 实况照片)显示提示
// HEIC 文件(iOS Live Photo)自动转换
const isHEIC = ext.toLowerCase() === "heic" || ext.toLowerCase() === "heif";
if (isHEIC) {
await sendMessage(chatId, "🎞️ 检测到 Live Photo,正在转换为视频...");
try {
// 转换 HEIC 为 MP4 视频
const videoFilename = baseFilename + ".mp4";
const videoPath = path.join(articleDir, videoFilename);
// 使用 ffmpeg 转换 HEIC 为 MP4(保持原有帧率和质量)
execSync(`ffmpeg -y -i "${fullPath}" -c:v libx264 -crf 23 -preset medium -pix_fmt yuv420p "${videoPath}"`, { timeout: 60000 });
// 提取第一帧作为封面图
const coverFilename = baseFilename + "-cover.jpg";
const coverPath = path.join(articleDir, coverFilename);
execSync(`ffmpeg -y -i "${videoPath}" -vframes 1 -q:v 2 "${coverPath}"`, { timeout: 30000 });
// 删除原始 HEIC 文件
fs.unlinkSync(fullPath);
// 生成 livephoto 短代码
const livePhotoShortcode = `\n\n{{< livephoto src="${videoFilename}" cover="${coverFilename}" >}}\n\n`;
appendContent(chatId, livePhotoShortcode);
await sendMessage(chatId, `✅ <b>Live Photo 转换完成!</b>
📹 视频:${videoFilename}
🖼️ 封面:${coverFilename}
已插入 livephoto 短代码,支持点击播放动态效果。`, { parse_mode: "HTML" });
return;
} catch (convertError) {
console.error("[bot:heic-convert]", convertError instanceof Error ? convertError.message : String(convertError));
// 转换失败,回退到普通图片处理
appendContent(chatId, `\n![Live Photo](${filename})\n`);
await sendMessage(chatId, `📷 图片已保存:${filename}
💡 <b>检测到 iOS 实况照片(HEIC 格式)</b>
⚠️ <b>Live Photo 转换失败</b>
动态效果无法自动提取。如需保留动态效果,请:
动态效果无法提取,已作为普通图片插入。如需动态效果,请:
1. 在 iPhone 上使用「快捷指令」将实况照片转为 GIF
2. 或使用第三方 App 导出为视频后重新发送
继续发送其他内容...</b>`, { parse_mode: "HTML" });
} else {
await sendMessage(chatId, `📷 图片已保存:${filename}`);
2. 或使用第三方 App 导出为视频后重新发送`, { parse_mode: "HTML" });
return;
}
}
// 普通图片处理
const imgCaption = caption || "image";
appendContent(chatId, `\n![${imgCaption}](${filename})\n`);
await sendMessage(chatId, `📷 图片已保存:${filename}`);
} catch (e) {
console.error("[bot:photo]", e instanceof Error ? e.message : String(e));
await sendMessage(chatId, "❌ 图片保存失败");