@t3lnet/sceneforge 1.0.10 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -53,7 +53,9 @@ async function addAudioToStep(videoPath, audioPath, outputPath, padding, nextVid
53
53
  "-c:v",
54
54
  "libx264",
55
55
  "-preset",
56
- "fast",
56
+ "medium",
57
+ "-crf",
58
+ "18",
57
59
  "-c:a",
58
60
  "aac",
59
61
  "-b:a",
@@ -90,7 +92,9 @@ async function addAudioToStep(videoPath, audioPath, outputPath, padding, nextVid
90
92
  "-c:v",
91
93
  "libx264",
92
94
  "-preset",
93
- "fast",
95
+ "medium",
96
+ "-crf",
97
+ "18",
94
98
  "-c:a",
95
99
  "aac",
96
100
  "-b:a",
@@ -117,7 +121,9 @@ async function addAudioToStep(videoPath, audioPath, outputPath, padding, nextVid
117
121
  "-c:v",
118
122
  "libx264",
119
123
  "-preset",
120
- "fast",
124
+ "medium",
125
+ "-crf",
126
+ "18",
121
127
  "-c:a",
122
128
  "aac",
123
129
  "-b:a",
@@ -96,7 +96,9 @@ async function buildConcatWithIntroOutro(stepFiles, demoDir, introPath, outroPat
96
96
  "-c:v",
97
97
  "libx264",
98
98
  "-preset",
99
- "fast",
99
+ "medium",
100
+ "-crf",
101
+ "18",
100
102
  "-c:a",
101
103
  "aac",
102
104
  "-b:a",
@@ -315,7 +317,9 @@ async function concatDemo(demoName, paths, options = {}) {
315
317
  "-c:v",
316
318
  "libx264",
317
319
  "-preset",
318
- "fast",
320
+ "medium",
321
+ "-crf",
322
+ "18",
319
323
  "-c:a",
320
324
  "aac",
321
325
  "-b:a",
@@ -287,7 +287,7 @@ ${colors.blue}══════════════════════
287
287
 
288
288
  // Show what files will be created
289
289
  const { deployContext, getToolConfig, getSupportedTools } = await import(
290
- "../../context/index.js"
290
+ "../../dist/index.js"
291
291
  );
292
292
 
293
293
  const tools = target === "all" ? getSupportedTools() : [target];
@@ -395,7 +395,7 @@ async function runDeployCommand(args) {
395
395
 
396
396
  // Dynamic import of context module
397
397
  const { deployContext, isValidTool, isValidFormat, getSupportedTools } = await import(
398
- "../../context/index.js"
398
+ "../../dist/index.js"
399
399
  );
400
400
 
401
401
  // Validate target
@@ -487,7 +487,7 @@ async function runListCommand(args) {
487
487
 
488
488
  const outputDir = resolveRoot(output);
489
489
 
490
- const { listDeployedContext } = await import("../../context/index.js");
490
+ const { listDeployedContext } = await import("../../dist/index.js");
491
491
 
492
492
  try {
493
493
  const { files } = await listDeployedContext(outputDir);
@@ -532,7 +532,7 @@ async function runRemoveCommand(args) {
532
532
  const outputDir = resolveRoot(output);
533
533
 
534
534
  const { removeContext, isValidTool, getSupportedTools } = await import(
535
- "../../context/index.js"
535
+ "../../dist/index.js"
536
536
  );
537
537
 
538
538
  // Validate target
@@ -596,7 +596,7 @@ async function runPreviewCommand(args) {
596
596
  }
597
597
 
598
598
  const { previewContext, isValidTool, getSupportedTools } = await import(
599
- "../../context/index.js"
599
+ "../../dist/index.js"
600
600
  );
601
601
 
602
602
  // Validate target
@@ -640,7 +640,7 @@ async function runSkillCommand(args) {
640
640
  const copy = getFlagValue(args, "--copy");
641
641
  const output = getFlagValue(args, "--output");
642
642
 
643
- const { listSkills, getSkill } = await import("../../context/index.js");
643
+ const { listSkills, getSkill } = await import("../../dist/index.js");
644
644
 
645
645
  if (list) {
646
646
  try {
@@ -127,7 +127,9 @@ async function splitDemo(demoName, paths) {
127
127
  "-c:v",
128
128
  "libx264",
129
129
  "-preset",
130
- "fast",
130
+ "medium",
131
+ "-crf",
132
+ "18",
131
133
  "-an",
132
134
  outputPath,
133
135
  ]);
@@ -104,6 +104,8 @@ sceneforge split --demo <name> [options]
104
104
  | `--demo` | Demo name (folder in output) |
105
105
  | `--output`, `-o` | Output directory |
106
106
 
107
+ **Video Quality:** Encodes with H.264 (libx264), CRF 18, medium preset for high-quality output.
108
+
107
109
  ### voiceover
108
110
  Generate voiceover audio from scripts.
109
111
 
@@ -136,6 +138,8 @@ sceneforge add-audio --demo <name> [options]
136
138
  | `--demo` | Demo name |
137
139
  | `--output`, `-o` | Output directory |
138
140
 
141
+ **Video Quality:** Re-encodes with H.264 (libx264), CRF 18, medium preset. Audio encoded as AAC at 192kbps.
142
+
139
143
  ### concat
140
144
  Concatenate step clips into final video.
141
145
 
@@ -149,6 +153,8 @@ sceneforge concat --demo <name> [options]
149
153
  | `--demo` | Demo name |
150
154
  | `--output`, `-o` | Output directory |
151
155
 
156
+ **Video Quality:** Final encode with H.264 (libx264), CRF 18, medium preset. Includes `+faststart` for web streaming optimization. Audio encoded as AAC at 192kbps.
157
+
152
158
  ### doctor
153
159
  Run environment diagnostics.
154
160
 
@@ -234,3 +240,27 @@ sceneforge doctor
234
240
  # Record in headed mode with slow motion
235
241
  sceneforge record -d demo.yaml -b http://localhost:3000 --headed --slowmo 500
236
242
  ```
243
+
244
+ ## Video Quality
245
+
246
+ SceneForge uses high-quality FFmpeg encoding settings optimized for multi-pass video processing:
247
+
248
+ | Setting | Value | Purpose |
249
+ |---------|-------|---------|
250
+ | Codec | `libx264` | H.264 for broad compatibility |
251
+ | Preset | `medium` | Balanced quality/speed tradeoff |
252
+ | CRF | `18` | High quality (visually lossless) |
253
+ | Audio | `aac @ 192k` | High-quality audio |
254
+ | Flags | `+faststart` | Web streaming optimization |
255
+
256
+ **Why these settings:**
257
+ - Videos go through multiple processing stages (split → add-audio → concat)
258
+ - Each re-encoding can degrade quality (generation loss)
259
+ - CRF 18 preserves quality across all stages
260
+ - Medium preset provides good compression without sacrificing quality
261
+
262
+ **CRF Reference:**
263
+ - 0 = Lossless (huge files)
264
+ - 18 = Visually lossless (SceneForge default)
265
+ - 23 = FFmpeg default
266
+ - 28+ = Lower quality, smaller files
@@ -217,6 +217,26 @@ Aim for variance within ±500ms per step:
217
217
  - [ ] Volume consistent across steps
218
218
  - [ ] No unexpected pauses
219
219
 
220
+ ### Video Quality Check
221
+ SceneForge uses high-quality encoding settings to preserve video fidelity:
222
+ - [ ] Video appears sharp (no compression artifacts)
223
+ - [ ] Colors are accurate (no banding)
224
+ - [ ] Text is readable (no blur from compression)
225
+ - [ ] No visible quality degradation between steps
226
+
227
+ **Encoding Settings Used:**
228
+ | Setting | Value | Purpose |
229
+ |---------|-------|---------|
230
+ | Codec | `libx264` | H.264 for compatibility |
231
+ | CRF | `18` | High quality (visually lossless) |
232
+ | Preset | `medium` | Balanced quality/speed |
233
+ | Audio | `aac @ 192k` | High-quality audio |
234
+
235
+ **If you notice quality issues:**
236
+ 1. Ensure source recording is high quality (check `output/videos/<demo>.webm`)
237
+ 2. Re-run the pipeline to regenerate all clips
238
+ 3. Check available disk space (low space can affect encoding)
239
+
220
240
  ## Final Checklist
221
241
 
222
242
  - [ ] All steps have acceptable timing variance
@@ -225,4 +245,6 @@ Aim for variance within ±500ms per step:
225
245
  - [ ] No dead air or overlap issues
226
246
  - [ ] Intro provides adequate context
227
247
  - [ ] Outro concludes naturally
248
+ - [ ] Video quality is sharp and clear
249
+ - [ ] Audio is clear with consistent volume
228
250
  - [ ] Overall demo flows professionally
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t3lnet/sceneforge",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "SceneForge runner and generation utilities for YAML-driven demos",
5
5
  "license": "MIT",
6
6
  "author": "T3LNET",