diff --git a/src/encoding/convertWithFfmpeg.ts b/src/encoding/convertWithFfmpeg.ts new file mode 100644 index 0000000..d01e066 --- /dev/null +++ b/src/encoding/convertWithFfmpeg.ts @@ -0,0 +1,10 @@ +import ffmpeg from 'fluent-ffmpeg'; + +export default function (sourcePath: string, targetPath: string, format: string){ + return new Promise(resolve => { + ffmpeg(sourcePath).toFormat(format).save(targetPath) + .on('end', () => { + resolve(); + }) + }) +} diff --git a/src/encoding/silk.ts b/src/encoding/silk.ts index b750d70..eb5c36e 100644 --- a/src/encoding/silk.ts +++ b/src/encoding/silk.ts @@ -48,5 +48,6 @@ export default { const { path, cleanup } = await file(); await fsP.writeFile(path, bufPcm); await conventPcmToOgg(path, outputPath); + cleanup(); }, }; diff --git a/src/services/ForwardService.ts b/src/services/ForwardService.ts index a639686..1017f67 100644 --- a/src/services/ForwardService.ts +++ b/src/services/ForwardService.ts @@ -22,6 +22,7 @@ import { md5Hex } from '../utils/hashing'; import Instance from '../models/Instance'; import { Pair } from '../models/Pair'; import sharp from 'sharp'; +import convertWithFfmpeg from '../encoding/convertWithFfmpeg'; const NOT_CHAINABLE_ELEMENTS = ['flash', 'record', 'video', 'location', 'share', 'json', 'xml', 'poke']; @@ -253,7 +254,7 @@ export default class ForwardService { } chain.push({ type: 'image', - file: '/' + convertedPath, + file: convertedPath, asface: true, }); } @@ -271,6 +272,23 @@ export default class ForwardService { if (file.size > 20 * 1024 * 1024) { chain.push('[视频大于 20MB]'); } + else if (file.mimeType === 'video/webm') { + // 把 webm 转换成 gif + const convertedPath = path.resolve(path.join('./data/cache/webm', message.document.id.toString(16) + '.gif')); + // 先从缓存中找 + if (!fs.existsSync(convertedPath)) { + await fsP.mkdir('./data/cache/webm', { recursive: true }); + const temp = await createTempFile(); + tempFiles.push(temp); + await fsP.writeFile(temp.path, await message.downloadMedia({})); + await convertWithFfmpeg(temp.path, convertedPath, 'gif'); + } + chain.push({ + type: 'image', + file: convertedPath, + asface: true, + }); + } else { const temp = await createTempFile(); tempFiles.push(temp); @@ -384,13 +402,13 @@ export default class ForwardService { const notChainableElements = chain.filter(element => typeof element === 'object' && NOT_CHAINABLE_ELEMENTS.includes(element.type)); const chainableElements = chain.filter(element => typeof element !== 'object' || !NOT_CHAINABLE_ELEMENTS.includes(element.type)); const qqMessages = []; - if (chainableElements) { + if (chainableElements.length) { qqMessages.push({ ...await pair.qq.sendMsg(chainableElements, source), brief, }); } - if (notChainableElements) { + if (notChainableElements.length) { qqMessages.push({ ...await pair.qq.sendMsg(notChainableElements, source), brief,