File size: 4,321 Bytes
65d68f5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | // Quick audit script to inspect all lesson packages
const fs = require("fs");
const path = require("path");
// Generated packages
const genDir = path.join(__dirname, "../../data/teaching/social-science/generated");
const histDir = path.join(__dirname, "../../data/teaching/history");
function auditPackage(filePath) {
const d = JSON.parse(fs.readFileSync(filePath, "utf8"));
const visualKinds = {};
d.scenes.forEach(s => {
visualKinds[s.visual.kind] = (visualKinds[s.visual.kind] || 0) + 1;
});
const sections = [...new Set(d.scenes.map(s => s.section))];
const hasImages = d.scenes.filter(s => s.visual.image).length;
const totalWords = d.scenes.reduce((sum, s) => sum + s.narration.split(/\s+/).length, 0);
return {
file: path.basename(filePath),
chapterId: d.chapterId,
subject: d.subject,
discipline: d.discipline || "unknown",
chapterTitle: d.chapterTitle,
chapterNumber: d.chapterNumber,
bookPart: d.bookPart,
targetDuration: d.targetDurationMinutes,
teachingMode: d.teachingMode,
sceneCount: d.scenes.length,
totalWords,
sections,
visualKinds,
scenesWithImages: hasImages,
sourceEdition: d.sourceEdition,
};
}
console.log("=== GENERATED PACKAGES ===");
const genFiles = fs.readdirSync(genDir).filter(f => f.endsWith(".json")).sort();
genFiles.forEach(f => {
const info = auditPackage(path.join(genDir, f));
console.log(`\n--- ${info.chapterId} ---`);
console.log(` Title: ${info.chapterTitle}`);
console.log(` Discipline: ${info.discipline} | Book: ${info.bookPart} | Ch#: ${info.chapterNumber}`);
console.log(` Scenes: ${info.sceneCount} | Words: ${info.totalWords} | Images: ${info.scenesWithImages}`);
console.log(` Target: ${info.targetDuration}min | Mode: ${info.teachingMode}`);
console.log(` Visual kinds:`, JSON.stringify(info.visualKinds));
console.log(` Sections: [${info.sections.join(", ")}]`);
});
console.log("\n\n=== HISTORY PACKAGES ===");
const histFiles = fs.readdirSync(histDir).filter(f => f.endsWith(".json")).sort();
histFiles.forEach(f => {
const info = auditPackage(path.join(histDir, f));
console.log(`\n--- ${info.chapterId} ---`);
console.log(` Title: ${info.chapterTitle}`);
console.log(` Discipline: ${info.discipline} | Book: ${info.bookPart} | Ch#: ${info.chapterNumber}`);
console.log(` Scenes: ${info.sceneCount} | Words: ${info.totalWords} | Images: ${info.scenesWithImages}`);
console.log(` Target: ${info.targetDuration}min | Mode: ${info.teachingMode}`);
console.log(` Visual kinds:`, JSON.stringify(info.visualKinds));
console.log(` Sections: [${info.sections.join(", ")}]`);
});
// Check existing 1080p outputs
console.log("\n\n=== EXISTING 1080p MP4 OUTPUTS ===");
const outputRoot = path.join(__dirname, "../../outputs/video/social-science");
function findMp4s(dir) {
if (!fs.existsSync(dir)) return [];
const results = [];
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) results.push(...findMp4s(full));
else if (entry.name.endsWith("-1080p.mp4")) results.push(full);
}
return results;
}
const mp4s = findMp4s(outputRoot);
mp4s.forEach(f => {
const stat = fs.statSync(f);
console.log(` ${path.relative(outputRoot, f)} (${(stat.size / 1024 / 1024).toFixed(1)} MB)`);
});
console.log(`\nTotal 1080p MP4s found: ${mp4s.length}`);
// Check existing audio manifests
console.log("\n\n=== EXISTING AUDIO MANIFESTS ===");
function findManifests(dir) {
if (!fs.existsSync(dir)) return [];
const results = [];
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) results.push(...findManifests(full));
else if (entry.name === "manifest.json" && full.includes("kokoro")) results.push(full);
}
return results;
}
const manifests = findManifests(outputRoot);
manifests.forEach(f => {
try {
const m = JSON.parse(fs.readFileSync(f, "utf8"));
console.log(` ${path.relative(outputRoot, f)} (${m.sceneCount} scenes, ${(m.totalDurationSeconds / 60).toFixed(1)}min, voice: ${m.voice})`);
} catch { console.log(` ${path.relative(outputRoot, f)} (parse error)`); }
});
console.log(`\nTotal audio manifests: ${manifests.length}`);
|