2032
This commit is contained in:
1 parent
22b52aaf4a
commit
7d187acc65
3 files changed
+55
-19
No files matched your search
Vendored
+1
-1
@@ -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.
|
||||
@@ -201,9 +201,7 @@ handlers.help = async (chatId) => {
|
||||
`├─ 🎙️ 语音消息:自动转文字 + 生成语音播放器`,
|
||||
`├─ 🎵 MP3 文件:交互式问答生成音乐卡片`,
|
||||
`├─ 📷 普通图片:直接插入文章`,
|
||||
`├─ 📷 HEIC 图片(iOS 实况照片):`,
|
||||
`│ └─ 动态效果无法自动提取`,
|
||||
`│ └─ 需先转为 GIF/视频再发送`,
|
||||
`├─ 📷 Live Photo(iOS HEIC):自动转换为视频 + 生成 livephoto 播放器`,
|
||||
`├─ 🎬 视频/GIF:直接插入文章`,
|
||||
`└─ 📄 文档:保存到文章目录`,
|
||||
].join("\n"));
|
||||
|
||||
@@ -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\n`);
|
||||
|
||||
// 只对 HEIC 文件(iOS 实况照片)显示提示
|
||||
// HEIC 文件(iOS Live Photo)自动转换
|
||||
const isHEIC = ext.toLowerCase() === "heic" || ext.toLowerCase() === "heif";
|
||||
if (isHEIC) {
|
||||
await sendMessage(chatId, `📷 图片已保存:${filename}
|
||||
await sendMessage(chatId, "🎞️ 检测到 Live Photo,正在转换为视频...");
|
||||
|
||||
💡 <b>检测到 iOS 实况照片(HEIC 格式)</b>
|
||||
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\n`);
|
||||
await sendMessage(chatId, `📷 图片已保存:${filename}
|
||||
|
||||
⚠️ <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\n`);
|
||||
await sendMessage(chatId, `📷 图片已保存:${filename}`);
|
||||
|
||||
} catch (e) {
|
||||
console.error("[bot:photo]", e instanceof Error ? e.message : String(e));
|
||||
await sendMessage(chatId, "❌ 图片保存失败");
|
||||
|
||||
Reference in new issue
Block a user