Added utility scripts for GIF management: 1. regenerate-all-gifs.ts: - Regenerates GIF previews for all existing videos - Deletes old GIFs before creating new ones - Provides progress feedback and summary statistics - Useful for bulk GIF generation after deployment 2. check-gifs.ts: - Quick diagnostic to list all GIF records in database - Shows term names and GIF URLs - Useful for verifying GIF generation 3. insert-gif-test.ts: - Test script to verify GIF enum value works in database - Creates, verifies, and cleans up test GIF record - Includes Prisma query logging for debugging Usage: cd packages/backend npx tsx scripts/regenerate-all-gifs.ts npx tsx scripts/check-gifs.ts npx tsx scripts/insert-gif-test.ts Co-Authored-By: Auggie
105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
import { PrismaClient, MediaKind } from '@prisma/client';
|
|
import { generateGifFromVideo } from '../src/utils/gifGenerator.js';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function regenerateAllGifs() {
|
|
console.log('🎬 Starting GIF regeneration for all videos...\n');
|
|
|
|
try {
|
|
// Get all video media
|
|
const videoMedia = await prisma.termMedia.findMany({
|
|
where: { kind: MediaKind.VIDEO },
|
|
include: { term: true },
|
|
});
|
|
|
|
console.log(`Found ${videoMedia.length} videos to process\n`);
|
|
|
|
let successCount = 0;
|
|
let failCount = 0;
|
|
|
|
for (const media of videoMedia) {
|
|
const videoFilename = path.basename(media.url);
|
|
const videoPath = path.join(__dirname, '..', 'uploads', 'videos', videoFilename);
|
|
|
|
// Check if video file exists
|
|
if (!fs.existsSync(videoPath)) {
|
|
console.log(`❌ Video file not found: ${videoFilename}`);
|
|
failCount++;
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
// Generate GIF filename
|
|
const gifFilename = videoFilename.replace(/\.(mp4|webm|mov)$/i, '.gif');
|
|
const gifsDir = path.join(__dirname, '..', 'uploads', 'gifs');
|
|
const gifPath = path.join(gifsDir, gifFilename);
|
|
const gifRelativeUrl = `/uploads/gifs/${gifFilename}`;
|
|
|
|
// Ensure gifs directory exists
|
|
if (!fs.existsSync(gifsDir)) {
|
|
fs.mkdirSync(gifsDir, { recursive: true });
|
|
}
|
|
|
|
// Delete old GIF if exists
|
|
const existingGif = await prisma.termMedia.findFirst({
|
|
where: {
|
|
termId: media.termId,
|
|
kind: MediaKind.GIF,
|
|
url: gifRelativeUrl,
|
|
},
|
|
});
|
|
|
|
if (existingGif) {
|
|
await prisma.termMedia.delete({ where: { id: existingGif.id } });
|
|
if (fs.existsSync(gifPath)) {
|
|
fs.unlinkSync(gifPath);
|
|
}
|
|
}
|
|
|
|
// Generate GIF
|
|
console.log(`🎨 Generating GIF for: ${media.term.wordText} (${videoFilename})`);
|
|
await generateGifFromVideo(videoPath, gifPath, {
|
|
fps: 10,
|
|
width: 300,
|
|
duration: 3,
|
|
startTime: 0,
|
|
});
|
|
|
|
// Create GIF media record
|
|
await prisma.termMedia.create({
|
|
data: {
|
|
termId: media.termId,
|
|
kind: MediaKind.GIF,
|
|
url: gifRelativeUrl,
|
|
},
|
|
});
|
|
|
|
console.log(`✅ Success: ${media.term.wordText}\n`);
|
|
successCount++;
|
|
} catch (error: any) {
|
|
console.log(`❌ Failed: ${media.term.wordText} - ${error.message}\n`);
|
|
failCount++;
|
|
}
|
|
}
|
|
|
|
console.log('\n📊 Summary:');
|
|
console.log(`✅ Success: ${successCount}`);
|
|
console.log(`❌ Failed: ${failCount}`);
|
|
console.log(`📝 Total: ${videoMedia.length}`);
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
} finally {
|
|
await prisma.$disconnect();
|
|
}
|
|
}
|
|
|
|
regenerateAllGifs();
|
|
|