@gentbajko/slopify 3.25.9 → 4.1.0
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.
- package/dist/adapters/account-limits.js +30 -0
- package/dist/adapters/alignment/audio.js +1 -1
- package/dist/adapters/alignment/cache.js +4 -6
- package/dist/adapters/alignment/ctc.js +1 -2
- package/dist/adapters/alignment/lock.js +4 -3
- package/dist/adapters/alignment/multilingual.js +2 -4
- package/dist/adapters/alignment/prefetch.js +2 -1
- package/dist/adapters/alignment/runner.js +1 -1
- package/dist/adapters/alignment/worker.js +3 -2
- package/dist/adapters/explain.js +10 -12
- package/dist/adapters/ffmpeg.js +19 -1
- package/dist/adapters/host-cli/index.js +21 -4
- package/dist/adapters/host-cli/transport.js +2 -1
- package/dist/adapters/http-failure.js +53 -0
- package/dist/adapters/image/bytes.js +2 -1
- package/dist/adapters/image/codex.js +42 -9
- package/dist/adapters/image/fal.js +21 -53
- package/dist/adapters/image/google.js +33 -56
- package/dist/adapters/image/models.js +2 -2
- package/dist/adapters/image/openai.js +22 -48
- package/dist/adapters/image/reference.js +36 -0
- package/dist/adapters/image/replicate.js +21 -49
- package/dist/adapters/image/video.js +2 -1
- package/dist/adapters/interest/search-interest.js +113 -0
- package/dist/adapters/key-probes.js +54 -3
- package/dist/adapters/llm/antigravity-models.js +1 -1
- package/dist/adapters/llm/antigravity.js +11 -6
- package/dist/adapters/llm/assistant-cli.js +388 -0
- package/dist/adapters/llm/child-session.js +83 -0
- package/dist/adapters/llm/claude-code-models.js +52 -99
- package/dist/adapters/llm/claude-code.js +16 -4
- package/dist/adapters/llm/codex-limits.js +27 -68
- package/dist/adapters/llm/codex-models.js +1 -1
- package/dist/adapters/llm/codex-server-models.js +61 -109
- package/dist/adapters/llm/codex.js +12 -1
- package/dist/adapters/llm/document-workspace.js +3 -2
- package/dist/adapters/llm/image-workspace.js +3 -2
- package/dist/adapters/llm/openrouter.js +12 -48
- package/dist/adapters/llm/run-cli.js +9 -24
- package/dist/adapters/llm/sse-lines.js +5 -1
- package/dist/adapters/model-access.js +37 -0
- package/dist/adapters/tts/cartesia.js +15 -46
- package/dist/adapters/tts/elevenlabs.js +20 -52
- package/dist/adapters/tts/gemini.js +21 -41
- package/dist/adapters/tts/inworld-async.js +6 -2
- package/dist/adapters/tts/inworld.js +6 -2
- package/dist/adapters/tts/openai.js +20 -50
- package/dist/adapters/tts/system.js +2 -1
- package/dist/assets/models-lifecycle.yaml +6 -0
- package/dist/assistant-wiring.js +60 -0
- package/dist/autopilot-timers.js +59 -0
- package/dist/catalog/lifecycle.js +52 -0
- package/dist/catalog/propose.js +204 -0
- package/dist/catalog/registry.js +23 -14
- package/dist/catalog/schema.js +4 -1
- package/dist/catalog/store.js +39 -0
- package/dist/catalog/validate.js +5 -2
- package/dist/edge/autostart/native.js +3 -5
- package/dist/edge/autostart/prompt.js +2 -1
- package/dist/edge/autostart/service.js +3 -4
- package/dist/edge/cli-args.js +3 -4
- package/dist/edge/cli.js +2 -1
- package/dist/edge/docker-install/apply.js +11 -11
- package/dist/edge/docker-install/run.js +2 -1
- package/dist/edge/docker-install/state.js +4 -3
- package/dist/edge/docker-install/tree.js +2 -4
- package/dist/edge/docker-install/volume.js +3 -2
- package/dist/edge/docker.js +5 -4
- package/dist/edge/events/hub.js +5 -5
- package/dist/edge/http/actions.js +11 -32
- package/dist/edge/http/actor.js +5 -3
- package/dist/edge/http/app.js +86 -11
- package/dist/edge/http/assistant.js +129 -0
- package/dist/edge/http/audio-preview.js +4 -11
- package/dist/edge/http/auditions.js +1 -1
- package/dist/edge/http/autostart.js +5 -5
- package/dist/edge/http/backups.js +2 -4
- package/dist/edge/http/channel-memory.js +9 -22
- package/dist/edge/http/channels.js +14 -27
- package/dist/edge/http/checkpoints.js +39 -21
- package/dist/edge/http/design-templates.js +167 -0
- package/dist/edge/http/designs.js +178 -0
- package/dist/edge/http/diagnostics.js +5 -1
- package/dist/edge/http/document-themes.js +5 -14
- package/dist/edge/http/draft-files.js +1 -3
- package/dist/edge/http/draft-problem.js +5 -10
- package/dist/edge/http/drafts.js +3 -3
- package/dist/edge/http/entries.js +6 -9
- package/dist/edge/http/extension-auth.js +27 -0
- package/dist/edge/http/external-reviews.js +12 -11
- package/dist/edge/http/files.js +5 -11
- package/dist/edge/http/folder-location.js +1 -4
- package/dist/edge/http/fonts.js +0 -7
- package/dist/edge/http/home.js +47 -14
- package/dist/edge/http/host-cli.js +18 -8
- package/dist/edge/http/ids.js +8 -0
- package/dist/edge/http/keywords.js +35 -0
- package/dist/edge/http/model-checks.js +132 -0
- package/dist/edge/http/narration-peaks.js +5 -13
- package/dist/edge/http/onboarding.js +30 -26
- package/dist/edge/http/open-folder.js +5 -10
- package/dist/edge/http/outputs.js +7 -14
- package/dist/edge/http/patch-notes.js +6 -12
- package/dist/edge/http/planning.js +3 -7
- package/dist/edge/http/problem.js +2 -4
- package/dist/edge/http/project-create.js +2 -1
- package/dist/edge/http/project-templates.js +31 -19
- package/dist/edge/http/projects.js +24 -16
- package/dist/edge/http/prompts.js +9 -16
- package/dist/edge/http/pronunciations.js +1 -2
- package/dist/edge/http/providers.js +48 -34
- package/dist/edge/http/refusal.js +29 -0
- package/dist/edge/http/remote-access.js +40 -0
- package/dist/edge/http/remote-guard.js +71 -0
- package/dist/edge/http/request-guard.js +91 -0
- package/dist/edge/http/reviews.js +12 -25
- package/dist/edge/http/revision-files.js +6 -11
- package/dist/edge/http/revisions.js +14 -19
- package/dist/edge/http/run-cost.js +1 -2
- package/dist/edge/http/same-page.js +80 -0
- package/dist/edge/http/schedules.js +69 -40
- package/dist/edge/http/settings.js +27 -14
- package/dist/edge/http/social.js +283 -0
- package/dist/edge/http/staging.js +3 -5
- package/dist/edge/http/storage-files.js +5 -7
- package/dist/edge/http/storage.js +33 -25
- package/dist/edge/http/studio.js +94 -69
- package/dist/edge/http/style-preview.js +3 -6
- package/dist/edge/http/subtitles.js +3 -17
- package/dist/edge/http/template-studio.js +436 -0
- package/dist/edge/http/trash.js +11 -12
- package/dist/edge/http/tutorial.js +1 -2
- package/dist/edge/http/tutorials.js +5 -11
- package/dist/edge/http/update.js +7 -13
- package/dist/edge/http/waveform.js +3 -6
- package/dist/edge/http/youtube-edits.js +3 -4
- package/dist/edge/mcp/assistant.js +279 -0
- package/dist/edge/mcp/attribution.js +8 -2
- package/dist/edge/mcp/call-route.js +11 -2
- package/dist/edge/mcp/excluded-routes.js +29 -3
- package/dist/edge/mcp/http.js +11 -2
- package/dist/edge/mcp/instructions.js +6 -4
- package/dist/edge/mcp/library-tools.js +9 -5
- package/dist/edge/mcp/remake-tools.js +7 -4
- package/dist/edge/mcp/route-tool.js +35 -15
- package/dist/edge/mcp/server.js +13 -8
- package/dist/edge/mcp/tools-channels.js +11 -9
- package/dist/edge/mcp/tools-designs.js +165 -0
- package/dist/edge/mcp/tools-library.js +19 -7
- package/dist/edge/mcp/tools-planning.js +40 -21
- package/dist/edge/mcp/tools-projects.js +38 -11
- package/dist/edge/mcp/tools-publishing.js +9 -9
- package/dist/edge/mcp/tools-runs.js +23 -10
- package/dist/edge/mcp/tools-schedules.js +32 -8
- package/dist/edge/mcp/tools-setup.js +75 -11
- package/dist/edge/mcp/tools-social.js +47 -0
- package/dist/edge/mcp/tools-storage.js +11 -3
- package/dist/edge/mcp/tools-template-studio.js +166 -0
- package/dist/edge/mcp/tools.js +6 -0
- package/dist/edge/remote-access/cli.js +71 -0
- package/dist/edge/remote-access/model.js +32 -0
- package/dist/edge/remote-access/rules.js +207 -0
- package/dist/edge/remote-access/service.js +203 -0
- package/dist/edge/remote-access/store.js +44 -0
- package/dist/edge/remote-access/views.js +43 -0
- package/dist/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/host-cli/install.js +2 -2
- package/dist/host-cli/open-folder.js +2 -2
- package/dist/host-cli/paths.js +2 -4
- package/dist/host-cli/server.js +4 -4
- package/dist/host-cli/service.js +3 -3
- package/dist/host-cli/status.js +7 -7
- package/dist/kernel/db/migrations/0063-model-checks.sql +20 -0
- package/dist/kernel/db/migrations/0064-template-studio.sql +46 -0
- package/dist/kernel/db/migrations/0065-promise-and-assistant-reviews.sql +58 -0
- package/dist/kernel/db/migrations/0066-assistant.sql +44 -0
- package/dist/kernel/db/migrations/0067-autopilot.sql +6 -0
- package/dist/kernel/db/migrations/0068-topic-scores.sql +17 -0
- package/dist/kernel/db/migrations/0070-designs.sql +53 -0
- package/dist/kernel/db/migrations/0071-design-usage.sql +33 -0
- package/dist/kernel/db/migrations/0072-design-templates.sql +33 -0
- package/dist/kernel/db/migrations/0073-schedule-design-kind.sql +5 -0
- package/dist/kernel/db/migrations/0074-template-bakeoffs.sql +44 -0
- package/dist/kernel/db/migrations/0075-social-posts.sql +25 -0
- package/dist/kernel/db/migrations/0076-channel-social.sql +5 -0
- package/dist/kernel/db/migrations/0077-post-prompts.sql +17 -0
- package/dist/kernel/db/migrations/0078-uploaded-from-links.sql +7 -0
- package/dist/kernel/db/tx.js +2 -4
- package/dist/kernel/errors.js +27 -1
- package/dist/kernel/json-answer.js +15 -0
- package/dist/kernel/lock.js +4 -9
- package/dist/kernel/paths.js +8 -0
- package/dist/kernel/pipeline.js +12 -0
- package/dist/kernel/ports/assistant-cli.js +4 -0
- package/dist/kernel/ports/host-cli.js +3 -0
- package/dist/kernel/ports/interest.js +4 -0
- package/dist/kernel/ports/languages.js +0 -3
- package/dist/kernel/ports/model.js +2 -0
- package/dist/kernel/ports/settings-places.js +31 -0
- package/dist/kernel/ports/system-speech.js +31 -3
- package/dist/kernel/runner/attempt.js +14 -4
- package/dist/kernel/runner/audition.js +3 -1
- package/dist/kernel/runner/checkpoint-authority.js +2 -1
- package/dist/kernel/runner/index.js +8 -10
- package/dist/kernel/runner/model-access.js +40 -0
- package/dist/kernel/runner/model-check.js +153 -0
- package/dist/kernel/runner/providers.js +18 -12
- package/dist/kernel/runner/standalone.js +11 -7
- package/dist/main.js +338 -21
- package/dist/model-catalog.js +20 -0
- package/dist/model-checks.js +166 -0
- package/dist/patch-notes/4.0.0.md +51 -0
- package/dist/patch-notes/4.1.0.md +42 -0
- package/dist/patch-notes/index.json +12 -0
- package/dist/slices/admission/heads.js +2 -1
- package/dist/slices/admission/listing-facts.js +95 -0
- package/dist/slices/admission/repo.js +11 -7
- package/dist/slices/admission/rules.js +50 -15
- package/dist/slices/admission/schema.js +8 -0
- package/dist/slices/admission/stage-writes.js +0 -3
- package/dist/slices/admission/start.js +48 -31
- package/dist/slices/admission/state-words.js +34 -5
- package/dist/slices/admission/substitute.js +7 -4
- package/dist/slices/agents/attention-posts.js +31 -0
- package/dist/slices/agents/attention-templates.js +33 -0
- package/dist/slices/agents/attention.js +10 -1
- package/dist/slices/agents/connection.js +2 -6
- package/dist/slices/agents/model.js +6 -3
- package/dist/slices/agents/repo.js +15 -7
- package/dist/slices/article/continuation.js +0 -63
- package/dist/slices/article/plain.js +3 -2
- package/dist/slices/article/segments.js +2 -62
- package/dist/slices/assistant/access.js +1 -0
- package/dist/slices/assistant/asks.js +80 -0
- package/dist/slices/assistant/cost.js +54 -0
- package/dist/slices/assistant/gate.js +222 -0
- package/dist/slices/assistant/model.js +86 -0
- package/dist/slices/assistant/names.js +23 -0
- package/dist/slices/assistant/prompt.js +74 -0
- package/dist/slices/assistant/repo.js +74 -0
- package/dist/slices/assistant/tokens.js +18 -0
- package/dist/slices/assistant/turn.js +344 -0
- package/dist/slices/autopilot/buffer.js +76 -0
- package/dist/slices/autopilot/model.js +14 -0
- package/dist/slices/autopilot/notify.js +27 -0
- package/dist/slices/autopilot/repo.js +34 -0
- package/dist/slices/autopilot/signals.js +194 -0
- package/dist/slices/autopilot/warnings.js +85 -0
- package/dist/slices/autopilot/weekly.js +100 -0
- package/dist/slices/backups/files.js +2 -6
- package/dist/slices/backups/repo.js +3 -15
- package/dist/slices/backups/service.js +8 -7
- package/dist/slices/channels/cast-images.js +3 -2
- package/dist/slices/channels/model.js +0 -1
- package/dist/slices/channels/rebrand.js +0 -3
- package/dist/slices/channels/repo.js +4 -0
- package/dist/slices/channels/schema.js +7 -1
- package/dist/slices/channels/service.js +10 -0
- package/dist/slices/channels/videos.js +3 -15
- package/dist/slices/checkpoints/index.js +0 -1
- package/dist/slices/control/providers.js +2 -28
- package/dist/slices/designs/artwork.js +66 -0
- package/dist/slices/designs/budget.js +23 -0
- package/dist/slices/designs/calls.js +124 -0
- package/dist/slices/designs/check-context.js +38 -0
- package/dist/slices/designs/check-text.js +43 -0
- package/dist/slices/designs/fields.js +88 -0
- package/dist/slices/designs/frames.js +34 -0
- package/dist/slices/designs/gate.js +130 -0
- package/dist/slices/designs/layout.js +293 -0
- package/dist/slices/designs/model.js +35 -0
- package/dist/slices/designs/pdf-job.js +23 -0
- package/dist/slices/designs/pdf-pages.js +30 -0
- package/dist/slices/designs/pdf-runner.js +68 -0
- package/dist/slices/designs/pdf-worker.js +24 -0
- package/dist/slices/designs/picture-size.js +79 -0
- package/dist/slices/designs/pictures.js +55 -0
- package/dist/slices/designs/quote.js +24 -0
- package/dist/slices/designs/render-args.js +36 -0
- package/dist/slices/designs/render-input.js +59 -0
- package/dist/slices/designs/render.js +215 -0
- package/dist/slices/designs/repo.js +101 -0
- package/dist/slices/designs/requests.js +80 -0
- package/dist/slices/designs/runner.js +239 -0
- package/dist/slices/designs/sample-repo.js +91 -0
- package/dist/slices/designs/sample.js +223 -0
- package/dist/slices/designs/schema.js +87 -0
- package/dist/slices/designs/sections.js +44 -0
- package/dist/slices/designs/service.js +233 -0
- package/dist/slices/designs/steps-repo.js +102 -0
- package/dist/slices/designs/studio-kind.js +39 -0
- package/dist/slices/designs/template-checks.js +44 -0
- package/dist/slices/designs/template-make.js +118 -0
- package/dist/slices/designs/templates.js +218 -0
- package/dist/slices/document/fonts.js +2 -1
- package/dist/slices/document/model.js +7 -4
- package/dist/slices/document/render.js +2 -1
- package/dist/slices/document/theme-schema.js +1 -1
- package/dist/slices/document/theme.js +49 -3
- package/dist/slices/episodes/summarize.js +6 -2
- package/dist/slices/estimate/index.js +72 -28
- package/dist/slices/estimate/requests.js +4 -4
- package/dist/slices/fixes/rules.js +3 -1
- package/dist/slices/fonts/catalog.js +5 -3
- package/dist/slices/fonts/coverage.js +2 -1
- package/dist/slices/fonts/discovery.js +3 -2
- package/dist/slices/fonts/files.js +2 -6
- package/dist/slices/fonts/index.js +0 -1
- package/dist/slices/fonts/sfnt.js +45 -10
- package/dist/slices/images/appearance.js +8 -16
- package/dist/slices/images/scenes.js +102 -28
- package/dist/slices/keywords/digest.js +85 -0
- package/dist/slices/keywords/facts.js +92 -0
- package/dist/slices/keywords/fill.js +80 -0
- package/dist/slices/keywords/model.js +75 -0
- package/dist/slices/keywords/rules.js +187 -0
- package/dist/slices/keywords/schema.js +28 -0
- package/dist/slices/keywords/specs.js +260 -0
- package/dist/slices/keywords/values.js +74 -0
- package/dist/slices/library/lint.js +29 -12
- package/dist/slices/library/model.js +2 -0
- package/dist/slices/library/photorealistic.js +4 -12
- package/dist/slices/library/rename.js +9 -7
- package/dist/slices/library/save.js +14 -10
- package/dist/slices/library/slots.js +37 -11
- package/dist/slices/library/transfer.js +5 -4
- package/dist/slices/library/used-by.js +25 -10
- package/dist/slices/loudness/loudnorm.js +53 -12
- package/dist/slices/loudness/model.js +3 -2
- package/dist/slices/loudness/sentence-level.js +2 -1
- package/dist/slices/model-checks/cost.js +61 -0
- package/dist/slices/model-checks/listing.js +124 -0
- package/dist/slices/model-checks/model.js +20 -0
- package/dist/slices/model-checks/record.js +32 -0
- package/dist/slices/model-checks/repo.js +120 -0
- package/dist/slices/model-checks/rules.js +125 -0
- package/dist/slices/model-checks/run.js +143 -0
- package/dist/slices/model-checks/service.js +198 -0
- package/dist/slices/model-upkeep/model.js +1 -1
- package/dist/slices/model-upkeep/switch.js +72 -27
- package/dist/slices/model-upkeep/usage.js +39 -13
- package/dist/slices/narration/breaths.js +3 -1
- package/dist/slices/narration/clean-pieces.js +3 -1
- package/dist/slices/narration/concat.js +2 -1
- package/dist/slices/narration/pauses-model.js +3 -2
- package/dist/slices/narration/peaks.js +3 -4
- package/dist/slices/narration/pronunciation-chunks.js +4 -3
- package/dist/slices/narration/pronunciation.js +6 -4
- package/dist/slices/narration/steering.js +4 -3
- package/dist/slices/notifications/notifier.js +4 -3
- package/dist/slices/notifications/rules.js +5 -2
- package/dist/slices/notifications/settings.js +4 -12
- package/dist/slices/notifications/subject.js +4 -3
- package/dist/slices/onboarding/copy.js +21 -3
- package/dist/slices/onboarding/first-run.js +16 -40
- package/dist/slices/onboarding/full-video.js +3 -2
- package/dist/slices/onboarding/install.js +6 -4
- package/dist/slices/onboarding/model.js +26 -37
- package/dist/slices/onboarding/packs.js +22 -22
- package/dist/slices/onboarding/preferred-model.js +14 -0
- package/dist/slices/onboarding/quick-short.js +105 -65
- package/dist/slices/onboarding/sample.js +4 -2
- package/dist/slices/onboarding/state.js +9 -11
- package/dist/slices/onboarding/template.js +8 -6
- package/dist/slices/outputs/add.js +3 -2
- package/dist/slices/outputs/service.js +2 -2
- package/dist/slices/patch-notes/library.js +4 -3
- package/dist/slices/play-drafts/convert.js +4 -0
- package/dist/slices/play-drafts/readiness.js +3 -3
- package/dist/slices/play-drafts/review-inputs.js +9 -3
- package/dist/slices/play-drafts/review.js +5 -4
- package/dist/slices/play-drafts/schema.js +4 -0
- package/dist/slices/play-drafts/service.js +17 -7
- package/dist/slices/project-templates/from-project.js +9 -2
- package/dist/slices/project-templates/next-chapter.js +2 -1
- package/dist/slices/project-templates/provider-defaults.js +22 -0
- package/dist/slices/project-templates/repo.js +6 -1
- package/dist/slices/project-templates/setup-sections.js +26 -0
- package/dist/slices/project-templates/setup.js +14 -1
- package/dist/slices/project-templates/stand-ins.js +22 -0
- package/dist/slices/rebuild/activity.js +2 -0
- package/dist/slices/rebuild/admission-repo.js +3 -2
- package/dist/slices/rebuild/narration-history.js +4 -5
- package/dist/slices/rebuild/narration-retry.js +2 -1
- package/dist/slices/rebuild/preview-details.js +32 -14
- package/dist/slices/rebuild/preview-plan.js +3 -8
- package/dist/slices/rebuild/recipe-build.js +8 -3
- package/dist/slices/rebuild/recipe-describe.js +3 -3
- package/dist/slices/rebuild/recipe-digest.js +58 -0
- package/dist/slices/rebuild/recipe-input-schema.js +10 -0
- package/dist/slices/rebuild/recipe-keywords.js +71 -0
- package/dist/slices/rebuild/recipe-legacy.js +5 -1
- package/dist/slices/rebuild/recipe-model.js +4 -0
- package/dist/slices/rebuild/recipe-narration-text.js +2 -1
- package/dist/slices/rebuild/recipe-preparation.js +4 -4
- package/dist/slices/rebuild/recipe-reference.js +8 -4
- package/dist/slices/rebuild/recipe-reviews.js +27 -7
- package/dist/slices/rebuild/recipe-save.js +8 -5
- package/dist/slices/rebuild/recipe-scenes.js +40 -11
- package/dist/slices/rebuild/recipe-shorts.js +8 -8
- package/dist/slices/rebuild/recipe-social.js +46 -0
- package/dist/slices/rebuild/recipe-text.js +64 -20
- package/dist/slices/rebuild/recipe-validation.js +102 -31
- package/dist/slices/rebuild/recipe-visual.js +55 -16
- package/dist/slices/rebuild/recipe-voices.js +3 -2
- package/dist/slices/rebuild/recipe-work.js +19 -7
- package/dist/slices/rebuild/recipe-youtube.js +4 -3
- package/dist/slices/rebuild/recovery-selection.js +3 -1
- package/dist/slices/rebuild/recovery.js +9 -8
- package/dist/slices/rebuild/remake-outdated.js +5 -5
- package/dist/slices/rebuild/repo.js +4 -3
- package/dist/slices/rebuild/review-promise.js +25 -0
- package/dist/slices/rebuild/review-redo.js +3 -2
- package/dist/slices/rebuild/runtime-admission.js +4 -3
- package/dist/slices/rebuild/runtime-agent-review.js +11 -5
- package/dist/slices/rebuild/runtime-animate.js +10 -9
- package/dist/slices/rebuild/runtime-article.js +7 -5
- package/dist/slices/rebuild/runtime-checkpoints.js +5 -4
- package/dist/slices/rebuild/runtime-document.js +11 -13
- package/dist/slices/rebuild/runtime-export-bed.js +8 -12
- package/dist/slices/rebuild/runtime-export-edit.js +8 -16
- package/dist/slices/rebuild/runtime-export-inputs.js +12 -11
- package/dist/slices/rebuild/runtime-export-short.js +9 -5
- package/dist/slices/rebuild/runtime-export.js +38 -15
- package/dist/slices/rebuild/runtime-figure-card.js +2 -1
- package/dist/slices/rebuild/runtime-image.js +8 -12
- package/dist/slices/rebuild/runtime-instructions.js +2 -0
- package/dist/slices/rebuild/runtime-keywords.js +59 -0
- package/dist/slices/rebuild/runtime-lines.js +2 -11
- package/dist/slices/rebuild/runtime-local.js +17 -22
- package/dist/slices/rebuild/runtime-narration-publication.js +2 -5
- package/dist/slices/rebuild/runtime-narration-reuse.js +9 -13
- package/dist/slices/rebuild/runtime-narration-text.js +13 -17
- package/dist/slices/rebuild/runtime-pictures.js +2 -4
- package/dist/slices/rebuild/runtime-piece-label.js +10 -6
- package/dist/slices/rebuild/runtime-plan.js +31 -5
- package/dist/slices/rebuild/runtime-provider.js +67 -25
- package/dist/slices/rebuild/runtime-publication.js +10 -9
- package/dist/slices/rebuild/runtime-review.js +39 -33
- package/dist/slices/rebuild/runtime-run.js +4 -1
- package/dist/slices/rebuild/runtime-shorts.js +31 -50
- package/dist/slices/rebuild/runtime-store.js +20 -10
- package/dist/slices/rebuild/runtime-subtitles.js +28 -25
- package/dist/slices/rebuild/runtime-voices.js +10 -16
- package/dist/slices/rebuild/runtime-youtube.js +14 -31
- package/dist/slices/rebuild/service-readiness.js +11 -3
- package/dist/slices/rebuild/transition-repo.js +6 -5
- package/dist/slices/rebuild/work-records.js +6 -0
- package/dist/slices/reruns/cascade.js +1 -2
- package/dist/slices/reruns/index.js +6 -9
- package/dist/slices/research/synthesis.js +3 -2
- package/dist/slices/reviews/external-model.js +4 -1
- package/dist/slices/reviews/external-repo.js +2 -1
- package/dist/slices/reviews/external-rows.js +2 -3
- package/dist/slices/reviews/holds.js +5 -4
- package/dist/slices/reviews/model.js +32 -11
- package/dist/slices/reviews/repo.js +2 -1
- package/dist/slices/reviews/rules.js +4 -3
- package/dist/slices/reviews/verdict.js +2 -1
- package/dist/slices/reviews/view.js +5 -2
- package/dist/slices/revisions/downloads.js +4 -5
- package/dist/slices/revisions/image-plan.js +1 -1
- package/dist/slices/revisions/mutation-assets.js +9 -5
- package/dist/slices/revisions/mutation-cues.js +2 -5
- package/dist/slices/revisions/mutations.js +3 -3
- package/dist/slices/revisions/repo.js +3 -1
- package/dist/slices/revisions/schema.js +1 -0
- package/dist/slices/revisions/view.js +20 -0
- package/dist/slices/run-cost/limits.js +5 -2
- package/dist/slices/run-cost/meter.js +12 -5
- package/dist/slices/run-cost/panel.js +8 -74
- package/dist/slices/run-cost/plan-readings.js +127 -0
- package/dist/slices/run-cost/plan-use.js +169 -0
- package/dist/slices/run-cost/pricing.js +3 -3
- package/dist/slices/run-cost/week.js +32 -4
- package/dist/slices/schedules/agenda.js +18 -7
- package/dist/slices/schedules/by-date.js +42 -0
- package/dist/slices/schedules/calendar.js +5 -0
- package/dist/slices/schedules/design-agenda.js +36 -0
- package/dist/slices/schedules/design-check.js +41 -0
- package/dist/slices/schedules/design-run.js +126 -0
- package/dist/slices/schedules/next-run.js +62 -0
- package/dist/slices/schedules/prepare.js +18 -2
- package/dist/slices/schedules/repo.js +30 -21
- package/dist/slices/schedules/rescore.js +35 -0
- package/dist/slices/schedules/scheduler.js +13 -3
- package/dist/slices/schedules/schema.js +57 -3
- package/dist/slices/schedules/score.js +107 -0
- package/dist/slices/schedules/service.js +57 -24
- package/dist/slices/schedules/topic-list.js +15 -0
- package/dist/slices/schedules/topic-scores.js +104 -0
- package/dist/slices/schedules/topics.js +53 -41
- package/dist/slices/settings/cli-paths.js +4 -6
- package/dist/slices/settings/first-run.js +8 -43
- package/dist/slices/settings/health.js +30 -15
- package/dist/slices/settings/key-test.js +1 -1
- package/dist/slices/settings/model-reach.js +3 -17
- package/dist/slices/settings/model.js +14 -2
- package/dist/slices/settings/playback.js +34 -23
- package/dist/slices/settings/probe-read.js +16 -0
- package/dist/slices/settings/repo.js +33 -0
- package/dist/slices/settings/tutorial.js +2 -2
- package/dist/slices/settings/voices.js +4 -12
- package/dist/slices/shorts/keep.js +2 -1
- package/dist/slices/shorts/pick.js +6 -18
- package/dist/slices/shorts/prompts.js +4 -14
- package/dist/slices/shorts/render.js +6 -2
- package/dist/slices/social/channel.js +44 -0
- package/dist/slices/social/defaults.js +17 -0
- package/dist/slices/social/due.js +36 -0
- package/dist/slices/social/extension.js +18 -0
- package/dist/slices/social/fit.js +115 -0
- package/dist/slices/social/limits.js +186 -0
- package/dist/slices/social/links.js +21 -0
- package/dist/slices/social/media.js +132 -0
- package/dist/slices/social/model.js +75 -0
- package/dist/slices/social/notice.js +19 -0
- package/dist/slices/social/pack.js +176 -0
- package/dist/slices/social/post-prompt.js +56 -0
- package/dist/slices/social/queue.js +31 -0
- package/dist/slices/social/repo.js +133 -0
- package/dist/slices/social/reshape.js +97 -0
- package/dist/slices/social/rules.js +5 -0
- package/dist/slices/social/schema.js +70 -0
- package/dist/slices/social/serve.js +51 -0
- package/dist/slices/social/service.js +129 -0
- package/dist/slices/social/settings.js +21 -0
- package/dist/slices/social/sources.js +114 -0
- package/dist/slices/social/state.js +110 -0
- package/dist/slices/social/text.js +149 -0
- package/dist/slices/storage/arrange.js +3 -1
- package/dist/slices/storage/assets.js +8 -10
- package/dist/slices/storage/backup-designs.js +74 -0
- package/dist/slices/storage/backup-export.js +8 -3
- package/dist/slices/storage/backup-format.js +10 -0
- package/dist/slices/storage/backup-import.js +22 -4
- package/dist/slices/storage/delete-project.js +6 -5
- package/dist/slices/storage/files-location.js +6 -8
- package/dist/slices/storage/layout.js +13 -2
- package/dist/slices/storage/model.js +3 -0
- package/dist/slices/storage/portable.js +17 -12
- package/dist/slices/storage/schema.js +2 -0
- package/dist/slices/storage/staging-refs.js +2 -1
- package/dist/slices/storage/staging.js +6 -9
- package/dist/slices/storage/trim.js +26 -9
- package/dist/slices/studio/calendar.js +7 -2
- package/dist/slices/studio/disclosure.js +4 -4
- package/dist/slices/studio/model.js +1 -1
- package/dist/slices/studio/pack.js +9 -8
- package/dist/slices/studio/pick.js +2 -11
- package/dist/slices/studio/plan.js +7 -16
- package/dist/slices/studio/queue.js +3 -14
- package/dist/slices/studio/releases.js +26 -0
- package/dist/slices/studio/settings.js +20 -57
- package/dist/slices/studio/videos.js +35 -4
- package/dist/slices/style-preview/render.js +37 -16
- package/dist/slices/style-preview/schema.js +14 -1
- package/dist/slices/style-preview/service.js +2 -1
- package/dist/slices/style-preview/settings.js +33 -5
- package/dist/slices/subtitles/captions.js +1 -1
- package/dist/slices/telemetry/collector-client.js +2 -4
- package/dist/slices/telemetry/flush.js +2 -4
- package/dist/slices/telemetry/model.js +0 -7
- package/dist/slices/telemetry/record.js +10 -3
- package/dist/slices/template-studio/anatomy-view.js +161 -0
- package/dist/slices/template-studio/anatomy.js +73 -0
- package/dist/slices/template-studio/bakeoff-make.js +225 -0
- package/dist/slices/template-studio/bakeoff-repo.js +83 -0
- package/dist/slices/template-studio/bakeoff.js +333 -0
- package/dist/slices/template-studio/budget.js +106 -0
- package/dist/slices/template-studio/cards.js +78 -0
- package/dist/slices/template-studio/checks.js +322 -0
- package/dist/slices/template-studio/document-sample.js +56 -0
- package/dist/slices/template-studio/edit.js +15 -0
- package/dist/slices/template-studio/for-all.js +161 -0
- package/dist/slices/template-studio/free-video.js +31 -0
- package/dist/slices/template-studio/free.js +176 -0
- package/dist/slices/template-studio/gate.js +40 -0
- package/dist/slices/template-studio/hidden.js +20 -0
- package/dist/slices/template-studio/jobs.js +79 -0
- package/dist/slices/template-studio/loudness.js +111 -0
- package/dist/slices/template-studio/make.js +40 -0
- package/dist/slices/template-studio/model.js +58 -0
- package/dist/slices/template-studio/pack-import.js +253 -0
- package/dist/slices/template-studio/pack-samples.js +60 -0
- package/dist/slices/template-studio/pack.js +207 -0
- package/dist/slices/template-studio/paid-view.js +66 -0
- package/dist/slices/template-studio/paid.js +355 -0
- package/dist/slices/template-studio/quote.js +155 -0
- package/dist/slices/template-studio/ready.js +104 -0
- package/dist/slices/template-studio/repo.js +134 -0
- package/dist/slices/template-studio/reviews-path.js +58 -0
- package/dist/slices/template-studio/runner.js +84 -0
- package/dist/slices/template-studio/save.js +236 -0
- package/dist/slices/template-studio/say-it-as.js +248 -0
- package/dist/slices/template-studio/schedule-gate.js +34 -0
- package/dist/slices/template-studio/schedule-price.js +32 -0
- package/dist/slices/template-studio/schedule-sample.js +91 -0
- package/dist/slices/template-studio/schema.js +243 -0
- package/dist/slices/template-studio/scope.js +124 -0
- package/dist/slices/template-studio/sections.js +176 -0
- package/dist/slices/template-studio/service.js +175 -0
- package/dist/slices/template-studio/status.js +191 -0
- package/dist/slices/template-studio/topic.js +223 -0
- package/dist/slices/thumbnail/by-llm.js +1 -1
- package/dist/slices/trash/designs.js +76 -0
- package/dist/slices/trash/model.js +13 -4
- package/dist/slices/trash/service.js +52 -2
- package/dist/slices/tutorials/library.js +3 -2
- package/dist/slices/uploads/repo.js +37 -1
- package/dist/slices/uploads/rules.js +3 -2
- package/dist/slices/video/ass-text.js +17 -0
- package/dist/slices/video/audio-export.js +2 -64
- package/dist/slices/video/edit-list.js +2 -2
- package/dist/slices/video/edit-settings.js +1 -1
- package/dist/slices/video/encoding.js +169 -0
- package/dist/slices/video/ffmpeg.js +23 -21
- package/dist/slices/video/figure-card.js +1 -15
- package/dist/slices/video/plan.js +2 -1
- package/dist/slices/video/slideshow.js +43 -18
- package/dist/slices/voices/attribution.js +3 -2
- package/dist/slices/voices/model.js +9 -8
- package/dist/slices/voices/palette.js +0 -3
- package/dist/slices/voices/script.js +2 -1
- package/dist/slices/youtube/answer.js +4 -16
- package/dist/slices/youtube/edits-repo.js +3 -12
- package/dist/tutorials/AI-CLIs.md +25 -25
- package/dist/tutorials/Agents-MCP.md +34 -33
- package/dist/tutorials/Assistant.md +42 -0
- package/dist/tutorials/Backups.md +7 -7
- package/dist/tutorials/Calendar.md +17 -25
- package/dist/tutorials/Cast-Library.md +19 -19
- package/dist/tutorials/Channels.md +42 -35
- package/dist/tutorials/Costs-and-Run-Cost.md +38 -40
- package/dist/tutorials/Create-Article.md +114 -0
- package/dist/tutorials/Create-Extras.md +112 -0
- package/dist/tutorials/Create-Images.md +165 -0
- package/dist/tutorials/Create-Narration.md +178 -0
- package/dist/tutorials/Create-Overview.md +244 -0
- package/dist/tutorials/Create-Video-and-Style.md +144 -0
- package/dist/tutorials/Docker.md +3 -3
- package/dist/tutorials/Document-Themes.md +32 -32
- package/dist/tutorials/Editing-a-Project.md +94 -94
- package/dist/tutorials/FAQ.md +18 -18
- package/dist/tutorials/First-Launch-and-Welcome.md +50 -64
- package/dist/tutorials/Home-and-Projects.md +115 -71
- package/dist/tutorials/Home.md +33 -33
- package/dist/tutorials/Install.md +14 -13
- package/dist/tutorials/Intros-and-Outros.md +33 -34
- package/dist/tutorials/Keyboard-Shortcuts-and-Command-Palette.md +62 -58
- package/dist/tutorials/Keywords-Slopify-Fills.md +87 -0
- package/dist/tutorials/Models.md +53 -21
- package/dist/tutorials/Multiple-Voices.md +41 -40
- package/dist/tutorials/Narration-Aliases-and-Glossary.md +14 -14
- package/dist/tutorials/Notifications.md +27 -17
- package/dist/tutorials/Other-Languages.md +15 -15
- package/dist/tutorials/PDF-Documents.md +38 -29
- package/dist/tutorials/Posting-to-Social-Sites.md +121 -0
- package/dist/tutorials/Project-Page.md +118 -120
- package/dist/tutorials/Prompts-and-Templates.md +84 -0
- package/dist/tutorials/Prompts.md +48 -44
- package/dist/tutorials/Providers-and-Keys.md +105 -98
- package/dist/tutorials/Publishing-to-YouTube.md +31 -31
- package/dist/tutorials/Recovery-and-Retries.md +31 -31
- package/dist/tutorials/Remote-Access.md +63 -0
- package/dist/tutorials/Reviews-and-Checkpoints.md +98 -90
- package/dist/tutorials/Schedules.md +46 -27
- package/dist/tutorials/Settings-Reference.md +194 -174
- package/dist/tutorials/Shorts.md +34 -33
- package/dist/tutorials/Start-at-Login.md +3 -3
- package/dist/tutorials/Studio-Extension.md +22 -24
- package/dist/tutorials/Template-Studio.md +128 -0
- package/dist/tutorials/Templates.md +51 -77
- package/dist/tutorials/Trash.md +4 -4
- package/dist/tutorials/Troubleshooting.md +44 -44
- package/dist/tutorials/Uninstalling-and-Moving.md +5 -5
- package/dist/tutorials/Updating-and-Patch-Notes.md +18 -18
- package/dist/tutorials/Video-Editing.md +34 -34
- package/dist/tutorials/Where-Your-Files-Live.md +10 -10
- package/dist/tutorials/YouTube-Description.md +26 -26
- package/dist/tutorials/Your-First-Short.md +35 -35
- package/dist/tutorials/_Sidebar.md +19 -14
- package/dist/updater/work-in-progress.js +42 -12
- package/dist/web/assets/index-BNftKQrA.css +1 -0
- package/dist/web/assets/index-Cpa58woP.js +459 -0
- package/dist/web/assets/pdf-BKh8f7R6.js +56 -0
- package/dist/web/assets/pdf.worker.min-BmVo14Nb.mjs +28 -0
- package/dist/web/assets/pdf.worker.min-D7i8o3wR.js +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +6 -2
- package/dist/slices/article/provided-entries.js +0 -66
- package/dist/slices/article/run.js +0 -145
- package/dist/slices/images/run.js +0 -234
- package/dist/slices/narration/legacy-plan.js +0 -58
- package/dist/slices/narration/run.js +0 -270
- package/dist/slices/rebuild/runtime-actions.js +0 -90
- package/dist/slices/research/run.js +0 -224
- package/dist/slices/subtitles/prepare.js +0 -194
- package/dist/slices/subtitles/transcript.js +0 -34
- package/dist/slices/thumbnail/run.js +0 -219
- package/dist/slices/video/audio-inputs.js +0 -33
- package/dist/slices/video/reuse-audio.js +0 -62
- package/dist/slices/video/run.js +0 -78
- package/dist/slices/video/write-export.js +0 -158
- package/dist/slices/video/write-subtitles.js +0 -59
- package/dist/tutorials/Library-Overview.md +0 -76
- package/dist/tutorials/Play-Images.md +0 -161
- package/dist/tutorials/Play-Narration.md +0 -167
- package/dist/tutorials/Play-Outputs.md +0 -109
- package/dist/tutorials/Play-Overview.md +0 -227
- package/dist/tutorials/Play-Title-and-Article.md +0 -136
- package/dist/tutorials/Play-Video-and-Style.md +0 -143
- package/dist/web/assets/index-BadsoORk.css +0 -1
- package/dist/web/assets/index-D8LqNsCl.js +0 -326
- package/dist/web/assets/pdf-T7MCwjIv.js +0 -54
- package/dist/web/assets/pdf.worker.min-Dswkl-cV.mjs +0 -29
- package/dist/web/assets/pdf.worker.min-zC6nfbxG.js +0 -1
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { copyFileSync, existsSync, mkdirSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
2
|
-
import { dirname } from "node:path";
|
|
3
|
-
import { transact } from "../../kernel/db/tx.js";
|
|
4
|
-
import { setStageProgress } from "../admission/stage-writes.js";
|
|
5
|
-
import { outputPath } from "../storage/layout.js";
|
|
6
|
-
import { deleteOutput, insertOutput, outputsOf } from "../storage/repo.js";
|
|
7
|
-
import { subtitleRoles } from "../subtitles/prepare.js";
|
|
8
|
-
const progressIntervalMs = 500;
|
|
9
|
-
const renderRoles = [
|
|
10
|
-
"video",
|
|
11
|
-
"audio_export",
|
|
12
|
-
"render_params",
|
|
13
|
-
...subtitleRoles,
|
|
14
|
-
];
|
|
15
|
-
// Both local exports retain the previous finished asset until ffmpeg succeeds and
|
|
16
|
-
// the abort check passes. The part file keeps its muxer's filename extension.
|
|
17
|
-
export async function writeExport(deps, context, output) {
|
|
18
|
-
const { projectId } = context.stage;
|
|
19
|
-
const target = outputPath(deps.paths, projectId, output.filename);
|
|
20
|
-
mkdirSync(dirname(target), { recursive: true, mode: 0o700 });
|
|
21
|
-
// The plan is the record of what was rendered and names the file the user downloads,
|
|
22
|
-
// so it keeps the final path; only the ffmpeg invocation is pointed at the part file.
|
|
23
|
-
const part = outputPath(deps.paths, projectId, output.partName);
|
|
24
|
-
const totalMs = Math.round(output.totalSeconds * 1000);
|
|
25
|
-
let announced = 0;
|
|
26
|
-
try {
|
|
27
|
-
// No retry and no timeout. A render that fails is terminal.
|
|
28
|
-
await output.render(part, (elapsedMs) => {
|
|
29
|
-
const at = deps.clock.now().getTime();
|
|
30
|
-
if (at - announced < progressIntervalMs) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
announced = at;
|
|
34
|
-
const current = output.subtitles === undefined
|
|
35
|
-
? Math.min(elapsedMs, totalMs)
|
|
36
|
-
: Math.round((0.35 + 0.65 * Math.min(elapsedMs / totalMs, 1)) * totalMs);
|
|
37
|
-
setStageProgress(deps.db, context.stage.id, current, totalMs);
|
|
38
|
-
context.emit({
|
|
39
|
-
type: "stage.progress",
|
|
40
|
-
projectId,
|
|
41
|
-
stage: "video",
|
|
42
|
-
current,
|
|
43
|
-
total: totalMs,
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
// A cancel protects an output that was already stored, not one about to be. One
|
|
47
|
-
// landing between ffmpeg exiting and the rows below discards the render rather than
|
|
48
|
-
// reporting done to a page that pressed Cancel.
|
|
49
|
-
context.signal.throwIfAborted();
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
// A partial render file is discarded, never kept or served. Only the part file: the
|
|
53
|
-
// previous export is a finished output and stays downloadable.
|
|
54
|
-
rmSync(part, { force: true });
|
|
55
|
-
if (output.subtitles !== undefined)
|
|
56
|
-
rmSync(output.subtitles.directory, { recursive: true, force: true });
|
|
57
|
-
throw error;
|
|
58
|
-
}
|
|
59
|
-
const params = outputPath(deps.paths, projectId, "render.json");
|
|
60
|
-
const previousOutputs = outputsOf(deps.db, projectId);
|
|
61
|
-
const replaced = [];
|
|
62
|
-
const paramsPart = outputPath(deps.paths, projectId, "render.part.json");
|
|
63
|
-
let committed = false;
|
|
64
|
-
try {
|
|
65
|
-
writeFileSync(paramsPart, `${JSON.stringify(output.record, null, 2)}\n`, { mode: 0o600 });
|
|
66
|
-
// The DB commit can fail after ffmpeg succeeds. Keep rollback copies until all
|
|
67
|
-
// media, caption and font rows commit, so a failed export keeps its old playback.
|
|
68
|
-
for (const path of [target, params]) {
|
|
69
|
-
const saved = { path, backup: `${path}.previous`, existed: existsSync(path), swapped: false };
|
|
70
|
-
if (saved.existed)
|
|
71
|
-
copyFileSync(path, saved.backup);
|
|
72
|
-
replaced.push(saved);
|
|
73
|
-
}
|
|
74
|
-
for (const saved of replaced) {
|
|
75
|
-
renameSync(saved.path === target ? part : paramsPart, saved.path);
|
|
76
|
-
saved.swapped = true;
|
|
77
|
-
}
|
|
78
|
-
transact(deps.db, () => {
|
|
79
|
-
for (const previous of previousOutputs) {
|
|
80
|
-
if (renderRoles.includes(previous.role))
|
|
81
|
-
deleteOutput(deps.db, previous.id);
|
|
82
|
-
}
|
|
83
|
-
store(deps, projectId, "render_params", "render.json", null);
|
|
84
|
-
store(deps, projectId, output.role, output.filename, totalMs, {
|
|
85
|
-
...(output.subtitles?.omissions?.length
|
|
86
|
-
? { subtitleOmissions: output.subtitles.omissions }
|
|
87
|
-
: {}),
|
|
88
|
-
subtitlesMode: output.subtitles === undefined ? "off" : output.subtitles.burnIn ? "burn-in" : "files",
|
|
89
|
-
});
|
|
90
|
-
for (const asset of output.subtitles?.assets ?? [])
|
|
91
|
-
store(deps, projectId, asset.role, asset.path, null);
|
|
92
|
-
});
|
|
93
|
-
committed = true;
|
|
94
|
-
}
|
|
95
|
-
catch (error) {
|
|
96
|
-
for (const saved of replaced) {
|
|
97
|
-
if (!saved.swapped)
|
|
98
|
-
continue;
|
|
99
|
-
if (saved.existed)
|
|
100
|
-
renameSync(saved.backup, saved.path);
|
|
101
|
-
else
|
|
102
|
-
rmSync(saved.path, { force: true });
|
|
103
|
-
saved.swapped = false;
|
|
104
|
-
}
|
|
105
|
-
rmSync(part, { force: true });
|
|
106
|
-
rmSync(paramsPart, { force: true });
|
|
107
|
-
if (output.subtitles !== undefined)
|
|
108
|
-
rmSync(output.subtitles.directory, { recursive: true, force: true });
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
111
|
-
finally {
|
|
112
|
-
for (const saved of replaced) {
|
|
113
|
-
if (!committed && saved.swapped)
|
|
114
|
-
continue;
|
|
115
|
-
try {
|
|
116
|
-
rmSync(saved.backup, { force: true });
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
/* A retained backup is collected at the next boot. */
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const kept = new Set(outputsOf(deps.db, projectId).map((one) => one.path));
|
|
124
|
-
for (const previous of previousOutputs) {
|
|
125
|
-
if (renderRoles.includes(previous.role) && !kept.has(previous.path)) {
|
|
126
|
-
try {
|
|
127
|
-
rmSync(outputPath(deps.paths, projectId, previous.path), { force: true });
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
/* Boot reconciliation collects a file that could not be removed. */
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
// Written as well as emitted: a page opened after the render reads the row, and the
|
|
135
|
-
// throttled in-flight writes would have left it frozen short of the end.
|
|
136
|
-
setStageProgress(deps.db, context.stage.id, totalMs, totalMs);
|
|
137
|
-
context.emit({
|
|
138
|
-
type: "stage.progress",
|
|
139
|
-
projectId,
|
|
140
|
-
stage: "video",
|
|
141
|
-
current: totalMs,
|
|
142
|
-
total: totalMs,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
function store(deps, projectId, role, path, durationMs, meta = {}) {
|
|
146
|
-
insertOutput(deps.db, {
|
|
147
|
-
id: deps.ids.next(),
|
|
148
|
-
projectId,
|
|
149
|
-
stageKind: "video",
|
|
150
|
-
role,
|
|
151
|
-
path,
|
|
152
|
-
originalFilename: null,
|
|
153
|
-
bytes: statSync(outputPath(deps.paths, projectId, path)).size,
|
|
154
|
-
durationMs,
|
|
155
|
-
meta,
|
|
156
|
-
createdAt: deps.clock.now().toISOString(),
|
|
157
|
-
});
|
|
158
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { rmSync, statSync } from "node:fs";
|
|
2
|
-
import { transact } from "../../kernel/db/tx.js";
|
|
3
|
-
import { setStageProgress } from "../admission/stage-writes.js";
|
|
4
|
-
import { outputPath } from "../storage/layout.js";
|
|
5
|
-
import { deleteOutput, insertOutput, outputsOf } from "../storage/repo.js";
|
|
6
|
-
import { subtitleRoles } from "../subtitles/prepare.js";
|
|
7
|
-
// Commit sidecars and subtitle metadata without opening, copying or replacing the WAV.
|
|
8
|
-
export function writeSubtitles(deps, context, media, subtitles) {
|
|
9
|
-
const projectId = context.stage.projectId;
|
|
10
|
-
const previous = outputsOf(deps.db, projectId).filter((output) => subtitleRoles.some((role) => role === output.role));
|
|
11
|
-
const { subtitleOmissions: _oldOmissions, subtitlesMode: _oldMode, ...keptMeta } = media.meta;
|
|
12
|
-
const meta = {
|
|
13
|
-
...keptMeta,
|
|
14
|
-
subtitlesMode: subtitles === undefined ? "off" : "files",
|
|
15
|
-
...(subtitles?.omissions?.length ? { subtitleOmissions: subtitles.omissions } : {}),
|
|
16
|
-
};
|
|
17
|
-
try {
|
|
18
|
-
context.emit({ type: "stage.progress", projectId, stage: "video", current: 99, total: 100 });
|
|
19
|
-
context.signal.throwIfAborted();
|
|
20
|
-
transact(deps.db, () => {
|
|
21
|
-
for (const output of previous)
|
|
22
|
-
deleteOutput(deps.db, output.id);
|
|
23
|
-
deps.db
|
|
24
|
-
.prepare("UPDATE outputs SET meta = ? WHERE id = ?")
|
|
25
|
-
.run(JSON.stringify(meta), media.id);
|
|
26
|
-
for (const asset of subtitles?.assets ?? [])
|
|
27
|
-
insertOutput(deps.db, {
|
|
28
|
-
id: deps.ids.next(),
|
|
29
|
-
projectId,
|
|
30
|
-
stageKind: "video",
|
|
31
|
-
role: asset.role,
|
|
32
|
-
path: asset.path,
|
|
33
|
-
originalFilename: null,
|
|
34
|
-
bytes: statSync(outputPath(deps.paths, projectId, asset.path)).size,
|
|
35
|
-
durationMs: null,
|
|
36
|
-
meta: {},
|
|
37
|
-
createdAt: deps.clock.now().toISOString(),
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
if (subtitles !== undefined)
|
|
43
|
-
rmSync(subtitles.directory, { recursive: true, force: true });
|
|
44
|
-
throw error;
|
|
45
|
-
}
|
|
46
|
-
const kept = new Set((subtitles?.assets ?? []).map((asset) => asset.path));
|
|
47
|
-
for (const output of previous) {
|
|
48
|
-
if (kept.has(output.path))
|
|
49
|
-
continue;
|
|
50
|
-
try {
|
|
51
|
-
rmSync(outputPath(deps.paths, projectId, output.path), { force: true });
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
/* Boot reconciliation collects obsolete files still held by a player. */
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
setStageProgress(deps.db, context.stage.id, 100, 100);
|
|
58
|
-
context.emit({ type: "stage.progress", projectId, stage: "video", current: 100, total: 100 });
|
|
59
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# Library Overview
|
|
2
|
-
|
|
3
|
-
The Library holds the reusable pieces your videos are made from: prompts, intros and outros, templates, PDF document themes and narration aliases. Write a piece once and pick it on Play for every video that needs it.
|
|
4
|
-
|
|
5
|
-
**Where to find it:** **Library** in the sidebar. It opens on **Prompts**; the tabs across the top switch sections. They come in three groups: **Setups** (what a project starts from), **Building blocks** (what those setups are made of) and **Results**.
|
|
6
|
-
|
|
7
|
-
## The tabs
|
|
8
|
-
|
|
9
|
-
| Group | Tab | What it holds | Page |
|
|
10
|
-
|---|---|---|---|
|
|
11
|
-
| Setups | **Templates** | Saved Play setups, and **Add pack** for the starter packs | [Templates](Templates) |
|
|
12
|
-
| Building blocks | **Prompts** | The instructions for articles, images, thumbnails, narration cues, YouTube descriptions, shorts, reviews and multi-voice scripts, each with `{{keywords}}` where the subject goes | [Prompts](Prompts) |
|
|
13
|
-
| Building blocks | **Intros & outros** | Short narrated openings and closings, written as text or generated by the text model | [Intros and outros](Intros-and-Outros) |
|
|
14
|
-
| Building blocks | **PDF themes** | Document themes: the look of the PDF made from the article | [Document themes](Document-Themes) |
|
|
15
|
-
| Building blocks | **Narration aliases** | Words the narrator says differently from how they are written, such as Dr. as Doctor | [Aliases and glossary](Narration-Aliases-and-Glossary) |
|
|
16
|
-
| Results | **A/B results** | How the versions of an A/B test did | |
|
|
17
|
-
|
|
18
|
-
## What every Library list has
|
|
19
|
-
|
|
20
|
-
Prompts, Intros & outros and Templates share the same row actions, in the same order:
|
|
21
|
-
|
|
22
|
-
| Action | What it does |
|
|
23
|
-
|---|---|
|
|
24
|
-
| **Edit** | Opens the item in its editor. (A template has no editor: Edit picks it and shows its keywords beside the list.) |
|
|
25
|
-
| **Duplicate** | Opens the editor with a copy, for you to rename and save. (A template is copied as `<name> copy` at once.) |
|
|
26
|
-
| **Use in Play** | Picks the item in your open Play draft and opens Play on the field that shows it. An article prompt switches the article to Generate, an image prompt is ticked with one image, a thumbnail prompt switches the thumbnail to From prompt, and a Description or Shorts prompt turns that step on. The rest of the draft stays as it was. The button is off while Play is starting a run. |
|
|
27
|
-
| **History** | Opens the item's versions, a side-by-side compare, and what uses it. See [Prompts](Prompts#history-and-versions). |
|
|
28
|
-
| **Delete** | Asks first, then moves the item to **Settings → Backup & storage → Trash** for 30 days. See [Trash](Trash). |
|
|
29
|
-
|
|
30
|
-
Your document themes have Edit, Duplicate and Delete, but no Use in Play or History. Built-in themes can only be copied.
|
|
31
|
-
|
|
32
|
-
A press anywhere on a row picks it; the row's own buttons still do their own thing. Beside each list, the selected item shows its text, its **Keywords**, what it is **Used by**, and its latest change.
|
|
33
|
-
|
|
34
|
-
### Rename in the row
|
|
35
|
-
|
|
36
|
-
In Prompts, Intros & outros and Templates, the pencil beside a name (**Rename <name>**) turns the name into a field. Type the new name and press **Save name** or Enter; `Esc` or **Cancel** keeps the old one. Only the name changes, and the notice ("Renamed “A” to “B”.") has **Undo**. A prompt's or entry's rename is one History version; a template's is a new template version.
|
|
37
|
-
|
|
38
|
-
### Save with Ctrl+S
|
|
39
|
-
|
|
40
|
-
In the prompt, intro and outro and document theme editors, `Ctrl+S` (`Cmd+S`) saves, even while you are typing in a field.
|
|
41
|
-
|
|
42
|
-
## Search and filter
|
|
43
|
-
|
|
44
|
-
- **Prompts** has a **Prompt kind** picker (Article, Image, Thumbnail, Narration Preparation, YouTube Description, Shorts, Review, Script (speakers)) and **Search prompts**.
|
|
45
|
-
- **Intros & outros** has **Search intros and outros**.
|
|
46
|
-
- **Templates** has **Show templates of** to filter by channel.
|
|
47
|
-
- Press `/` on Prompts or Intros & outros to jump to the search box.
|
|
48
|
-
|
|
49
|
-
## Command palette shortcuts
|
|
50
|
-
|
|
51
|
-
Press `Ctrl+K` anywhere and type to find **New prompt**, **New intro or outro**, **New PDF theme**, **Open prompts**, **Open intros and outros**, **Open templates** or **Open PDF themes**, or a saved item by name: **Open template <name>** (Templates with it shown beside the list), **Edit prompt <name>**, **Edit intro <name>** / **Edit outro <name>** and **Edit PDF theme <name>**. See [Keyboard and Ctrl+K](Keyboard-Shortcuts-and-Command-Palette).
|
|
52
|
-
|
|
53
|
-
## Starter packs
|
|
54
|
-
|
|
55
|
-
**Library → Templates → Add pack** adds a ready-made set for one kind of channel: prompts, a suggested voice and a Play template. There are four packs: Sleep lore, True crime, History and Science explainers. Adding one twice changes nothing, and a pack never replaces a prompt or template of yours with the same name. See [Templates](Templates#starter-packs).
|
|
56
|
-
|
|
57
|
-
## Fonts
|
|
58
|
-
|
|
59
|
-
The Library has no separate font manager. Fonts live where they are used:
|
|
60
|
-
|
|
61
|
-
- **Caption (subtitle) fonts:** upload your own in the subtitle font picker on Play's video style settings. Uploaded fonts then appear in a channel's brand kit too. See [Video and style](Play-Video-and-Style) and [Channels](Channels).
|
|
62
|
-
- **PDF fonts:** each document theme picks its fonts from the bundled Cinzel and the fonts built into every PDF reader (Times, Helvetica, Courier). See [Document themes](Document-Themes).
|
|
63
|
-
|
|
64
|
-
Uploaded fonts travel in backups, but templates leave them out.
|
|
65
|
-
|
|
66
|
-
## How changes reach your videos
|
|
67
|
-
|
|
68
|
-
A project copies the prompts, intros, outros, aliases and theme settings it uses when it starts. Editing the Library later changes only runs started afterwards. Templates also keep their own copies, so save a template again to pick up a changed prompt. In a project, **Edit project** shows the project's own copy of each prompt: pick the Library prompt again (or press **Use the Library version**) to bring in your latest edit, and press **Update from Library** under narration aliases to copy the current alias list. See [Editing a project](Editing-a-Project).
|
|
69
|
-
|
|
70
|
-
## Related pages
|
|
71
|
-
|
|
72
|
-
- [Prompts](Prompts)
|
|
73
|
-
- [Intros and outros](Intros-and-Outros)
|
|
74
|
-
- [Templates](Templates)
|
|
75
|
-
- [Document themes](Document-Themes)
|
|
76
|
-
- [Aliases and glossary](Narration-Aliases-and-Glossary)
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
# Play Images
|
|
2
|
-
|
|
3
|
-
The images are the pictures your video shows while the narration plays. On Play you pick who draws them, which Library image prompts they come from and how many each makes, and optionally an establishing image that keeps characters and style consistent. You get a set of images, drawn in the video's frame shape, played in order.
|
|
4
|
-
|
|
5
|
-
**Where to find it:** Play → **Images** row → **Change**.
|
|
6
|
-
|
|
7
|
-
## Choose where the images come from
|
|
8
|
-
|
|
9
|
-
The Images row starts with a **Source** switch:
|
|
10
|
-
|
|
11
|
-
| Source | What happens | Cost |
|
|
12
|
-
| --- | --- | --- |
|
|
13
|
-
| **Generate** (default) | Draws images from the ticked image prompts, one image-model call each. | Per image, by the provider |
|
|
14
|
-
| **Provide** | Uses your own PNG, JPEG or WebP files (**Slideshow images**) in the order you pick them. | None |
|
|
15
|
-
| **Off** | No images. This turns the video off too: the **Video and style** row says "Video is Off because Images is Off." | None |
|
|
16
|
-
|
|
17
|
-
### Use your own images
|
|
18
|
-
|
|
19
|
-
1. Set **Source** to **Provide**.
|
|
20
|
-
2. Pick the files under **Slideshow images**. Each is numbered in the order it plays.
|
|
21
|
-
3. Remove a file with its remove button, or reattach one whose upload was lost.
|
|
22
|
-
|
|
23
|
-
A video can have at most 60 of your images, and the same file cannot be picked twice. Wait for every upload to finish before pressing Start.
|
|
24
|
-
|
|
25
|
-
## Pick the image provider and model
|
|
26
|
-
|
|
27
|
-
| Option | What it does | Default |
|
|
28
|
-
| --- | --- | --- |
|
|
29
|
-
| **Provider** | Who draws the images, the thumbnail and the shorts' pictures: a keyed service billed per image (fal.ai, Replicate, OpenAI, Google), or a command-line tool you are signed in to (Codex CLI). A greyed provider says why it cannot be used; fix it under Settings. | Your Settings default |
|
|
30
|
-
| **Model** | The provider's image model. Models differ in quality, speed and price per image; the estimate in the right rail shows what this run costs. The refresh button asks for the current list; **Custom ID** lets you type one. | Your Settings default |
|
|
31
|
-
| **Effort** | How long an image agent, such as the Codex CLI, reasons before it draws. Higher effort can follow the prompt more closely but takes longer and uses more tokens. Shown only for models that offer levels. | **Model default** |
|
|
32
|
-
|
|
33
|
-
Changing the provider clears the model.
|
|
34
|
-
|
|
35
|
-
### Drawing with the Codex CLI
|
|
36
|
-
|
|
37
|
-
With **Codex CLI** as the image provider, the **Model** list holds **Codex default** and the Codex CLI's own models. **Codex default** leaves the model and effort to the CLI's own defaults. Any other model runs with the **Effort** you pick. An image agent that reviews and redraws its picture can work for several minutes at a high effort. Images drawn this way cost nothing extra on your plan; the estimate shows the approximate API price beside **$0 on your plan**. See [AI CLIs](AI-CLIs).
|
|
38
|
-
|
|
39
|
-
## Pick the image prompts
|
|
40
|
-
|
|
41
|
-
1. Under **Image prompts**, tick the Library prompts that should draw the video's images.
|
|
42
|
-
2. Give each ticked prompt a **Number**: how many images it makes, 1 to 20.
|
|
43
|
-
3. Check the total under the list, for example **8 of 60 images**.
|
|
44
|
-
|
|
45
|
-
| Rule | Value |
|
|
46
|
-
| --- | --- |
|
|
47
|
-
| Images per prompt | 1 to 20 |
|
|
48
|
-
| Images per run, hand-set | at most 60 |
|
|
49
|
-
| Images per run, with **More images for long videos** | at most 240 |
|
|
50
|
-
| Order | The images play in the order you ticked the prompts |
|
|
51
|
-
|
|
52
|
-
Each image is one image-model call. A prompt that has been deleted since this draft picked it shows **Missing template · untick to remove**. With no image prompts at all, the row says "No image prompts saved. Write one on Prompts." See [Prompts](Prompts).
|
|
53
|
-
|
|
54
|
-
### Photorealistic prompts
|
|
55
|
-
|
|
56
|
-
An image prompt in the Library has a **Draws photorealistic pictures** tick. Turn it on when the prompt's style looks like real photos or film. Prepare upload then answers Yes to YouTube's AI use question for videos and shorts drawn with it. Leave it off for painterly or illustrated styles. It is set on the prompt, not on Play: open Library → Prompts → the prompt. See [Prompts](Prompts) and [Publishing to YouTube](Publishing-to-YouTube).
|
|
57
|
-
|
|
58
|
-
## Establishing image
|
|
59
|
-
|
|
60
|
-
The establishing image is made first and never shown in the video. Every other image, the shorts' images and (if ticked) the thumbnail are drawn with it as a reference, so characters, style and palette stay the same across the video.
|
|
61
|
-
|
|
62
|
-
| Option | What it does | Default |
|
|
63
|
-
| --- | --- | --- |
|
|
64
|
-
| **Establishing image** | **Off**, **From a prompt** (costs one more image) or **Upload** (your own PNG or JPEG, **Establishing image file**). | Off |
|
|
65
|
-
| **Establishing prompt** | The Library image prompt that draws it, keywords filled like the others. Describe the characters, setting and style every other image should share. | None |
|
|
66
|
-
| **Draw the thumbnail from it too** | Draws the thumbnail with the establishing image as a reference too, so it matches the video. Untick it for a thumbnail drawn on its own. | On |
|
|
67
|
-
|
|
68
|
-
Changing the establishing image later marks the images drawn from it as outdated. When you upload the establishing image, the style preview in the right rail is drawn on it, so you judge the Look and captions on your own picture.
|
|
69
|
-
|
|
70
|
-
### Set up an establishing image
|
|
71
|
-
|
|
72
|
-
1. Under **Establishing image**, pick **From a prompt** or **Upload**.
|
|
73
|
-
2. For **From a prompt**, pick the **Establishing prompt**. For **Upload**, pick the file.
|
|
74
|
-
3. Leave **Draw the thumbnail from it too** ticked if the thumbnail should match.
|
|
75
|
-
|
|
76
|
-
## The channel's cast
|
|
77
|
-
|
|
78
|
-
The channel you pick in the **Channel** row brings its cast: characters, creatures, places and objects, each with reference pictures. When an image's brief mentions a cast member by name or alias (as a whole word, ignoring case), that image is drawn with the member's pictures as references, after the establishing image when it is on. The establishing image and the thumbnail also take the members the title mentions. At most four members go with one image.
|
|
79
|
-
|
|
80
|
-
Models that take several input pictures (Codex, OpenAI, Google, and fal.ai's FLUX.2 and Nano Banana 2 edit models) use the pictures directly. A model that takes none gets the members described in words instead. The cast is used even when **Use the channel's brand kit** is off. See [Cast Library](Cast-Library) and [Channels](Channels).
|
|
81
|
-
|
|
82
|
-
## More images for long videos
|
|
83
|
-
|
|
84
|
-
A long video with a fixed handful of images repeats them for an hour. **More images for long videos** adds images as the narration gets longer.
|
|
85
|
-
|
|
86
|
-
| Option | What it does | Default / range |
|
|
87
|
-
| --- | --- | --- |
|
|
88
|
-
| **More images for long videos** | Adds images, planned from the expected length when the run starts. The extra images are shared among the ticked prompts in order, up to 240 in all. Each is one more image call. | Off |
|
|
89
|
-
| **How the rate is given** | **Every N minutes**: one image every N minutes of narration (0.25 to 60). **N per hour**: N images per hour (1 to 240). Switching keeps the same rate. | One image every 2 minutes |
|
|
90
|
-
|
|
91
|
-
### Turn it on
|
|
92
|
-
|
|
93
|
-
1. Tick at least one image prompt.
|
|
94
|
-
2. Switch on **More images for long videos**.
|
|
95
|
-
3. Pick **Every N minutes** or **N per hour** and type the rate.
|
|
96
|
-
4. Read the line under it, for example: "For about 60 minutes (9,000 words expected, set on Review): 30 images, 26 more than the prompts' 4."
|
|
97
|
-
|
|
98
|
-
How the count is worked out:
|
|
99
|
-
|
|
100
|
-
- The length is the pasted article's own word count, or else **Expected article words per video** in the right rail, at 150 spoken words a minute.
|
|
101
|
-
- Each ticked prompt keeps its own **Number** as a minimum. The extra images are handed to the ticked prompts one at a time, in the order they were ticked.
|
|
102
|
-
- When the prompts' own Numbers already cover the length, nothing is added.
|
|
103
|
-
- The count stops at 240. After that the slideshow repeats its images, as it does whenever the narration outlasts them.
|
|
104
|
-
- The count is planned once, when the run starts. A narration that turns out longer is still covered by the slideshow cycling its images.
|
|
105
|
-
|
|
106
|
-
Turning it on also switches **Motion** (in the **Video and style** row) from **Zoom in and out** to **Mix of both**, so a long video pans and zooms by turns. A **Pan across** or **Still** you picked stays, and you can pick Zoom again.
|
|
107
|
-
|
|
108
|
-
## Scenes from the article
|
|
109
|
-
|
|
110
|
-
Without it, every image of a prompt is drawn from the same text, so three images of one prompt tend to show the same picture three times. **Scenes from the article** gives every image its own moment.
|
|
111
|
-
|
|
112
|
-
| Option | What it does | Default |
|
|
113
|
-
| --- | --- | --- |
|
|
114
|
-
| **Scenes from the article** | Before the images are drawn, the project's AI model reads the article once and writes a short scene for each image. Scene 1 comes from the article's opening and the last from its ending, in the order the images are shown. Each image is drawn from its prompt with its scene added. One more AI call per run. | Off |
|
|
115
|
-
|
|
116
|
-
Where the scene goes:
|
|
117
|
-
|
|
118
|
-
- A prompt with `{{Scene}}` gets the scene there, for example a line `Scene: {{Scene}}` under the prompt's first sentence. `{{Scene}}` is never a field to fill in: Slopify writes it.
|
|
119
|
-
- A prompt without it gets the scene as a line of its own after its first paragraph, so any prompt works unchanged.
|
|
120
|
-
- With the switch off, a line holding `{{Scene}}` is left out and the prompt is drawn as it always was.
|
|
121
|
-
- A **thumbnail** prompt with `{{Scene}}` gets a scene from a call of its own (one more AI call, in the Thumbnail stage, so changing the thumbnail never remakes the images): the article's most striking moment, the one that would make someone click, taken from anywhere in the article. With **Thumbnails** set to 3, each thumbnail gets a different moment, so the A/B test compares ideas as well as compositions. A thumbnail prompt without `{{Scene}}` is drawn as it always was.
|
|
122
|
-
|
|
123
|
-
The style, composition and everything else in the prompt stay as written; only the scene changes from image to image. The scenes are written once the article exists, and each image waits for them. Switching it on or off in **Edit project** remakes the images.
|
|
124
|
-
|
|
125
|
-
## Looks looked up: {{Appearance}}
|
|
126
|
-
|
|
127
|
-
An image model draws a named figure from whatever it half remembers, so the same character can look different in every image. Put `{{Appearance}}` in an image, thumbnail, establishing or shorts image prompt, for example a line `Looks: {{Appearance}}`, and Slopify looks the looks up instead.
|
|
128
|
-
|
|
129
|
-
- Once the article exists, one call to the project's AI model **searches the web** for how the video's subject and every named character in the article look: build, face, clothing, colours and the marks that make them recognisable. Where depictions disagree, it describes the most iconic one.
|
|
130
|
-
- With **Scenes from the article** on, each picture gets the looks of the figures its scene names (up to three besides the subject), so a scene of a place or of someone else isn't redrawn with the subject in it; a scene that names no one leaves the looks line out. A thumbnail always gets the subject's look. Without scenes, every picture gets the subject's look.
|
|
131
|
-
- There is no switch: a prompt with `{{Appearance}}` turns it on, and prompts without it are drawn as they always were. `{{Appearance}}` is never a field to fill in.
|
|
132
|
-
- It costs one more AI call per run, with web search. The pictures that use it wait for it.
|
|
133
|
-
|
|
134
|
-
## How long each image stays on screen
|
|
135
|
-
|
|
136
|
-
**Seconds per image** (1 to 600, default 15) is in the **Video and style** row, beside **Cuts**, **Zoom** and **Motion**. When cuts follow the narration, it is the target length and a cut waits for a sentence end. When images run out, they start again. See [Play Video and Style](Play-Video-and-Style).
|
|
137
|
-
|
|
138
|
-
## The thumbnail and the shorts
|
|
139
|
-
|
|
140
|
-
The thumbnail and the shorts' images use the same image provider and model. If the video's images are not generated but the thumbnail is, the thumbnail gets its own **Provider**, **Model** and **Effort** pickers in the **Outputs** row. See [Play Outputs](Play-Outputs) and [Shorts](Shorts).
|
|
141
|
-
|
|
142
|
-
## What the row summary says
|
|
143
|
-
|
|
144
|
-
Folded, the Images row lists each ticked prompt with its Number, the provider and model, and "establishing image" when one is on, for example `Scene × 6, Portrait × 2 · fal.ai · flux-pro · establishing image`. With Provide it says how many of your images there are.
|
|
145
|
-
|
|
146
|
-
## Tips
|
|
147
|
-
|
|
148
|
-
- Keep one style across the video with an establishing image, instead of repeating the style in every image prompt.
|
|
149
|
-
- Picture reviews can check each image for malformed hands, stray text and a match with its brief. They need Claude Code or Codex as the reviewer. See [Reviews and Checkpoints](Reviews-and-Checkpoints).
|
|
150
|
-
- After the run, you can add, remove or regenerate single images on the project page. See [Editing a Project](Editing-a-Project).
|
|
151
|
-
|
|
152
|
-
## Related pages
|
|
153
|
-
|
|
154
|
-
- [Play Overview](Play-Overview)
|
|
155
|
-
- [Prompts](Prompts)
|
|
156
|
-
- [Cast Library](Cast-Library)
|
|
157
|
-
- [Channels](Channels)
|
|
158
|
-
- [Models](Models)
|
|
159
|
-
- [Costs and Run Cost](Costs-and-Run-Cost)
|
|
160
|
-
- [Play Video and Style](Play-Video-and-Style)
|
|
161
|
-
- [Play Outputs](Play-Outputs)
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# Play Narration
|
|
2
|
-
|
|
3
|
-
The narration is the article read aloud by a text-to-speech (TTS) voice. On Play you pick the service, model and voice, and fine-tune how the text is prepared, split, paced and levelled. You get a narration track that the captions, cuts, chapters and shorts are all timed from.
|
|
4
|
-
|
|
5
|
-
**Where to find it:** Play → **Narration** row → **Change**. The pauses, the volume levelling and the silences sit in Play → **Video and style**, and **Show tables and figures on screen** sits in Play → **Outputs**; they are described here because they shape the narration.
|
|
6
|
-
|
|
7
|
-
## Choose where the narration comes from
|
|
8
|
-
|
|
9
|
-
The Narration row starts with a **Source** switch:
|
|
10
|
-
|
|
11
|
-
| Source | What happens | Cost |
|
|
12
|
-
| --- | --- | --- |
|
|
13
|
-
| **Generate** (default) | A TTS voice reads the article aloud. | Charged by the provider per character |
|
|
14
|
-
| **Provide** | Uses an audio file you upload (**Narration file**), as it is. | None |
|
|
15
|
-
| **Off** | Makes a silent video with no captions, YouTube description or shorts. The row reads "Off, a silent video". | None |
|
|
16
|
-
|
|
17
|
-
With **Provide**, the file is used as is: "Uploaded narration is used as-is; include any intro and outro in that file." It is never levelled piece by piece; only the final master reaches it when **Level the volume** is on.
|
|
18
|
-
|
|
19
|
-
## Pick a voice
|
|
20
|
-
|
|
21
|
-
1. Open the **Narration** row and leave **Source** on **Generate**.
|
|
22
|
-
2. Pick the **TTS** provider. A greyed provider says why it cannot be used; add its key under Settings.
|
|
23
|
-
3. Pick the **TTS model**.
|
|
24
|
-
4. Pick a **Voice**. If the list says "No voices. Add one in Settings.", add a voice first (see [Add a voice](#add-a-voice-under-settings--voices)).
|
|
25
|
-
|
|
26
|
-
| Option | What it does | Default |
|
|
27
|
-
| --- | --- | --- |
|
|
28
|
-
| **TTS** | The text-to-speech service, charged per character of text: ElevenLabs, OpenAI, Cartesia, Inworld, Google Gemini, or **System voice**, your computer's own speech, which is free (greyed as **Speech Program Missing** when none is found; see [the system voice](Providers-and-Keys#the-system-voice)). Changing it clears the model and voice. | Your Settings default |
|
|
29
|
-
| **TTS model** | The provider's speech model. Models differ in quality, languages, speed and price per character. Narration Preparation needs Inworld TTS-2. The refresh button asks the provider for its current list; **Custom ID** lets you type one. | Your Settings default |
|
|
30
|
-
| **Voice** | Who reads the narration: the voices you added under Settings → Voices for this provider, filtered to the project's language. With several speakers, this voice reads the intro and outro. | None |
|
|
31
|
-
| **Show all voices** | The voice list hides voices listed for other languages than the project's. Tick this to pick one anyway, for example a multilingual voice whose languages are listed wrong. The label says how many are hidden. A voice with unknown languages is always shown. | Off |
|
|
32
|
-
|
|
33
|
-
### Several speakers
|
|
34
|
-
|
|
35
|
-
Under the voice is a **Speakers** disclosure. It reads "Narration, one voice" by default. Open it to pick an audiobook, podcast, radio drama or interview format with several speakers, each with their own voice. See [Multiple Voices](Multiple-Voices) for every speaker setting, and [Other Languages](Other-Languages) for narrating in another language.
|
|
36
|
-
|
|
37
|
-
## More audio settings
|
|
38
|
-
|
|
39
|
-
**More audio settings** is a disclosure under the voice. Its line says what is not at the default, for example `words · intro Welcome · glossary on`.
|
|
40
|
-
|
|
41
|
-
### Chunking
|
|
42
|
-
|
|
43
|
-
How the narration is split into TTS requests. Split it when a provider refuses long text. It changes the number of requests, not the characters charged.
|
|
44
|
-
|
|
45
|
-
| Option | What it does | Default |
|
|
46
|
-
| --- | --- | --- |
|
|
47
|
-
| **Chunking** | **Whole** sends the narration in one request. **Paragraph** sends one per paragraph. **Every N words** or **Every N characters** ends each request at a sentence end. | **Whole** |
|
|
48
|
-
| **Words** / **Characters** (chunk size) | How long each request may be. Each request ends at the last whole sentence that fits, so a single longer sentence stays whole. Characters count spaces. | 500 words, or 3000 characters |
|
|
49
|
-
|
|
50
|
-
Up to 10,000 words or 1,000,000 characters per chunk.
|
|
51
|
-
|
|
52
|
-
### Intro and outro
|
|
53
|
-
|
|
54
|
-
**Intro** and **Outro** pick Library entries read before and after the article. See [Play Title and Article](Play-Title-and-Article#intro-and-outro) and [Intros and Outros](Intros-and-Outros).
|
|
55
|
-
|
|
56
|
-
### Narration Preparation
|
|
57
|
-
|
|
58
|
-
Has the text model add delivery directions and sounds, such as a sigh or a laugh, following the Library narration prompt you pick. The article and captions stay unchanged.
|
|
59
|
-
|
|
60
|
-
| Option | What it does | Default |
|
|
61
|
-
| --- | --- | --- |
|
|
62
|
-
| **Narration Preparation** | Pick a narration prompt from the Library, or **Off**. One text-model call per narration chunk and per intro or outro entry. | Off |
|
|
63
|
-
|
|
64
|
-
It needs the Inworld TTS-2 model. With another model, the field says "Choose Inworld TTS-2 or turn preparation Off." With several speakers it works per speaker: each turn of a speaker on Inworld TTS-2 is prepared on its own, with the speaker's name and role, so every voice gets its own cues. At least one speaker must use TTS-2; turns of speakers on other voices are spoken as written. See [Multiple Voices](Multiple-Voices). Preparation is written by the text model: when nothing earlier needs one (a pasted article, say), **Text generation** appears in this row.
|
|
65
|
-
|
|
66
|
-
### Pronunciation Glossary
|
|
67
|
-
|
|
68
|
-
| Option | What it does | Default |
|
|
69
|
-
| --- | --- | --- |
|
|
70
|
-
| **Use Pronunciation Glossary** | Reads names with the IPA in the article's Pronunciation Glossary, such as `Arda: /ˈɑɹdə/`, with no extra text-model call. Works with Inworld TTS-2 and TTS-2 Flash. The written text stays unchanged. | On |
|
|
71
|
-
| **Also use pronunciations from my other projects** | Adds every term from your other projects' glossaries, copied when this project starts. This project's own glossary wins where they differ. Turn it off to use only this article's glossary. | On |
|
|
72
|
-
|
|
73
|
-
With another provider or model the switch is greyed and says "Unavailable for this provider or model. Your saved preference is retained."
|
|
74
|
-
|
|
75
|
-
To get a glossary, ask for one in your article prompt: a section in slash-delimited standard-English IPA, one `Term: /IPA/` per line, with an English approximation for foreign names. A line with sounds English lacks is read as plain text. The glossary is never narrated itself. See [Narration Aliases and Glossary](Narration-Aliases-and-Glossary).
|
|
76
|
-
|
|
77
|
-
### Narration aliases
|
|
78
|
-
|
|
79
|
-
| Option | What it does | Default |
|
|
80
|
-
| --- | --- | --- |
|
|
81
|
-
| **Use narration aliases** | Says the words listed in Library → Narration aliases the way they are written there, such as `Dr.` as `Doctor`, with any generated voice. They are copied when the project starts. The article and captions keep the written words. | On |
|
|
82
|
-
|
|
83
|
-
Manage the list in [Narration Aliases and Glossary](Narration-Aliases-and-Glossary).
|
|
84
|
-
|
|
85
|
-
### Tables, figures and code
|
|
86
|
-
|
|
87
|
-
An article written to be read can contain tables, pictures, equations and code. Read aloud cell by cell or symbol by symbol, they are noise.
|
|
88
|
-
|
|
89
|
-
| Option | What it does | Default |
|
|
90
|
-
| --- | --- | --- |
|
|
91
|
-
| **Describe tables and figures in the narration** | The text model writes a short spoken passage for each table, picture, equation and code block (a table's pattern, what a figure or equation means, what code does), and the narration says it in its place. One extra text-model call per block, in the estimate and kept for reuse. The article and PDF keep the real table; captions show what is said. Needs a text model. | On |
|
|
92
|
-
| **Leave code out** | Shown under the switch above. Drops code blocks from the narration instead of summarising each in a sentence or two. Tables, figures and equations are still described. | Off |
|
|
93
|
-
| **Show tables and figures on screen** (in the **Outputs** row) | Each block the narration describes is also shown in the video while it is described: the article's own picture for a figure, a card drawn in your brand kit's title font and colour for the rest. The images take turns around them, and Shorts that include one show it upright. Drawn on this computer at no cost. Offered while the narration describes tables and figures. | On |
|
|
94
|
-
|
|
95
|
-
Even with the switch off, some things are handled for you: links are read without their address, and footnote markers, the Sources Consulted section and the Pronunciation Glossary are never narrated.
|
|
96
|
-
|
|
97
|
-
## Pauses between sentences and paragraphs
|
|
98
|
-
|
|
99
|
-
Some voices run one sentence into the next with barely a breath. These settings add quiet where the voice's own pause is shorter. They never shorten a pause or cut a word, and the captions follow. They are in the **Video and style** row, beside **Level the volume**, and only show while the narration is generated.
|
|
100
|
-
|
|
101
|
-
| Option | What it does | Default / range |
|
|
102
|
-
| --- | --- | --- |
|
|
103
|
-
| **Pause between sentences (seconds)** | The least quiet after each sentence. About 0.25 s is brisk, 0.35 to 0.45 natural or documentary, 0.5 to 0.8 an audiobook's relaxed pace, 0.8 and up sleep content. 0 keeps the voice's own. | 0.4; 0 to 2 in steps of 0.05 |
|
|
104
|
-
| **Pause between paragraphs (seconds)** | The least quiet at the end of a paragraph, when you want more than between sentences. Try 0.8 to 1.2 for a slower read. 0 gives paragraphs the sentence pause. | 0; 0 to 2 in steps of 0.05 |
|
|
105
|
-
|
|
106
|
-
The pauses are added on this computer before the word timing, so the captions, cuts, shorts and YouTube chapters stay in step. With several speakers, the gap between turns is **Gap between turns** under Speakers instead.
|
|
107
|
-
|
|
108
|
-
## Level the volume
|
|
109
|
-
|
|
110
|
-
TTS comes back at a different loudness for every voice and even every request, so a joined narration can jump between quiet and loud. **Level the volume** brings every narration piece (each chunk, each intro and outro, each speaker's turn) to one loudness before they are joined, then sets the finished video, shorts and audio files to a target loudness. It runs on this computer with no API calls. It is in the **Video and style** row and shows whenever there is narration.
|
|
111
|
-
|
|
112
|
-
| Option | What it does | Default / range |
|
|
113
|
-
| --- | --- | --- |
|
|
114
|
-
| **Level the volume** | Turns levelling on or off for this run. A draft that never changed it follows Settings → General. | On |
|
|
115
|
-
| **Video volume** | How loud the finished video and shorts are. 0 dB is −14 LUFS, what YouTube and Spotify play everything at. Peaks always stay under −1.5 dBTP. | 0 dB; −10 to +4 dB in steps of 0.5 |
|
|
116
|
-
| **Audio files volume** | How loud the audio-only WAV and an audiobook's MP3 and M4B are. 0 dB is −18 LUFS, the level audiobook shops ask for. Peaks always stay under −3 dBTP. | 0 dB; −10 to +4 dB in steps of 0.5 |
|
|
117
|
-
|
|
118
|
-
Type each volume in **dB** or as a **%** of the recommended level; the other box follows. −6 dB is about 50% and +4 dB about 158%. The help line under each field says the LUFS it stands for. LUFS is how loud a file sounds on average, measured the way ears hear it.
|
|
119
|
-
|
|
120
|
-
## Silence at the edges and between segments
|
|
121
|
-
|
|
122
|
-
Both are in the **Video and style** row and only show while there is narration.
|
|
123
|
-
|
|
124
|
-
| Option | What it does | Default / range |
|
|
125
|
-
| --- | --- | --- |
|
|
126
|
-
| **Silence at start and end (seconds)** | Quiet time before the narration starts and after it ends. | 2; 0 to 30 |
|
|
127
|
-
| **Silence between segments (seconds)** | Quiet between the intro and the narration, and between the narration and the outro. Only matters when an intro or outro is set. Leave it empty to use the gap set in Settings. | Settings value (3 unless changed); 0 to 30 |
|
|
128
|
-
|
|
129
|
-
## Add a voice under Settings → Voices
|
|
130
|
-
|
|
131
|
-
The **Voice** list on Play only offers voices you have added.
|
|
132
|
-
|
|
133
|
-
1. Open Settings → **Voices**.
|
|
134
|
-
2. Fill in **Voice name**, **Provider**, **Voice ID** and, optionally, **Languages**.
|
|
135
|
-
3. Press **Add voice**. The voice joins the table above the form.
|
|
136
|
-
4. Optional: tick **Real person** on the voice's row in the table if it imitates a real person.
|
|
137
|
-
|
|
138
|
-
| Field | What it does |
|
|
139
|
-
| --- | --- |
|
|
140
|
-
| **Voice name** | The name you pick this voice by on Play and in Edit project. Only you see it. |
|
|
141
|
-
| **Provider** | The TTS service the voice ID belongs to. Only providers set up under Settings are listed. |
|
|
142
|
-
| **Voice ID** | The provider's own id for the voice, copied from its voice library. It is not checked now; a wrong id fails when a run's narration uses it. |
|
|
143
|
-
| **Languages** | The languages the voice speaks, as codes such as `es`, `de`. Play lists the voice only for projects in these languages. Blank asks the provider when it can say; a voice with unknown languages is offered for every language. |
|
|
144
|
-
| **Real person** | Turn on for a voice cloned from, or made to sound like, a real person. Prepare upload then answers Yes to YouTube's AI use question for videos it narrates. An AI voice that imitates no one stays off. |
|
|
145
|
-
|
|
146
|
-
See [Settings Reference](Settings-Reference) and [Publishing to YouTube](Publishing-to-YouTube).
|
|
147
|
-
|
|
148
|
-
## What the row summary says
|
|
149
|
-
|
|
150
|
-
Folded, the Narration row shows the provider and voice (or the speakers format and count), and any preparation prompt, intro and outro, for example `Inworld · Ada · intro Welcome`. With Provide it shows your file's name.
|
|
151
|
-
|
|
152
|
-
## Tips
|
|
153
|
-
|
|
154
|
-
- If a provider refuses long requests, switch **Chunking** to **Paragraph** or **Every 500 words**. The characters charged stay the same.
|
|
155
|
-
- Listen to the narration on the project page before publishing, in Slopify's own player (see [Project Page](Project-Page#the-players)). Fix a single chunk there instead of re-running everything. See [Editing a Project](Editing-a-Project).
|
|
156
|
-
- An automatic review can check the narration for missing or garbled passages. See [Reviews and Checkpoints](Reviews-and-Checkpoints).
|
|
157
|
-
|
|
158
|
-
## Related pages
|
|
159
|
-
|
|
160
|
-
- [Play Overview](Play-Overview)
|
|
161
|
-
- [Multiple Voices](Multiple-Voices)
|
|
162
|
-
- [Other Languages](Other-Languages)
|
|
163
|
-
- [Narration Aliases and Glossary](Narration-Aliases-and-Glossary)
|
|
164
|
-
- [Intros and Outros](Intros-and-Outros)
|
|
165
|
-
- [Prompts](Prompts)
|
|
166
|
-
- [Providers and Keys](Providers-and-Keys)
|
|
167
|
-
- [Play Video and Style](Play-Video-and-Style)
|