@crievo/omni 0.0.0-stage → 0.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/.env.example +41 -0
- package/README.md +2 -2
- package/bin/omni.mjs +14 -0
- package/docs/onboarding/clone-voice.png +0 -0
- package/docs/onboarding/getting-started.png +0 -0
- package/docs/onboarding/new-video.png +0 -0
- package/docs/onboarding/providers.png +0 -0
- package/docs/onboarding/publish.png +0 -0
- package/docs/onboarding/references.png +0 -0
- package/docs/onboarding.md +212 -0
- package/omnivideo.config.example.json +437 -0
- package/package.json +40 -4
- package/reference/captions.md +156 -0
- package/reference/carousel-contract.md +91 -0
- package/reference/cloud.md +96 -0
- package/reference/learnings.md +792 -0
- package/reference/omnichat.md +305 -0
- package/reference/premiere-mcp.md +91 -0
- package/reference/publish.md +305 -0
- package/reference/scenes-contract.md +109 -0
- package/reference/studio.md +666 -0
- package/reference/voicestudio.md +81 -0
- package/reference/writing-for-voice.md +67 -0
- package/requirements.txt +3 -0
- package/studio/api/app.ts +87 -0
- package/studio/api/lib/errors.ts +33 -0
- package/studio/api/lib/files.ts +41 -0
- package/studio/api/lib/hono.ts +9 -0
- package/studio/api/lib/result.ts +14 -0
- package/studio/api/lib/validate.ts +31 -0
- package/studio/api/lib/video.ts +10 -0
- package/studio/api/middleware/json-charset.ts +11 -0
- package/studio/api/middleware/local-only.ts +32 -0
- package/studio/api/middleware/no-timeout.ts +10 -0
- package/studio/api/routes/admin.ts +18 -0
- package/studio/api/routes/agent-cascade.ts +100 -0
- package/studio/api/routes/agent-history.ts +23 -0
- package/studio/api/routes/agent.ts +162 -0
- package/studio/api/routes/analytics.ts +31 -0
- package/studio/api/routes/approval.ts +60 -0
- package/studio/api/routes/archive.ts +12 -0
- package/studio/api/routes/captions.ts +28 -0
- package/studio/api/routes/carousel.ts +38 -0
- package/studio/api/routes/clone.ts +27 -0
- package/studio/api/routes/create.ts +19 -0
- package/studio/api/routes/events.ts +11 -0
- package/studio/api/routes/export.ts +14 -0
- package/studio/api/routes/media.ts +30 -0
- package/studio/api/routes/omnichat.ts +113 -0
- package/studio/api/routes/onboarding.ts +14 -0
- package/studio/api/routes/publish.ts +40 -0
- package/studio/api/routes/queue.ts +14 -0
- package/studio/api/routes/references.ts +40 -0
- package/studio/api/routes/runner.ts +17 -0
- package/studio/api/routes/schedule.ts +47 -0
- package/studio/api/routes/services.ts +11 -0
- package/studio/api/routes/sessions.ts +27 -0
- package/studio/api/routes/settings.ts +102 -0
- package/studio/api/routes/sound.ts +45 -0
- package/studio/api/routes/thumbnail.ts +18 -0
- package/studio/api/routes/usage.ts +13 -0
- package/studio/api/routes/videos.ts +41 -0
- package/studio/api/routes/voices.ts +71 -0
- package/studio/api/services/admin.ts +113 -0
- package/studio/api/services/agent-cascade.ts +975 -0
- package/studio/api/services/agent-claude.ts +47 -0
- package/studio/api/services/agent-history.ts +103 -0
- package/studio/api/services/agent-persona.ts +77 -0
- package/studio/api/services/agent-tools.ts +2237 -0
- package/studio/api/services/agent-ui-tools.ts +259 -0
- package/studio/api/services/agent-wait.ts +32 -0
- package/studio/api/services/agent.ts +553 -0
- package/studio/api/services/analytics.ts +92 -0
- package/studio/api/services/approval.ts +134 -0
- package/studio/api/services/archive.ts +38 -0
- package/studio/api/services/captions.ts +268 -0
- package/studio/api/services/carousel.ts +206 -0
- package/studio/api/services/classify.ts +196 -0
- package/studio/api/services/clone-phrases.ts +75 -0
- package/studio/api/services/clone.ts +722 -0
- package/studio/api/services/create.ts +421 -0
- package/studio/api/services/events.ts +215 -0
- package/studio/api/services/media.ts +32 -0
- package/studio/api/services/omnichat.ts +624 -0
- package/studio/api/services/onboarding.ts +77 -0
- package/studio/api/services/publish.ts +287 -0
- package/studio/api/services/queue.ts +150 -0
- package/studio/api/services/references.ts +269 -0
- package/studio/api/services/root.ts +60 -0
- package/studio/api/services/services.ts +114 -0
- package/studio/api/services/sessions.ts +1007 -0
- package/studio/api/services/settings.ts +983 -0
- package/studio/api/services/sound.ts +311 -0
- package/studio/api/services/thumbnail.ts +133 -0
- package/studio/api/services/usage.ts +27 -0
- package/studio/api/services/videos.ts +418 -0
- package/studio/api/services/voice-pause.ts +98 -0
- package/studio/api/services/voices.ts +324 -0
- package/studio/runner/runner.ts +244 -0
- package/studio/shared/omni-actions.ts +68 -0
- package/studio/shared/omni-admin.ts +52 -0
- package/studio/shared/omni-farewell.ts +48 -0
- package/studio/shared/omni-hotword.ts +20 -0
- package/studio/shared/omni-screens.ts +228 -0
- package/studio/shared/schemas/admin.ts +15 -0
- package/studio/shared/schemas/agent-cascade.ts +58 -0
- package/studio/shared/schemas/agent-history.ts +73 -0
- package/studio/shared/schemas/agent.ts +50 -0
- package/studio/shared/schemas/analytics.ts +6 -0
- package/studio/shared/schemas/approval.ts +22 -0
- package/studio/shared/schemas/captions.ts +19 -0
- package/studio/shared/schemas/carousel.ts +26 -0
- package/studio/shared/schemas/clone.ts +40 -0
- package/studio/shared/schemas/common.ts +16 -0
- package/studio/shared/schemas/omnichat.ts +54 -0
- package/studio/shared/schemas/onboarding.ts +5 -0
- package/studio/shared/schemas/publish.ts +45 -0
- package/studio/shared/schemas/references.ts +20 -0
- package/studio/shared/schemas/settings.ts +82 -0
- package/studio/shared/schemas/sound.ts +22 -0
- package/studio/shared/schemas/videos.ts +38 -0
- package/studio/shared/schemas/voices.ts +23 -0
- package/studio/shared/types/api.ts +1290 -0
- package/studio/studio.ts +148 -0
- package/studio/tsconfig.json +15 -0
- package/studio/web/assets/logos/cartesia.svg +4 -0
- package/studio/web/assets/logos/elevenlabs.svg +12 -0
- package/studio/web/assets/logos/fish.svg +24 -0
- package/studio/web/assets/logos/omni-black.png +0 -0
- package/studio/web/assets/logos/omni-white.png +0 -0
- package/studio/web/assets/logos/voicestudio.svg +21 -0
- package/studio/web/components/AgentMark.tsx +7 -0
- package/studio/web/components/AgentWalking.tsx +11 -0
- package/studio/web/components/ApiKeyField.tsx +104 -0
- package/studio/web/components/AppShell.tsx +64 -0
- package/studio/web/components/ApprovalNotice.tsx +65 -0
- package/studio/web/components/AvatarGroupIcon.tsx +22 -0
- package/studio/web/components/AvatarNameField.tsx +86 -0
- package/studio/web/components/AvatarPicker.tsx +84 -0
- package/studio/web/components/BrandLogo.tsx +16 -0
- package/studio/web/components/CartesiaPlanSetting.tsx +90 -0
- package/studio/web/components/ClaudeWalking.tsx +32 -0
- package/studio/web/components/CloneVoiceDialog/GuidedScript.tsx +39 -0
- package/studio/web/components/CloneVoiceDialog/LanguageBar.tsx +37 -0
- package/studio/web/components/CloneVoiceDialog/LevelMeter.tsx +31 -0
- package/studio/web/components/CloneVoiceDialog/ProviderChoice.tsx +81 -0
- package/studio/web/components/CloneVoiceDialog/QualityPanel.tsx +62 -0
- package/studio/web/components/CloneVoiceDialog/RecordStep.tsx +50 -0
- package/studio/web/components/CloneVoiceDialog/RecorderBar.tsx +79 -0
- package/studio/web/components/CloneVoiceDialog/RedoSummary.tsx +54 -0
- package/studio/web/components/CloneVoiceDialog/SaveStep.tsx +91 -0
- package/studio/web/components/CloneVoiceDialog/SourceBar.tsx +30 -0
- package/studio/web/components/CloneVoiceDialog/index.tsx +141 -0
- package/studio/web/components/CloneVoiceDialog/types.ts +28 -0
- package/studio/web/components/CloneVoiceDialog/useCloneVoice.ts +528 -0
- package/studio/web/components/ConnectionSignals.tsx +51 -0
- package/studio/web/components/EditVoiceDialog/EditVoiceFooter.tsx +72 -0
- package/studio/web/components/EditVoiceDialog/ProviderCards.tsx +81 -0
- package/studio/web/components/EditVoiceDialog/index.tsx +256 -0
- package/studio/web/components/ErrorBanner.tsx +115 -0
- package/studio/web/components/FinishedTask.tsx +41 -0
- package/studio/web/components/FishModelSetting.tsx +69 -0
- package/studio/web/components/FishPriceSetting.tsx +44 -0
- package/studio/web/components/HumanBanner.tsx +64 -0
- package/studio/web/components/Lightbox.tsx +41 -0
- package/studio/web/components/LogStream.tsx +42 -0
- package/studio/web/components/Markdown.tsx +21 -0
- package/studio/web/components/MissingDmsPanel/BatchSend.tsx +137 -0
- package/studio/web/components/MissingDmsPanel/CommentCard.tsx +168 -0
- package/studio/web/components/MissingDmsPanel/CommentFeed.tsx +45 -0
- package/studio/web/components/MissingDmsPanel/DmBubble.tsx +38 -0
- package/studio/web/components/MissingDmsPanel/ReplyComposer.tsx +63 -0
- package/studio/web/components/MissingDmsPanel/index.tsx +98 -0
- package/studio/web/components/NotFound.tsx +48 -0
- package/studio/web/components/Omni/OmniAvatarPicker.tsx +92 -0
- package/studio/web/components/Omni/OmniCards.tsx +202 -0
- package/studio/web/components/Omni/OmniGlow.tsx +183 -0
- package/studio/web/components/Omni/OmniHistory.tsx +119 -0
- package/studio/web/components/Omni/OmniHotword.tsx +40 -0
- package/studio/web/components/Omni/OmniMicSelect.tsx +92 -0
- package/studio/web/components/Omni/OmniVoiceSample.tsx +81 -0
- package/studio/web/components/Omni/OmniWidget.tsx +743 -0
- package/studio/web/components/Omni/PendingActions.tsx +200 -0
- package/studio/web/components/Omni/Transcript.tsx +127 -0
- package/studio/web/components/OmnichatAccountStatus.tsx +87 -0
- package/studio/web/components/OmnichatRulePanel/RuleConfig.tsx +150 -0
- package/studio/web/components/OmnichatRulePanel/RuleDryRun.tsx +15 -0
- package/studio/web/components/OmnichatRulePanel/RuleEnableConfirm.tsx +42 -0
- package/studio/web/components/OmnichatRulePanel/RuleSkeleton.tsx +18 -0
- package/studio/web/components/OmnichatRulePanel/RuleStatus.tsx +55 -0
- package/studio/web/components/OmnichatRulePanel/index.tsx +115 -0
- package/studio/web/components/OmnichatRulePanel/rule-steps.ts +67 -0
- package/studio/web/components/OmnichatRulePanel/steps/MessageStep.tsx +91 -0
- package/studio/web/components/OmnichatRulePanel/steps/RepliesStep.tsx +201 -0
- package/studio/web/components/OmnichatRulePanel/steps/TriggerStep.tsx +76 -0
- package/studio/web/components/OmnichatRulePanel/steps/types.ts +11 -0
- package/studio/web/components/Palette.tsx +17 -0
- package/studio/web/components/PlatformCard.tsx +109 -0
- package/studio/web/components/PlatformIcon.tsx +19 -0
- package/studio/web/components/ProviderCard.tsx +80 -0
- package/studio/web/components/ProviderDetail.tsx +367 -0
- package/studio/web/components/ProviderLogo.tsx +20 -0
- package/studio/web/components/QueuePanel.tsx +77 -0
- package/studio/web/components/ReferenceActions.tsx +89 -0
- package/studio/web/components/ReferencePicker.tsx +136 -0
- package/studio/web/components/ResultMessage.tsx +7 -0
- package/studio/web/components/RuleForm.tsx +138 -0
- package/studio/web/components/RuleLog.tsx +151 -0
- package/studio/web/components/RunningTask.tsx +23 -0
- package/studio/web/components/SampleList.tsx +55 -0
- package/studio/web/components/SessionPanel.tsx +352 -0
- package/studio/web/components/SettingRow.tsx +14 -0
- package/studio/web/components/SettingsCategorySkeleton.tsx +25 -0
- package/studio/web/components/SidePanel.tsx +77 -0
- package/studio/web/components/Sidebar.tsx +289 -0
- package/studio/web/components/StageStepper.tsx +87 -0
- package/studio/web/components/StudioOffline.tsx +80 -0
- package/studio/web/components/TaskName.tsx +17 -0
- package/studio/web/components/TopBanners.tsx +30 -0
- package/studio/web/components/VideoOmnichatPanel.tsx +287 -0
- package/studio/web/components/VoiceAvatar.tsx +33 -0
- package/studio/web/components/VoiceCarousel.tsx +196 -0
- package/studio/web/components/VoiceCategory.tsx +9 -0
- package/studio/web/components/VoiceModal.tsx +39 -0
- package/studio/web/components/VoiceProfileCard.tsx +75 -0
- package/studio/web/components/VoiceProfilePicker.tsx +107 -0
- package/studio/web/components/VoiceProfilesSettings.tsx +150 -0
- package/studio/web/components/VoiceProviderCard.tsx +118 -0
- package/studio/web/components/VoiceProvidersCard.tsx +26 -0
- package/studio/web/components/WaitList.tsx +21 -0
- package/studio/web/components/icons.tsx +247 -0
- package/studio/web/components/ui/accordion.tsx +47 -0
- package/studio/web/components/ui/badge.tsx +18 -0
- package/studio/web/components/ui/calendar.tsx +43 -0
- package/studio/web/components/ui/chart.tsx +229 -0
- package/studio/web/components/ui/checkbox.tsx +26 -0
- package/studio/web/components/ui/cx.ts +2 -0
- package/studio/web/components/ui/date-time-picker.tsx +84 -0
- package/studio/web/components/ui/panel.tsx +23 -0
- package/studio/web/components/ui/picker.tsx +58 -0
- package/studio/web/components/ui/popover.tsx +24 -0
- package/studio/web/components/ui/select.tsx +89 -0
- package/studio/web/components/ui/skeleton.tsx +10 -0
- package/studio/web/components/ui/slider.tsx +68 -0
- package/studio/web/components/ui/switch.tsx +13 -0
- package/studio/web/components/ui/tooltip.test.tsx +30 -0
- package/studio/web/components/ui/tooltip.tsx +59 -0
- package/studio/web/hooks/useAccounts.ts +27 -0
- package/studio/web/hooks/useAdmin.ts +12 -0
- package/studio/web/hooks/useAnalytics.ts +21 -0
- package/studio/web/hooks/useAvatarAudioReactive.ts +87 -0
- package/studio/web/hooks/useBrowserConnect.ts +48 -0
- package/studio/web/hooks/useClonePlan.ts +14 -0
- package/studio/web/hooks/useConnected.ts +7 -0
- package/studio/web/hooks/useLiveQuery.ts +29 -0
- package/studio/web/hooks/useMenuCollapsed.ts +32 -0
- package/studio/web/hooks/useMicDevices.ts +53 -0
- package/studio/web/hooks/useMissingDms.ts +211 -0
- package/studio/web/hooks/useMissingSetupSteps.ts +26 -0
- package/studio/web/hooks/useNow.ts +11 -0
- package/studio/web/hooks/useOmniAgent.ts +278 -0
- package/studio/web/hooks/useOmniClaude.ts +124 -0
- package/studio/web/hooks/useOmniDock.ts +142 -0
- package/studio/web/hooks/useOmniGreeting.ts +60 -0
- package/studio/web/hooks/useOmniHotword.ts +128 -0
- package/studio/web/hooks/useOmnichat.ts +26 -0
- package/studio/web/hooks/useOnboarding.ts +27 -0
- package/studio/web/hooks/usePost.ts +23 -0
- package/studio/web/hooks/useQueue.ts +10 -0
- package/studio/web/hooks/useReferences.ts +20 -0
- package/studio/web/hooks/useRuleEditor.ts +101 -0
- package/studio/web/hooks/useRunner.ts +24 -0
- package/studio/web/hooks/useSaveAction.ts +23 -0
- package/studio/web/hooks/useSchedule.ts +11 -0
- package/studio/web/hooks/useServices.ts +10 -0
- package/studio/web/hooks/useSessions.ts +15 -0
- package/studio/web/hooks/useSettings.ts +11 -0
- package/studio/web/hooks/useSettingsSection.ts +30 -0
- package/studio/web/hooks/useSidePanel.ts +23 -0
- package/studio/web/hooks/useSound.ts +30 -0
- package/studio/web/hooks/useUsage.ts +11 -0
- package/studio/web/hooks/useVideoVoice.ts +36 -0
- package/studio/web/hooks/useVideos.ts +21 -0
- package/studio/web/hooks/useVoiceProfilePreview.ts +52 -0
- package/studio/web/hooks/useVoiceProfiles.ts +7 -0
- package/studio/web/hooks/useVoiceRunning.ts +10 -0
- package/studio/web/hooks/useVoiceStudioClosed.ts +8 -0
- package/studio/web/index.html +19 -0
- package/studio/web/lib/agent.ts +7 -0
- package/studio/web/lib/alerts.ts +210 -0
- package/studio/web/lib/analytics-metrics.ts +351 -0
- package/studio/web/lib/api.ts +70 -0
- package/studio/web/lib/audio.ts +39 -0
- package/studio/web/lib/avatars.ts +41 -0
- package/studio/web/lib/calendar.ts +218 -0
- package/studio/web/lib/caption-position.ts +249 -0
- package/studio/web/lib/carousel.ts +24 -0
- package/studio/web/lib/chime.ts +42 -0
- package/studio/web/lib/clone-voice.ts +55 -0
- package/studio/web/lib/export.ts +11 -0
- package/studio/web/lib/files.ts +8 -0
- package/studio/web/lib/format.ts +93 -0
- package/studio/web/lib/media.ts +29 -0
- package/studio/web/lib/mic-device.ts +72 -0
- package/studio/web/lib/missing-dms.ts +70 -0
- package/studio/web/lib/omni-cards.ts +42 -0
- package/studio/web/lib/omni-cascade.ts +1067 -0
- package/studio/web/lib/omni-greeting-audio.ts +24 -0
- package/studio/web/lib/omni-hotword.ts +231 -0
- package/studio/web/lib/omni-panel.ts +67 -0
- package/studio/web/lib/omni-realtime.ts +811 -0
- package/studio/web/lib/omni-ui.ts +402 -0
- package/studio/web/lib/omni-wait.ts +174 -0
- package/studio/web/lib/omnichat-api.ts +44 -0
- package/studio/web/lib/orb.ts +270 -0
- package/studio/web/lib/pcm-recorder.ts +115 -0
- package/studio/web/lib/platforms.ts +17 -0
- package/studio/web/lib/providers.ts +27 -0
- package/studio/web/lib/publish-draft.ts +52 -0
- package/studio/web/lib/publish-settings.ts +81 -0
- package/studio/web/lib/query-client.ts +122 -0
- package/studio/web/lib/references.ts +13 -0
- package/studio/web/lib/services.ts +40 -0
- package/studio/web/lib/sessions.ts +103 -0
- package/studio/web/lib/settings-categories.ts +58 -0
- package/studio/web/lib/sound-audio.ts +33 -0
- package/studio/web/lib/sound-timeline.ts +291 -0
- package/studio/web/lib/sse.ts +86 -0
- package/studio/web/lib/stage-history.ts +141 -0
- package/studio/web/lib/stages.ts +344 -0
- package/studio/web/lib/studio-offline.ts +60 -0
- package/studio/web/lib/upload.ts +24 -0
- package/studio/web/lib/video-tabs.ts +118 -0
- package/studio/web/lib/voice-profile-draft.ts +34 -0
- package/studio/web/lib/voice-profiles.ts +3 -0
- package/studio/web/main.tsx +14 -0
- package/studio/web/pages/AdminPage/index.tsx +123 -0
- package/studio/web/pages/AgentPage/components/Measurements.tsx +102 -0
- package/studio/web/pages/AgentPage/index.tsx +28 -0
- package/studio/web/pages/AnalyticsPage/components/About.tsx +52 -0
- package/studio/web/pages/AnalyticsPage/components/ChannelCards.tsx +106 -0
- package/studio/web/pages/AnalyticsPage/components/ChannelView.tsx +137 -0
- package/studio/web/pages/AnalyticsPage/components/CollectionStatus.tsx +46 -0
- package/studio/web/pages/AnalyticsPage/components/Comparison.tsx +68 -0
- package/studio/web/pages/AnalyticsPage/components/Diagnosis.tsx +50 -0
- package/studio/web/pages/AnalyticsPage/components/Highlights.tsx +49 -0
- package/studio/web/pages/AnalyticsPage/components/Hint.tsx +11 -0
- package/studio/web/pages/AnalyticsPage/components/HookVsBody.tsx +100 -0
- package/studio/web/pages/AnalyticsPage/components/HourlyWave.tsx +133 -0
- package/studio/web/pages/AnalyticsPage/components/Insights.tsx +70 -0
- package/studio/web/pages/AnalyticsPage/components/MetricCard.tsx +46 -0
- package/studio/web/pages/AnalyticsPage/components/PlanSection.tsx +40 -0
- package/studio/web/pages/AnalyticsPage/components/ProgressionChart.tsx +155 -0
- package/studio/web/pages/AnalyticsPage/components/ReelBarsChart.tsx +154 -0
- package/studio/web/pages/AnalyticsPage/components/ReelThumb.tsx +19 -0
- package/studio/web/pages/AnalyticsPage/components/ReelView.tsx +290 -0
- package/studio/web/pages/AnalyticsPage/components/ReelsTable.tsx +269 -0
- package/studio/web/pages/AnalyticsPage/components/RequestWithFocus.tsx +38 -0
- package/studio/web/pages/AnalyticsPage/components/SegmentedControl.tsx +35 -0
- package/studio/web/pages/AnalyticsPage/components/VsMedian.tsx +31 -0
- package/studio/web/pages/AnalyticsPage/index.tsx +17 -0
- package/studio/web/pages/GettingStartedPage/index.tsx +174 -0
- package/studio/web/pages/NewVideoPage/components/DeliverablesPicker.tsx +62 -0
- package/studio/web/pages/NewVideoPage/components/FormatPicker.tsx +33 -0
- package/studio/web/pages/NewVideoPage/index.tsx +133 -0
- package/studio/web/pages/NotFoundPage/index.tsx +9 -0
- package/studio/web/pages/OmnichatPage/components/NewFromLink.tsx +59 -0
- package/studio/web/pages/OmnichatPage/components/RuleListItem.tsx +64 -0
- package/studio/web/pages/OmnichatPage/components/RulePreview.tsx +14 -0
- package/studio/web/pages/OmnichatPage/components/RuleView.tsx +88 -0
- package/studio/web/pages/OmnichatPage/index.tsx +153 -0
- package/studio/web/pages/QueuePage/index.tsx +22 -0
- package/studio/web/pages/ReferencePage/components/ReferenceTexts.tsx +131 -0
- package/studio/web/pages/ReferencePage/index.tsx +216 -0
- package/studio/web/pages/ReferencesPage/components/NewReferenceForm.tsx +150 -0
- package/studio/web/pages/ReferencesPage/components/ReferenceCard.tsx +42 -0
- package/studio/web/pages/ReferencesPage/components/ReferenceGridSkeleton.tsx +31 -0
- package/studio/web/pages/ReferencesPage/index.tsx +67 -0
- package/studio/web/pages/SchedulePage/components/CalendarSkeleton.tsx +18 -0
- package/studio/web/pages/SchedulePage/components/DayView.tsx +177 -0
- package/studio/web/pages/SchedulePage/components/HourPicker.tsx +103 -0
- package/studio/web/pages/SchedulePage/components/MonthDayCell.tsx +111 -0
- package/studio/web/pages/SchedulePage/components/MonthView.tsx +47 -0
- package/studio/web/pages/SchedulePage/components/PlatformIcons.tsx +12 -0
- package/studio/web/pages/SchedulePage/components/PostThumb.tsx +15 -0
- package/studio/web/pages/SchedulePage/components/WeekColumn.tsx +75 -0
- package/studio/web/pages/SchedulePage/components/WeekView.tsx +35 -0
- package/studio/web/pages/SchedulePage/index.tsx +285 -0
- package/studio/web/pages/SettingsPage/components/AgentAccounts.tsx +263 -0
- package/studio/web/pages/SettingsPage/components/AgentCategory.tsx +20 -0
- package/studio/web/pages/SettingsPage/components/ModelPicker.tsx +49 -0
- package/studio/web/pages/SettingsPage/components/ModelsSettings.tsx +138 -0
- package/studio/web/pages/SettingsPage/components/PlatformsCategory.tsx +23 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/AccountStatus.tsx +29 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/AutoPublishPanel.tsx +90 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/BrowserConnect.tsx +62 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/CheckField.tsx +19 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/InstagramPanel.tsx +113 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/OmnichatSettingsPanel.tsx +146 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/SaveBar.tsx +33 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/SchedulePanel.tsx +132 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/SettingsCard.tsx +47 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/SettingsCardGroup.tsx +19 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/TextPanel.tsx +55 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/TiktokPanel.tsx +123 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/YoutubePanel.tsx +100 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/badges.tsx +15 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/index.tsx +40 -0
- package/studio/web/pages/SettingsPage/components/PublishingCategory/types.ts +10 -0
- package/studio/web/pages/SettingsPage/components/UsageCategory.tsx +389 -0
- package/studio/web/pages/SettingsPage/components/VoiceProvidersCategory.tsx +97 -0
- package/studio/web/pages/SettingsPage/index.tsx +85 -0
- package/studio/web/pages/VideoPage/components/AudioPlayer.tsx +113 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/AxisField.tsx +50 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionList.tsx +56 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionListItem.tsx +92 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionMargins.tsx +57 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionStyleFields.tsx +70 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/CaptionTextForm.tsx +87 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/ColorField.tsx +37 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/MarginField.tsx +59 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/NumberField.tsx +57 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/PositionControls.tsx +140 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/captionEditor.ts +215 -0
- package/studio/web/pages/VideoPage/components/CaptionPositionEditor/useCaptionPosition.ts +154 -0
- package/studio/web/pages/VideoPage/components/CarouselChangeRequest.tsx +72 -0
- package/studio/web/pages/VideoPage/components/CarouselCompositionStage.tsx +80 -0
- package/studio/web/pages/VideoPage/components/CarouselCreate.tsx +63 -0
- package/studio/web/pages/VideoPage/components/CarouselMissing.tsx +19 -0
- package/studio/web/pages/VideoPage/components/CarouselPublishStage.tsx +173 -0
- package/studio/web/pages/VideoPage/components/CarouselScriptStage.tsx +82 -0
- package/studio/web/pages/VideoPage/components/CarouselSlideCard.tsx +49 -0
- package/studio/web/pages/VideoPage/components/CarouselViewer.tsx +55 -0
- package/studio/web/pages/VideoPage/components/ChangedVoices.tsx +53 -0
- package/studio/web/pages/VideoPage/components/CompositionStage.tsx +78 -0
- package/studio/web/pages/VideoPage/components/CoverPicker.tsx +32 -0
- package/studio/web/pages/VideoPage/components/EditorStage.tsx +53 -0
- package/studio/web/pages/VideoPage/components/LineTakes.tsx +160 -0
- package/studio/web/pages/VideoPage/components/LineTextEditor.tsx +124 -0
- package/studio/web/pages/VideoPage/components/LineVoicePicker.tsx +37 -0
- package/studio/web/pages/VideoPage/components/MediaImage.tsx +25 -0
- package/studio/web/pages/VideoPage/components/MotionScriptStage.tsx +39 -0
- package/studio/web/pages/VideoPage/components/NarrationStage.tsx +70 -0
- package/studio/web/pages/VideoPage/components/PublishForm.tsx +387 -0
- package/studio/web/pages/VideoPage/components/PublishStage.tsx +76 -0
- package/studio/web/pages/VideoPage/components/PublishText.tsx +149 -0
- package/studio/web/pages/VideoPage/components/ScenesApprovalPanel.tsx +278 -0
- package/studio/web/pages/VideoPage/components/ScheduledInfo.tsx +72 -0
- package/studio/web/pages/VideoPage/components/ScriptApprovalPanel.tsx +189 -0
- package/studio/web/pages/VideoPage/components/ScriptStage.tsx +17 -0
- package/studio/web/pages/VideoPage/components/SequencePlayer.tsx +146 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/AddSound.tsx +117 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/AreaSelection.tsx +74 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/BedPanel.tsx +94 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/BedRow.tsx +45 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/CaptionOverlay.tsx +44 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/CaptionSaveBar.tsx +32 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/CaptionsPanel.tsx +22 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/ClipBlock.tsx +111 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/ClipPanel.tsx +76 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/CutsPanel.tsx +44 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/EditorTabBar.tsx +73 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/EffectChoice.tsx +46 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/EffectItem.tsx +89 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/EffectPanel.tsx +232 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/EffectsRow.tsx +21 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/Lane.tsx +39 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/MarkerRow.tsx +40 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/MuteButton.tsx +36 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/NumberInput.tsx +37 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/PlanWarnings.tsx +19 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/PlayerResizeHandle.tsx +50 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/PreviewControls.tsx +51 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/SceneRow.tsx +54 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/SettingsPanel.tsx +65 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/SoundLibrary.tsx +99 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/SoundPreview.tsx +82 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/SpeedPanel.tsx +128 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineDock.tsx +56 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineFooter.tsx +26 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineSkeleton.tsx +21 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineToolbar.tsx +160 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineTracks.tsx +121 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/TrackSidebar.tsx +30 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/VoiceRow.tsx +53 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/Waveform.tsx +97 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/clipActions.ts +50 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/effectActions.ts +161 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/index.tsx +161 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/timelineGeometry.ts +45 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/types.ts +43 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/useAutosave.ts +107 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/useEditorShortcuts.ts +168 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/useFitHeight.ts +40 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/useFollowPlayhead.ts +21 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/useListenMix.ts +43 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/usePlayback.ts +231 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/usePlayerWidth.ts +27 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/useSoundData.ts +124 -0
- package/studio/web/pages/VideoPage/components/SoundTimeline/useSoundTimeline.ts +511 -0
- package/studio/web/pages/VideoPage/components/StageDrawer/CompareVersions.tsx +111 -0
- package/studio/web/pages/VideoPage/components/StageDrawer/VersionCard.tsx +81 -0
- package/studio/web/pages/VideoPage/components/StageDrawer/VersionMedia.tsx +24 -0
- package/studio/web/pages/VideoPage/components/StageDrawer/VersionText.tsx +15 -0
- package/studio/web/pages/VideoPage/components/StageDrawer/index.tsx +109 -0
- package/studio/web/pages/VideoPage/components/StageProcess.tsx +126 -0
- package/studio/web/pages/VideoPage/components/StageResult.tsx +69 -0
- package/studio/web/pages/VideoPage/components/SwapReference.tsx +92 -0
- package/studio/web/pages/VideoPage/components/ThumbnailPanel.tsx +252 -0
- package/studio/web/pages/VideoPage/components/TimingPanel.tsx +89 -0
- package/studio/web/pages/VideoPage/components/VideoPlayer.tsx +18 -0
- package/studio/web/pages/VideoPage/components/VideoSkeleton.tsx +50 -0
- package/studio/web/pages/VideoPage/components/VideoVoiceInfo.tsx +33 -0
- package/studio/web/pages/VideoPage/components/VideoVoicePicker.tsx +165 -0
- package/studio/web/pages/VideoPage/components/VoicePauseBanner.tsx +56 -0
- package/studio/web/pages/VideoPage/components/WithLogo.tsx +10 -0
- package/studio/web/pages/VideoPage/index.tsx +295 -0
- package/studio/web/pages/VideosPage/components/PublishedOn.tsx +85 -0
- package/studio/web/pages/VideosPage/components/ServicesPanel.tsx +81 -0
- package/studio/web/pages/VideosPage/components/SessionsPanel.tsx +62 -0
- package/studio/web/pages/VideosPage/components/VideoListSkeleton.tsx +25 -0
- package/studio/web/pages/VideosPage/components/VideoRow.tsx +122 -0
- package/studio/web/pages/VideosPage/index.tsx +134 -0
- package/studio/web/pages/VoicePage/index.tsx +28 -0
- package/studio/web/router.tsx +201 -0
- package/studio/web/styles/base/elements.css +55 -0
- package/studio/web/styles/base/utilities.css +25 -0
- package/studio/web/styles/components/badge.css +33 -0
- package/studio/web/styles/components/claude-running.css +27 -0
- package/studio/web/styles/components/claude-session.css +212 -0
- package/studio/web/styles/components/claude-walking.css +92 -0
- package/studio/web/styles/components/clone-voice-save.css +136 -0
- package/studio/web/styles/components/clone-voice.css +379 -0
- package/studio/web/styles/components/controls.css +70 -0
- package/studio/web/styles/components/data-and-image.css +54 -0
- package/studio/web/styles/components/forms.css +132 -0
- package/studio/web/styles/components/human-banner.css +99 -0
- package/studio/web/styles/components/lightbox.css +50 -0
- package/studio/web/styles/components/markdown.css +68 -0
- package/studio/web/styles/components/modal.css +70 -0
- package/studio/web/styles/components/omni-cards.css +105 -0
- package/studio/web/styles/components/omni.css +859 -0
- package/studio/web/styles/components/omnichat.css +538 -0
- package/studio/web/styles/components/panel.css +115 -0
- package/studio/web/styles/components/platform-card.css +140 -0
- package/studio/web/styles/components/provider-card.css +132 -0
- package/studio/web/styles/components/queue.css +185 -0
- package/studio/web/styles/components/reference-actions.css +133 -0
- package/studio/web/styles/components/reference-picker.css +146 -0
- package/studio/web/styles/components/results-drawer.css +224 -0
- package/studio/web/styles/components/segmented.css +115 -0
- package/studio/web/styles/components/side-panel-tab.css +23 -0
- package/studio/web/styles/components/status-signals.css +66 -0
- package/studio/web/styles/components/stepper.css +208 -0
- package/studio/web/styles/components/table.css +19 -0
- package/studio/web/styles/components/tabs.css +24 -0
- package/studio/web/styles/components/ui/accordion.css +71 -0
- package/studio/web/styles/components/ui/chart.css +162 -0
- package/studio/web/styles/components/ui/checkbox.css +37 -0
- package/studio/web/styles/components/ui/date-picker.css +153 -0
- package/studio/web/styles/components/ui/select.css +110 -0
- package/studio/web/styles/components/ui/skeleton.css +25 -0
- package/studio/web/styles/components/ui/slider.css +81 -0
- package/studio/web/styles/components/ui/switch.css +41 -0
- package/studio/web/styles/components/ui/tooltip.css +24 -0
- package/studio/web/styles/components/voice-carousel.css +255 -0
- package/studio/web/styles/components/voice-editor.css +179 -0
- package/studio/web/styles/components/voice-grid.css +56 -0
- package/studio/web/styles/components/voice-profiles.css +192 -0
- package/studio/web/styles/design-system.md +136 -0
- package/studio/web/styles/index.css +116 -0
- package/studio/web/styles/layout/page.css +41 -0
- package/studio/web/styles/layout/sidebar-groups.css +39 -0
- package/studio/web/styles/layout/sidebar.css +111 -0
- package/studio/web/styles/pages/agent.css +26 -0
- package/studio/web/styles/pages/analytics/dashboard.css +614 -0
- package/studio/web/styles/pages/analytics/insights.css +48 -0
- package/studio/web/styles/pages/getting-started.css +166 -0
- package/studio/web/styles/pages/new-video/form.css +32 -0
- package/studio/web/styles/pages/not-found.css +59 -0
- package/studio/web/styles/pages/references.css +204 -0
- package/studio/web/styles/pages/schedule/calendar.css +541 -0
- package/studio/web/styles/pages/schedule/chip-states.css +60 -0
- package/studio/web/styles/pages/settings/models.css +72 -0
- package/studio/web/styles/pages/settings/shell.css +361 -0
- package/studio/web/styles/pages/settings/usage.css +63 -0
- package/studio/web/styles/pages/studio-offline.css +105 -0
- package/studio/web/styles/pages/video/caption-controls.css +194 -0
- package/studio/web/styles/pages/video/captions-grid.css +70 -0
- package/studio/web/styles/pages/video/captions.css +79 -0
- package/studio/web/styles/pages/video/editor-chat.css +103 -0
- package/studio/web/styles/pages/video/export.css +50 -0
- package/studio/web/styles/pages/video/frames.css +29 -0
- package/studio/web/styles/pages/video/fullscreen-stage.css +400 -0
- package/studio/web/styles/pages/video/instagram-carousel.css +309 -0
- package/studio/web/styles/pages/video/layout.css +285 -0
- package/studio/web/styles/pages/video/narration.css +138 -0
- package/studio/web/styles/pages/video/preview-overview.css +11 -0
- package/studio/web/styles/pages/video/processing-notice.css +34 -0
- package/studio/web/styles/pages/video/publish-when.css +76 -0
- package/studio/web/styles/pages/video/publish.css +97 -0
- package/studio/web/styles/pages/video/result.css +96 -0
- package/studio/web/styles/pages/video/scenes.css +167 -0
- package/studio/web/styles/pages/video/sound-timeline.css +672 -0
- package/studio/web/styles/pages/video/sound-toolbar.css +149 -0
- package/studio/web/styles/pages/video/take-player.css +100 -0
- package/studio/web/styles/pages/video/thumbnail.css +157 -0
- package/studio/web/styles/pages/video/timeline.css +117 -0
- package/studio/web/styles/pages/video/voice-picker.css +14 -0
- package/studio/web/styles/pages/video-list/active-row.css +27 -0
- package/studio/web/styles/pages/video-list/card-link.css +49 -0
- package/studio/web/styles/pages/video-list/list.css +86 -0
- package/studio/web/styles/theme/identity/details.css +204 -0
- package/studio/web/styles/theme/identity/shell.css +249 -0
- package/studio/web/styles/theme/identity/surfaces.css +183 -0
- package/studio/web/styles/theme/identity/titles-and-buttons.css +120 -0
- package/studio/web/styles/theme/no-borders/blocks.css +208 -0
- package/studio/web/styles/theme/no-borders/controls.css +256 -0
- package/studio/web/styles/tokens.css +245 -0
- package/studio/web/types/api.ts +2 -0
- package/studio/web/types/assets.d.ts +9 -0
- package/templates/brief.md +27 -0
- package/templates/captions.html +204 -0
- package/templates/carousel-composition.md +47 -0
- package/templates/carousel-script.md +60 -0
- package/templates/components/voiceavatar/README.md +87 -0
- package/templates/components/voiceavatar/demo.html +50 -0
- package/templates/components/voiceavatar/voiceavatar.js +415 -0
- package/templates/motion.md +80 -0
- package/templates/playbook.md +43 -0
- package/templates/reference.md +123 -0
- package/templates/scene.html +112 -0
- package/templates/scenes.example.json +96 -0
- package/templates/script.md +63 -0
- package/templates/slide.html +71 -0
- package/templates/wireframe.html +91 -0
- package/tools/analysis.mjs +300 -0
- package/tools/approval.mjs +442 -0
- package/tools/assemble.mjs +942 -0
- package/tools/build-motion.mjs +437 -0
- package/tools/captions.mjs +246 -0
- package/tools/carousel.mjs +558 -0
- package/tools/compose.mjs +307 -0
- package/tools/cuts.mjs +74 -0
- package/tools/editor.mjs +419 -0
- package/tools/epidemic-capture.js +54 -0
- package/tools/fanout.mjs +69 -0
- package/tools/history.mjs +70 -0
- package/tools/history.py +61 -0
- package/tools/job-queue.mjs +180 -0
- package/tools/job_queue.py +430 -0
- package/tools/lib/agents.mjs +412 -0
- package/tools/lib/channel.mjs +399 -0
- package/tools/lib/claude-settings.mjs +67 -0
- package/tools/lib/cli.mjs +9 -0
- package/tools/lib/fanout.mjs +234 -0
- package/tools/lib/http.mjs +94 -0
- package/tools/lib/index.js +14 -0
- package/tools/lib/mcp-server.mjs +69 -0
- package/tools/lib/metrics/metrics.mjs +204 -0
- package/tools/lib/narration.mjs +15 -0
- package/tools/lib/oauth-client.mjs +295 -0
- package/tools/lib/omnichat/config.mjs +139 -0
- package/tools/lib/omnichat/errors.mjs +42 -0
- package/tools/lib/omnichat/extract.mjs +82 -0
- package/tools/lib/omnichat/gate.mjs +151 -0
- package/tools/lib/omnichat/manual.mjs +166 -0
- package/tools/lib/omnichat/match.mjs +78 -0
- package/tools/lib/omnichat/pass.mjs +393 -0
- package/tools/lib/omnichat/record.mjs +208 -0
- package/tools/lib/omnichat/text.mjs +315 -0
- package/tools/lib/omnichat/webhook.mjs +166 -0
- package/tools/lib/pairing.mjs +99 -0
- package/tools/lib/paths.mjs +41 -0
- package/tools/lib/platforms/instagram.mjs +469 -0
- package/tools/lib/platforms/tiktok.mjs +343 -0
- package/tools/lib/platforms/youtube.mjs +228 -0
- package/tools/lib/publish/publish.mjs +244 -0
- package/tools/lib/schedule/schedule.mjs +191 -0
- package/tools/lib/service.mjs +134 -0
- package/tools/lib/skill-client.mjs +126 -0
- package/tools/lib/skills-release.mjs +196 -0
- package/tools/lib/testing.mjs +52 -0
- package/tools/lib/up.mjs +187 -0
- package/tools/metrics.mjs +415 -0
- package/tools/models.mjs +134 -0
- package/tools/narrate.mjs +257 -0
- package/tools/omni.mjs +298 -0
- package/tools/omni_paths.py +12 -0
- package/tools/omnichat.mjs +1577 -0
- package/tools/omnivideo.py +1122 -0
- package/tools/package.mjs +130 -0
- package/tools/platforms.mjs +236 -0
- package/tools/premiere.mjs +533 -0
- package/tools/publish.mjs +1496 -0
- package/tools/reference.mjs +1408 -0
- package/tools/render.mjs +426 -0
- package/tools/runner.mjs +156 -0
- package/tools/setup.mjs +466 -0
- package/tools/skills-release.mjs +93 -0
- package/tools/sound.mjs +1323 -0
- package/tools/soundtrack.mjs +217 -0
- package/tools/thumbnail.mjs +271 -0
- package/tools/timing.mjs +108 -0
- package/tools/usage.py +628 -0
- package/tools/voice-envelope.mjs +185 -0
- package/tools/voice.py +448 -0
- package/tools/voice_sample.py +75 -0
- package/tools/wireframe.mjs +230 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
# Publishing to YouTube, Instagram and TikTok
|
|
2
|
+
|
|
3
|
+
The **Publicar** (Publish) button lives in the studio's Publicar stage. Each
|
|
4
|
+
platform is a card with the icon, the photo and the @ of the connected account;
|
|
5
|
+
check one, two or all three. It writes the text to
|
|
6
|
+
`videos/<slug>/publication.json` and runs `tools/publish.mjs`, which uploads the
|
|
7
|
+
MP4 from `export/assembly.json` and writes back each platform's id and link. A
|
|
8
|
+
video that is already up on a platform doesn't go up again, unless you check
|
|
9
|
+
that platform again (`--again`).
|
|
10
|
+
|
|
11
|
+
Credentials live in `.env` (outside git). Each account is set up only once, in
|
|
12
|
+
Configurações (Settings) → Plataformas (Platforms) or in the terminal.
|
|
13
|
+
|
|
14
|
+
## Title, description and post caption
|
|
15
|
+
|
|
16
|
+
They come out of the script on their own. When the video has no text yet, the
|
|
17
|
+
Publicar stage runs `node tools/publish.mjs text videos/<slug>`: Claude
|
|
18
|
+
(`claude -p`, in the studio sessions' config folder) reads `script.md` and writes
|
|
19
|
+
the title, description, post caption and tags. Without Claude, the title comes
|
|
20
|
+
from the script's heading, the description from the thesis and the caption from
|
|
21
|
+
the hook. Everything is editable in the studio, and "Escrever de novo a partir do
|
|
22
|
+
roteiro" (Rewrite from the script) (`--redo`) replaces what is there. Publishing
|
|
23
|
+
also writes the text before uploading, if the title is missing.
|
|
24
|
+
|
|
25
|
+
The **post caption** is the same on Instagram and TikTok. If empty, the title
|
|
26
|
+
plus the description is used. Each platform's footer and the fixed hashtags go
|
|
27
|
+
at the end.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
node tools/publish.mjs status # what is connected
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## YouTube
|
|
34
|
+
|
|
35
|
+
1. **Project and API.** At [console.cloud.google.com](https://console.cloud.google.com),
|
|
36
|
+
create a project (for example `omnivideo`) and enable the **YouTube Data API v3**
|
|
37
|
+
under APIs & Services → Library.
|
|
38
|
+
2. **Consent screen.** In Google Auth Platform (or APIs & Services → OAuth
|
|
39
|
+
consent screen): type **External**, app name, your email. Under Audience, set
|
|
40
|
+
the app to **In production**. In "Testing", the login expires every 7 days.
|
|
41
|
+
Since the app isn't verified, Google shows a warning at login ("Google hasn't
|
|
42
|
+
verified this app"). For your own use, click Advanced → continue.
|
|
43
|
+
3. **OAuth client.** Under Clients → Create client, type **Desktop app**. Copy
|
|
44
|
+
the ID and the secret into `.env`:
|
|
45
|
+
```
|
|
46
|
+
YOUTUBE_CLIENT_ID=…apps.googleusercontent.com
|
|
47
|
+
YOUTUBE_CLIENT_SECRET=GOCSPX-…
|
|
48
|
+
```
|
|
49
|
+
4. **Login.** `node tools/publish.mjs auth youtube`. The browser opens: pick the
|
|
50
|
+
**channel's** account and allow. The refresh token goes to `.env`
|
|
51
|
+
(`YOUTUBE_REFRESH_TOKEN`), and the command shows the channel name.
|
|
52
|
+
`--browser Dia` opens the login in Dia; `--no-open` only prints the link to
|
|
53
|
+
paste. From the studio: Configurações → Plataformas → **Conectar no Dia**
|
|
54
|
+
(Connect in Dia) or **Gerar link para copiar** (Generate a link to copy). The
|
|
55
|
+
link only works in a browser on this machine, because Google sends the login
|
|
56
|
+
back to `127.0.0.1`. It waits up to 10 min.
|
|
57
|
+
|
|
58
|
+
**Private until the audit.** New API projects can only upload videos as
|
|
59
|
+
private. Even if you ask for "Public", YouTube locks it as private. Until the
|
|
60
|
+
project is audited, publish as private and switch to public in YouTube Studio
|
|
61
|
+
(the link is in `publication.json`, at `youtube.studio`). To unlock it, request
|
|
62
|
+
the audit through the "YouTube API Services – Audit and Quota Extension" form
|
|
63
|
+
(Google answers in days or weeks). Once approved, set
|
|
64
|
+
`publish.youtube.audited: true` in the config.
|
|
65
|
+
|
|
66
|
+
**Quota.** 10,000 units per day, and each upload costs about 1,600: roughly 6
|
|
67
|
+
videos per day.
|
|
68
|
+
|
|
69
|
+
A 9:16 video up to 3 min becomes a Short on its own. Category, language and
|
|
70
|
+
"made for kids" live in `publish.youtube` in the config. If the video has
|
|
71
|
+
realistic synthetic content that needs a disclosure, use
|
|
72
|
+
`synthetic_content: true`.
|
|
73
|
+
|
|
74
|
+
## Instagram (Reels)
|
|
75
|
+
|
|
76
|
+
1. **Professional account.** In the Instagram app: Settings → Account type →
|
|
77
|
+
switch to **Creator** or **Business**. A personal account can't publish
|
|
78
|
+
through the API.
|
|
79
|
+
2. **Meta app.** At [developers.facebook.com/apps](https://developers.facebook.com/apps),
|
|
80
|
+
create an app (use case: manage messaging and content on Instagram) and add
|
|
81
|
+
the **Instagram** product → "API setup with Instagram login".
|
|
82
|
+
3. **You as a tester.** Under App roles → Roles, add your Instagram account as
|
|
83
|
+
an **Instagram tester** and accept the invite in Instagram (Settings → Apps
|
|
84
|
+
and websites → Tester invites). With the app in development mode and only
|
|
85
|
+
your account, there is no need to go through App Review.
|
|
86
|
+
4. **Token.** Under "Generate access tokens", add the account and generate the
|
|
87
|
+
token with the `instagram_business_basic` and
|
|
88
|
+
`instagram_business_content_publish` permissions (for omnichat on comments,
|
|
89
|
+
also `instagram_business_manage_comments` and
|
|
90
|
+
`instagram_business_manage_messages`: `reference/omnichat.md`). Then run
|
|
91
|
+
`node tools/publish.mjs auth instagram <token>`.
|
|
92
|
+
|
|
93
|
+
The token lasts 60 days. `publish.mjs` renews it by itself when fewer than 20
|
|
94
|
+
days are left, on every publish or `status`. If more than 60 days pass without
|
|
95
|
+
publishing, generate another one (step 4).
|
|
96
|
+
|
|
97
|
+
**How the video gets there.** With Instagram login, Meta doesn't accept the
|
|
98
|
+
file: it downloads the video from a public URL (direct upload is only for apps
|
|
99
|
+
with Facebook login). `publish.mjs` opens that URL on the spot: a server on
|
|
100
|
+
`127.0.0.1` that serves only that MP4, at a random path, behind a `cloudflared`
|
|
101
|
+
quick tunnel (`https://<random>.trycloudflare.com/<token>.mp4`). The tunnel
|
|
102
|
+
takes about 15 s to respond, stays up until Instagram finishes processing and
|
|
103
|
+
closes right after. It needs `cloudflared` installed (`brew install
|
|
104
|
+
cloudflared`).
|
|
105
|
+
|
|
106
|
+
The video goes as Reels, also to the feed (`share_to_feed`). The cover is the
|
|
107
|
+
selected thumbnail (below, **Cover**); without one, the frame at `cover_at_s`
|
|
108
|
+
seconds (`null` = Instagram's choice). The post caption is the one in the
|
|
109
|
+
"Legenda" (Caption) field (the same as TikTok's), or the title and description
|
|
110
|
+
if it is empty: up to 2,200 characters and 30 hashtags. Reels through the API
|
|
111
|
+
accept 3 s to 15 min.
|
|
112
|
+
|
|
113
|
+
## Carousel (Instagram)
|
|
114
|
+
|
|
115
|
+
`node tools/publish.mjs carousel videos/<slug> --confirm` (the button of the
|
|
116
|
+
carousel's Publicar stage in the studio does the same). It uploads
|
|
117
|
+
`carousel/export/NN.jpg` (exported on the spot if the build changed after the last
|
|
118
|
+
export) as a carousel post. Images don't go up as files either: each JPEG goes
|
|
119
|
+
through the same `cloudflared` tunnel as the Reel, becomes a child container
|
|
120
|
+
(`is_carousel_item`), and the `CAROUSEL` container joins the children with the
|
|
121
|
+
caption. The caption is `carousel/publication.json`'s (the one edited in the
|
|
122
|
+
studio) or `carousel.json`'s `caption`, with the Instagram footer and the
|
|
123
|
+
hashtags from `publish.text`. The API accepts 2 to 10 slides
|
|
124
|
+
(`carousel.slides.publish`) and images from 4:5 to 1.91:1: the app's 3:4 does not
|
|
125
|
+
go through it yet. The result (id, link, when) goes back to
|
|
126
|
+
`carousel/publication.json`, which prevents publishing twice (`--again` uploads
|
|
127
|
+
it again). `--auto` and the schedule do not publish carousels. After it goes up,
|
|
128
|
+
the carousel's omnichat is checked like the Reel's.
|
|
129
|
+
|
|
130
|
+
## TikTok
|
|
131
|
+
|
|
132
|
+
1. **App.** At [developers.tiktok.com](https://developers.tiktok.com), create an
|
|
133
|
+
app. Add the **Login Kit** (platform **Desktop**) and **Content Posting API**
|
|
134
|
+
(turn on **Direct Post**) products. Under scopes, request
|
|
135
|
+
`user.info.basic`, `user.info.profile`, `video.publish` and `video.upload`.
|
|
136
|
+
2. **Credentials and redirect.** Copy the Client key and Client secret into
|
|
137
|
+
`.env` (or into Configurações → Plataformas → TikTok):
|
|
138
|
+
```
|
|
139
|
+
TIKTOK_CLIENT_KEY=…
|
|
140
|
+
TIKTOK_CLIENT_SECRET=…
|
|
141
|
+
```
|
|
142
|
+
Under Login Kit → Redirect URI, register `http://127.0.0.1:*/callback/`: the
|
|
143
|
+
login comes back to a free port on this machine.
|
|
144
|
+
3. **You as a tester.** Until the app is approved, add your TikTok account under
|
|
145
|
+
Sandbox → Target users (or use the app in sandbox mode).
|
|
146
|
+
4. **Login.** `node tools/publish.mjs auth tiktok` (or the button in
|
|
147
|
+
Configurações). The tokens go to `.env` (`TIKTOK_ACCESS_TOKEN`,
|
|
148
|
+
`TIKTOK_REFRESH_TOKEN`…). Access lasts 24 h and renews itself on every use; the
|
|
149
|
+
login lasts a year.
|
|
150
|
+
|
|
151
|
+
**Only me until the audit.** An unaudited app can only post directly as "Only
|
|
152
|
+
me" (`SELF_ONLY`), even if you ask for something else, and only to a **private
|
|
153
|
+
account**. On a public account TikTok refuses
|
|
154
|
+
(`unaudited_client_can_only_post_to_private_accounts`) and `publish.mjs` sends
|
|
155
|
+
it as a draft to the app's inbox, where you finish the post. To unlock it,
|
|
156
|
+
request the Content Posting API audit and set `publish.tiktok.audited: true`
|
|
157
|
+
(Configurações → TikTok → App auditado (App audited)).
|
|
158
|
+
|
|
159
|
+
**Draft.** With `publish.tiktok.mode: "draft"` the video goes to the TikTok
|
|
160
|
+
app's inbox, and you finish the post there (music, cover, text). It doesn't
|
|
161
|
+
depend on the audit.
|
|
162
|
+
|
|
163
|
+
Comments, duet, stitch, the AI-generated content label (`ai_content`) and the
|
|
164
|
+
cover (`cover_at_s`) live in `publish.tiktok`. The video needs at least 3 s,
|
|
165
|
+
and the maximum duration is whatever the account allows (publish checks it
|
|
166
|
+
first).
|
|
167
|
+
|
|
168
|
+
## Cover
|
|
169
|
+
|
|
170
|
+
The cover is the thumbnail selected in the studio's Publicar stage ("Usar este
|
|
171
|
+
na publicação" (Use this one for publishing), or
|
|
172
|
+
`node tools/thumbnail.mjs videos/<slug> choose v2`), which becomes
|
|
173
|
+
`thumbnail/thumbnail.png`. `publish.mjs` reads it **at upload time**: a
|
|
174
|
+
scheduled post takes whatever is selected when the scheduler runs, and the form
|
|
175
|
+
shows which one will go. `node tools/publish.mjs cover videos/<slug>` says the
|
|
176
|
+
same in the terminal, without publishing anything.
|
|
177
|
+
|
|
178
|
+
| platform | how it goes |
|
|
179
|
+
|---|---|
|
|
180
|
+
| YouTube | `thumbnails.set` right after the upload, as a JPG up to 2 MB. The channel needs advanced features (phone verification, youtube.com/verify); without them, YouTube refuses with 403. On Shorts the API accepts it, but YouTube doesn't guarantee the cover in the Shorts feed |
|
|
181
|
+
| Instagram | `cover_url`, through the same temporary link as the video, instead of `cover_at_s` |
|
|
182
|
+
| TikTok | doesn't go: the API only accepts a frame of the video (`cover_at_s`) |
|
|
183
|
+
|
|
184
|
+
With no thumbnail selected, each platform uses its usual frame. A failing
|
|
185
|
+
cover doesn't bring the video down: it uploads (Instagram retries without the
|
|
186
|
+
cover), publish warns, and the result stores
|
|
187
|
+
`cover: { version, applied: false, error }`.
|
|
188
|
+
|
|
189
|
+
## Schedule
|
|
190
|
+
|
|
191
|
+
In the Publicar stage, choose **Agendar** (Schedule), the day and time (this
|
|
192
|
+
Mac's time), and confirm. It is the same request as the Publicar button
|
|
193
|
+
(platforms, privacy, text), stored in `publication.json` (`schedule`) to go up
|
|
194
|
+
later. While it waits, the stage shows "agendada" (scheduled) and the card with
|
|
195
|
+
the time, from where it can be cancelled. Scheduling again replaces the previous
|
|
196
|
+
schedule.
|
|
197
|
+
|
|
198
|
+
To change only the time, drag the post in the studio's **Agenda** (Schedule)
|
|
199
|
+
screen, or
|
|
200
|
+
`node tools/publish.mjs schedule videos/<slug> --reschedule --when "2026-10-15 09:30" --confirm`.
|
|
201
|
+
Platforms, privacy and text stay; the state goes back to `scheduled` and the
|
|
202
|
+
attempts restart (a schedule that failed or missed its time, once rescheduled,
|
|
203
|
+
is valid again).
|
|
204
|
+
|
|
205
|
+
What publishes on time is the **scheduler agent**: a macOS LaunchAgent
|
|
206
|
+
(`~/Library/LaunchAgents/com.omnivideo.schedule.plist`) that runs
|
|
207
|
+
`publish.mjs scheduler run` every minute, with the studio open or closed. Turn
|
|
208
|
+
it on once in Configurações → Publicação → Agenda (Settings → Publishing →
|
|
209
|
+
Schedule) (or `scheduler install`). It uses the `node` of whoever installed it:
|
|
210
|
+
if you switch node versions, turn it on again. The log is in
|
|
211
|
+
`.schedule/schedule.log`.
|
|
212
|
+
|
|
213
|
+
- **Late.** A video that couldn't go up at its time still goes up to
|
|
214
|
+
`publish.schedule.max_delay_h` (12 h) after it; past that, it is **missed** and doesn't go up.
|
|
215
|
+
- **Failure.** A platform that fails retries on its own, up to
|
|
216
|
+
`publish.schedule.attempts` times (3), every `interval_min` (10 min). Then it
|
|
217
|
+
becomes **failed**, with the reason, waiting for you to schedule again or
|
|
218
|
+
publish now. The ones already up don't go up again.
|
|
219
|
+
- **Publishing by hand** a scheduled platform removes it from the schedule.
|
|
220
|
+
- **Instagram:** the `cloudflared` tunnel opens at publishing time, so the
|
|
221
|
+
internet has to be up at that time, as with the button.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
node tools/publish.mjs schedule videos/<slug> --when "2026-10-14 18:00" --youtube --tiktok --confirm
|
|
225
|
+
node tools/publish.mjs schedule videos/<slug> --cancel
|
|
226
|
+
node tools/publish.mjs scheduler # the agent and everything scheduled
|
|
227
|
+
node tools/publish.mjs scheduler install # turns the agent on (uninstall turns it off)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### In the cloud (cloud.schedule)
|
|
231
|
+
|
|
232
|
+
With `cloud.schedule: true` in the config, the Worker in `cloud/omnichat` publishes at the time. Scheduling does here what needs this
|
|
233
|
+
machine (the text, ffprobe, the cover JPEG and the omnichat rule the Reel will have, from
|
|
234
|
+
`omnichat.mjs published --plan`), uploads the MP4 and the cover to the cloud's R2 (deleted when the job
|
|
235
|
+
ends, or by a 7-day rule) and stores the job there; `--reschedule` and `--cancel` go to the cloud.
|
|
236
|
+
|
|
237
|
+
- **One short step a minute.** YouTube uploads in one; Instagram creates the container, then looks at
|
|
238
|
+
it each minute until it is processed, then publishes (it downloads the video from the Worker's
|
|
239
|
+
`/media/<key>`); TikTok uploads, then looks each minute. That keeps each run within the Workers Free
|
|
240
|
+
plan (10 ms of CPU, 50 subrequests). A failed step retries every `interval_min`, up to `attempts`.
|
|
241
|
+
- **The minute cron reads KV first** (`schedule:next`), so the database only wakes when something is
|
|
242
|
+
due.
|
|
243
|
+
- **When the Reel is live,** the cloud turns on its omnichat rule and adds it to the metrics right away.
|
|
244
|
+
- **This Mac's agent** only reads the outcome after the time (`scheduler run`) and writes the platform
|
|
245
|
+
entries into `publication.json`, as a local run would; until it does, the studio shows "agendada".
|
|
246
|
+
- **Credentials:** `publish.mjs cloud push` sends YouTube's and TikTok's (sealed there). TikTok renews
|
|
247
|
+
its refresh token on every renewal, so while the cloud schedules, this machine takes TikTok's newest
|
|
248
|
+
tokens from the cloud before using them and sends back what it renews: one chain, never two.
|
|
249
|
+
- A schedule made before the switch stays local: `cloud push` sends the pending ones up.
|
|
250
|
+
|
|
251
|
+
## In the terminal
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
node tools/publish.mjs text videos/<slug> # title, description and post caption from the script
|
|
255
|
+
node tools/publish.mjs videos/<slug> --youtube --instagram --tiktok --confirm
|
|
256
|
+
node tools/publish.mjs videos/<slug> --youtube --privacy unlisted --confirm
|
|
257
|
+
node tools/publish.mjs videos/<slug> --tiktok --tiktok-privacy FOLLOWER_OF_CREATOR --confirm
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`--confirm` exists because publishing goes outward: Claude only runs this when
|
|
261
|
+
the user asks. Scheduling also takes `--confirm`: it is the same request, made
|
|
262
|
+
now to go up later.
|
|
263
|
+
|
|
264
|
+
## publication.json
|
|
265
|
+
|
|
266
|
+
```json
|
|
267
|
+
{
|
|
268
|
+
"title": "…", "description": "…", "caption": "", "tags": ["…"],
|
|
269
|
+
"text_generated": { "at": "…", "by": "claude" },
|
|
270
|
+
"youtube": { "id": "…", "url": "https://youtube.com/shorts/…", "studio": "…", "privacy": "private",
|
|
271
|
+
"published_at": "…", "mp4": "export/<slug>.mp4", "mp4_mtime": 0 },
|
|
272
|
+
"instagram": { "id": "…", "url": "https://www.instagram.com/reel/…", "published_at": "…", "mp4": "…", "mp4_mtime": 0 },
|
|
273
|
+
"tiktok": { "id": "…", "publish_id": "…", "url": "https://www.tiktok.com/@…/video/…", "privacy": "SELF_ONLY",
|
|
274
|
+
"published_at": "…", "mp4": "…", "mp4_mtime": 0 }
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
`caption_instagram` is the old name of `caption`: it is still read. In draft
|
|
279
|
+
mode, `tiktok` gets `"draft": true` and has no `url`. The TikTok link only
|
|
280
|
+
exists after the post becomes public and passes moderation.
|
|
281
|
+
|
|
282
|
+
When an attempt fails, the reason goes in `<platform>.last_error`. When a video
|
|
283
|
+
goes up again, the previous id goes to `<platform>.previous`.
|
|
284
|
+
|
|
285
|
+
With the Reel live, `publish.mjs` calls `omnichat.mjs published`: an omnichat
|
|
286
|
+
rule that is already enabled starts replying on it and, with
|
|
287
|
+
`omnichat.instagram.enable_on_publish`, a missing one turns on by itself
|
|
288
|
+
(`reference/omnichat.md`, On publish). An omnichat failure is a warning: it
|
|
289
|
+
doesn't bring the publication down.
|
|
290
|
+
|
|
291
|
+
When scheduled, the file gets a `schedule`, which is removed once everything is
|
|
292
|
+
up; each platform published by the scheduler stores the scheduled time in
|
|
293
|
+
`scheduled_for`:
|
|
294
|
+
|
|
295
|
+
```json
|
|
296
|
+
"schedule": {
|
|
297
|
+
"when": "2026-10-14T21:00:00.000Z", "platforms": ["youtube", "tiktok"],
|
|
298
|
+
"privacy": "private", "tiktok_privacy": "SELF_ONLY", "republish": false,
|
|
299
|
+
"state": "scheduled", "attempts": 0, "created_at": "…", "origin": "studio"
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
`state`: `scheduled` (waiting for the time or the next attempt, in
|
|
304
|
+
`next_attempt`), `publishing`, `failed` or `missed`; the reason for the last two
|
|
305
|
+
is in `last_error`.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# The `scenes.json` contract
|
|
2
|
+
|
|
3
|
+
One file per video, at `videos/<slug>/scenes.json`. It is the only source of
|
|
4
|
+
scene, beat, line, duration and position. Each field has **one** owning stage;
|
|
5
|
+
the others only read it. A full example is in `templates/scenes.example.json`.
|
|
6
|
+
|
|
7
|
+
## Root
|
|
8
|
+
|
|
9
|
+
| field | owner | what it is |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| `slug` | 0 · open | `YYYY-MM-DD-subject`, also the export name (`export/<slug>.mp4`) |
|
|
12
|
+
| `title` | 1 · script | working title |
|
|
13
|
+
| `format` | 2 · motion script | `{ aspect: "9:16" \| "16:9", w, h, fps }` |
|
|
14
|
+
| `references` | 2 · motion script | library folders (`references.dir` in the config) the style came from: `["apura-paraguai"]` |
|
|
15
|
+
| `captions_in_motion` | 2, optional | `true` when the captions are drawn by the motion itself (from `OMNIVIDEO.video`); `assemble.mjs` does not burn the captions layer. `captions.srt` is still generated |
|
|
16
|
+
| `captions` | 8 · assembly, or the studio's Legenda (Captions) stage; optional | where the burned captions appear: `{ platform, anchor, x, y, style, scenes: { <scene>: { anchor?, x?, y? } }, individual: { <line>.<n>: { anchor?, x?, y?, hidden? } }, texts: { <line>.<n>: { text, original } } }` (`hidden: true` turns that caption off: assembly does not burn it; `texts` is the text edited in the studio, already written to `captions.srt`, and `original` is what the line generated). Each level overrides the previous one; whatever is missing comes from `captions.default_position` in the config. Rules in `reference/captions.md` |
|
|
17
|
+
| `voice` | optional | voice for this video only: `provider` (`fish`, `cartesia` or `voicestudio`; the others in the config's `voice.order` stay as fallback; the studio screen writes here), `speed` (applies to all lines), `voice_profile` (the `id` of a voice in the config's `voice.profiles`: its Fish `voice_id`, its Cartesia one and its VoiceStudio profile, plus the `order` to try them in; without it `voice.default_profile` applies, and with no voice at all each provider's `voice_id` and `voice.order`; a voice that no longer exists fails Fish and Cartesia with the reason, without switching voices), and for VoiceStudio `profile`, `language`, `num_step` |
|
|
18
|
+
| `preview` | legacy | the preview a video from before 2026-10-17 had approved (stage P no longer exists): ignored |
|
|
19
|
+
| `bed` | 3, optional | track under the video (music or texture), from `<video>/sfx/`: `"name.mp3"` or `{ name, db, from, to, trim, fade, loop, duck }`. `from`/`to` in seconds of the video (default: all of it); `loop` repeats the trim (texture only). Level: `sound.bed.level_db` below the voice, ducking `sound.bed.ducking_db`. The bed is isolated: `cuts` and `speed` never cut it or change its tempo; it plays straight through on the final timeline, ducked by the voice where the voice ends up (`from`/`to` say which part of the video it covers) |
|
|
20
|
+
| `speed` | 6 · studio Editor, optional | export speed, `1` to `1.5` (always written by the editor, even at `1`). `assemble.mjs` writes the base export at 100% (the editor's picture) and a second one, `export/<slug>-speed-<pct>.mp4`, that `assembly.json` then points to: picture, voice and effects sped up (voice without changing pitch), the bed not |
|
|
21
|
+
| `cuts` | 6 · studio Editor (the Corte de área (Range cut) tool), optional | `[{ from, to }]`, in seconds of scenes.json time (the video with no cuts at all), frame-aligned and non-overlapping: ranges removed from the export. `assemble.mjs` cuts at the end, with picture, captions and sound already assembled, and joins the rest; whatever crosses a cut loses only the part inside it. Voice, timing, render and `sound/` do not change. Conversions and rules in `tools/cuts.mjs`; `assembly.json` stores the cuts the export has |
|
|
22
|
+
| `scenes` | 2 · motion script | ordered list; the order is the timeline order |
|
|
23
|
+
| `total_duration` | 5 · `omnivideo.py timing` | sum of the scene durations |
|
|
24
|
+
|
|
25
|
+
## Scene
|
|
26
|
+
|
|
27
|
+
| field | owner | what it is |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `id` | 2 | `c01`, `c02`… |
|
|
30
|
+
| `title`, `goal`, `visual`, `hero` | 2 | what the scene communicates and shows; `hero` is the single highlighted element |
|
|
31
|
+
| `min_duration` | 3 | the minimum the motion needs, a multiple of 0.6 s |
|
|
32
|
+
| `html`, `mp4` | 2 | relative paths: `motion/c01.html`, `motion/c01.mp4` |
|
|
33
|
+
| `transition` | 3, optional | how the scene enters from the previous one: `"cut"` (default) or `{ "continues": ["card", "bg"] }`, the `data-continues` elements that must not jump at the cut. `sound` in the object (with or without `continues`) puts an effect on the cut, at the instant `scene.start` (same fields as a beat's `sound`). Ignored on the first scene |
|
|
34
|
+
| `beats` | 3 (`element`, `t`, `sound`) · 4 (`enters_with`, through `narrate.mjs apply`) | see below |
|
|
35
|
+
| `lines` | 4 (`id`, `text`, through `narrate.mjs apply`) · 5 · 7 | see below |
|
|
36
|
+
| `clips` | 6 · studio Editor (Navalha (Razor), drag, delete), optional | pieces of the scene MP4: `[{ from, to, offset, speed? }]`, `from`/`to` in seconds inside the MP4 (frame-aligned), `offset` how far the piece moves from its own place (negative moves it earlier) and `speed` (0.5 to 2, absent = 1) how fast the piece plays: it lasts (to − from) / speed from the same start, and what follows stays put (the gap holds the last frame). The Razor splits a clip in two; anything not in any clip was deleted. Without `clips`, the whole MP4 in place (or shifted by the old `video_offset`, which is still read). Beat and transition effects move with the piece they fall in (a beat in a deleted piece is dropped). `assemble.mjs` builds the picture with `tools/soundtrack.mjs`: where two pieces overlap, the one that started last shows, and in a gap the picture holds the last frame. A background that moves on video time may jump where a piece was shifted |
|
|
37
|
+
| `lead_in`, `hold` | 3, optional | seconds before the first line and after the last one, for this scene only (default: the config's `timing.lead_in` and `timing.final_hold`). A sentence that continues into the next scene uses `hold: 0` here and a comma-sized `lead_in` there |
|
|
38
|
+
| `duration` | 5 · `timing` | final duration, frame-aligned: `max(end of last line + hold, min_duration)` |
|
|
39
|
+
| `start` | 5 · `timing` | second at which the scene starts on the timeline |
|
|
40
|
+
|
|
41
|
+
## Beat
|
|
42
|
+
|
|
43
|
+
| field | owner | what it is |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `element` | 3 | name of what enters; becomes the CSS variable `--b-<element>` |
|
|
46
|
+
| `t` | 3 | provisional time in seconds, used until a voice exists |
|
|
47
|
+
| `enters_with` | 4 | reference to the line: `c01f2`, `c01f2:end`, `c01f2:palavra`, `c01f2:palavra#2`, with optional `+0.3`/`-0.3`. The word is the spoken (PT) word; `:fim` is still accepted as a legacy alias of `:end` |
|
|
48
|
+
| `sound` | 3, optional | effect on the beat: a file name in the global kit (`kit/sfx/kit.json`) or in `<video>/sfx/`, captured from Epidemic and registered in `sfx/sources.json` (`"clique-seco.mp3"`), an object with adjustments, or a list of them (layers at the same instant). Fields below |
|
|
49
|
+
|
|
50
|
+
`tools/timing.mjs` → `beatTime(scene, beat)` resolves it: `enters_with` if
|
|
51
|
+
present, otherwise `t`.
|
|
52
|
+
|
|
53
|
+
### Fields of a `sound`
|
|
54
|
+
|
|
55
|
+
| field | default | what it is |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `name` | required | file in the video's `sfx/` or in the global kit (`kit/sfx/`); the video's one wins. From the kit, the role's `db` is added (`sound.roles`) |
|
|
58
|
+
| `anchor` | `"peak"` | which point of the effect lands on the instant: `"peak"` (the loudest sample) or `"start"` |
|
|
59
|
+
| `offset` | 0 | seconds after the instant (negative: before) |
|
|
60
|
+
| `db` | 0 | adjustment over the default level: `sound.level_db` below the voice's integrated loudness |
|
|
61
|
+
| `trim` | whole file | `[from, to]` in seconds inside the file; `to: null` goes to the audible tail |
|
|
62
|
+
| `fade` | `[0, 0.05]` | `[in, out]` in seconds (4 ms fade-in when the trim does not start at 0) |
|
|
63
|
+
| `dur` | — | stretches or shrinks the trim to last this long, without changing pitch (continuous motion) |
|
|
64
|
+
| `speed` | 1 | speed factor; `dur` takes precedence. Limited to 0.25× to 4× |
|
|
65
|
+
| `pitch` | 0 | semitones, without changing duration |
|
|
66
|
+
| `duck` | `sound.ducking.db` | ducking under the voice for this effect only, in dB; `false` turns it off |
|
|
67
|
+
|
|
68
|
+
Each effect becomes `sound/<id>.wav` (`tools/sound.mjs`): id `<scene>-<element>`,
|
|
69
|
+
`<scene>-transition`, and `-2`, `-3`… for layers. The WAV comes out already
|
|
70
|
+
trimmed, processed, at volume and with ducking, starting at
|
|
71
|
+
`instant + offset − anchor`. The volume is measured after processing, by
|
|
72
|
+
perceived loudness (K-weighting over the `sound.window_s` window), not by peak.
|
|
73
|
+
`sound/plan.json` stores everything, including the voice segments that drive
|
|
74
|
+
the ducking.
|
|
75
|
+
|
|
76
|
+
## Line
|
|
77
|
+
|
|
78
|
+
| field | owner | what it is |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `id` | 4 | `<scene>f<n>`: `c01f1`, `c01f2` |
|
|
81
|
+
| `text` | 4 | what the voice says and the captions show, with final spelling and punctuation |
|
|
82
|
+
| `instruct` | 4, optional | style instruction for the voice (`"animado"`, `"sussurrando"`) |
|
|
83
|
+
| `wav`, `dur`, `hash` | 5 · `voice` | generated audio, duration in seconds, hash of text + voice + config of the provider that generated it |
|
|
84
|
+
| `provider`, `provider_requested` | 5 · `voice` | who generated the line and which provider the video had at that time; different = it came from fallback. A line with no `provider` predates providers (VoiceStudio) |
|
|
85
|
+
| `voice_profile` | 5 · `voice`, optional | the `id` of the voice (profile in `voice.profiles`) that spoke the line, for the studio player. Older lines don't have it; they show no voice name |
|
|
86
|
+
| `provider_pinned` | 5 · `voice`, optional | `true` when the line was generated with a provider chosen just for it (`voice --regenerate <line> --provider <id>`, the select next to "Gerar outra fala" (Generate another take)) or when the user picked a version from another provider in the studio (`voice --use`): it is a choice, not a fallback. The general `voice` run and `--regenerate-fallback` don't redo it, and it is left out of the mixed-voices warning. It disappears when the line is generated again without a choice |
|
|
87
|
+
| `start`, `end` | 5 · `timing` | position **inside the scene**, in seconds |
|
|
88
|
+
| `clips` | 6 · studio Editor, optional | pieces of the line's WAV, like the scene's `clips` (`from`/`to` in the audio, in ms; `speed` plays the piece faster with its pitch kept, through atempo). Without `clips`, the whole line in place. Captions and ducking move with the voice piece; a range outside the clips is silent and its caption is dropped |
|
|
89
|
+
| `words` | 7 · `captions` | `[{ w, s, e }]`, time of each word **inside the line**, measured on the audio (no transcription) |
|
|
90
|
+
|
|
91
|
+
Absolute time of a word on the timeline:
|
|
92
|
+
`scene.start + line.start + word.s`.
|
|
93
|
+
|
|
94
|
+
## Invalidation
|
|
95
|
+
|
|
96
|
+
| changed | becomes invalid | who recomputes |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| `line.text` or the voice profile | `wav`, `dur` and everything that depends on timing | `voice` detects it by the hash and clears the line's `start`, `end`, `words` |
|
|
99
|
+
| any `dur` | `start`/`duration` of every scene | `timing` |
|
|
100
|
+
| a scene's `duration` | that scene's MP4 and the following MP4s, if some background moves on video time (`--scene-start`) | `build-motion.mjs --render` |
|
|
101
|
+
| `transition`, `data-continues` or `motion/src/_common.html` | the scenes on both sides of the cut | `build-motion.mjs --transitions --render` |
|
|
102
|
+
| a beat's or transition's `sound`, `bed`, the voice, or any timing | `sound/` (level and ducking depend on the voice) | `assemble.mjs` (redoes `sound/` by itself) |
|
|
103
|
+
| `captions` (position) or `motion/src/_captions.css` | the export | `assemble.mjs` |
|
|
104
|
+
| `cuts` or `speed` | the export (the background music is not cut or sped up) | `assemble.mjs` |
|
|
105
|
+
| `clips` (scene or line) | `sound/` (beats and ducking move) and the export | `assemble.mjs` |
|
|
106
|
+
| anything above | `captions.srt`, export | `captions`, `assemble.mjs` |
|
|
107
|
+
|
|
108
|
+
`omnivideo.py status` checks most of this, including whether each MP4's
|
|
109
|
+
duration matches `scene.duration`.
|