(sourceDir: string, zipPath: string)
| 576 | private async convertMp4ToGif(mp4Path: string, gifPath: string): Promise<void> { |
| 577 | await execFileAsync('ffmpeg', [ |
| 578 | '-i', mp4Path, |
| 579 | '-vf', 'fps=15,scale=512:512:force_original_aspect_ratio=decrease,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=white@0', |
| 580 | gifPath |
| 581 | ]); |
| 582 | } |
| 583 | |
| 584 | private async createZipFile(sourceDir: string, zipPath: string): Promise<void> { |
| 585 | return new Promise((resolve, reject) => { |
| 586 | // 检查源目录是否存在 |
| 587 | if (!fs.existsSync(sourceDir)) { |
| 588 | reject(new Error(`源目录不存在: ${sourceDir}`)); |
| 589 | return; |
| 590 | } |
| 591 | |
| 592 | // 确保目标目录存在 |
| 593 | const zipDir = path.dirname(zipPath); |
| 594 | if (!fs.existsSync(zipDir)) { |
| 595 | fs.mkdirSync(zipDir, { recursive: true }); |
| 596 | } |
| 597 | |
| 598 | // 创建输出流 |
| 599 | const output = fs.createWriteStream(zipPath); |
| 600 | const archive = new ZipArchive( { |
| 601 | zlib: { level: 9 } // 最高压缩级别 |
| 602 | }); |
| 603 | |
| 604 | // 监听错误事件 |
| 605 | output.on('error', (err: Error) => { |
| 606 | console.error('输出流错误:', err); |
| 607 | reject(err); |
| 608 | }); |
| 609 | |
| 610 | archive.on('error', (err: Error) => { |
| 611 | console.error('Archive错误:', err); |
| 612 | reject(err); |
| 613 | }); |
| 614 | |
| 615 | // 监听完成事件 |
| 616 | output.on('close', () => { |
| 617 | console.log(`ZIP文件创建完成,总大小: ${archive.pointer()} 字节`); |
| 618 | |
| 619 | // 验证文件是否正确创建 |
| 620 | if (fs.existsSync(zipPath)) { |
| 621 | const stats = fs.statSync(zipPath); |
| 622 | if (stats.size > 0) { |
| 623 | console.log('ZIP文件验证成功'); |
| 624 | resolve(); |
| 625 | } else { |
| 626 | reject(new Error('ZIP文件为空')); |
| 627 | } |
| 628 | } else { |
| 629 | reject(new Error('ZIP文件创建失败')); |
| 630 | } |
| 631 | }); |
| 632 | |
| 633 | // 连接输出流 |
| 634 | archive.pipe(output); |
| 635 |
no test coverage detected