Download scripts/video-engine/audit-chapters.js from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 4.32 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/scripts/video-engine/audit-chapters.js
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/scripts/video-engine/audit-chapters.js
-
curl -L -o audit-chapters.js https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/scripts/video-engine/audit-chapters.js
4.32 kB
| // 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}`); | |