narractive 2.0.0__tar.gz

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.
Files changed (43) hide show
  1. narractive-2.0.0/LICENSE +21 -0
  2. narractive-2.0.0/MANIFEST.in +6 -0
  3. narractive-2.0.0/PKG-INFO +218 -0
  4. narractive-2.0.0/README.md +171 -0
  5. narractive-2.0.0/config.template.yaml +99 -0
  6. narractive-2.0.0/narractive.egg-info/PKG-INFO +218 -0
  7. narractive-2.0.0/narractive.egg-info/SOURCES.txt +41 -0
  8. narractive-2.0.0/narractive.egg-info/dependency_links.txt +1 -0
  9. narractive-2.0.0/narractive.egg-info/entry_points.txt +3 -0
  10. narractive-2.0.0/narractive.egg-info/requires.txt +31 -0
  11. narractive-2.0.0/narractive.egg-info/top_level.txt +1 -0
  12. narractive-2.0.0/pyproject.toml +94 -0
  13. narractive-2.0.0/requirements.txt +12 -0
  14. narractive-2.0.0/setup.cfg +4 -0
  15. narractive-2.0.0/tests/test_diagram_generator.py +57 -0
  16. narractive-2.0.0/tests/test_narrator.py +63 -0
  17. narractive-2.0.0/tests/test_obs_controller.py +35 -0
  18. narractive-2.0.0/tests/test_package.py +23 -0
  19. narractive-2.0.0/tests/test_sequences.py +153 -0
  20. narractive-2.0.0/tests/test_timeline.py +42 -0
  21. narractive-2.0.0/tests/test_video_assembler.py +34 -0
  22. narractive-2.0.0/video_automation/__init__.py +25 -0
  23. narractive-2.0.0/video_automation/__main__.py +4 -0
  24. narractive-2.0.0/video_automation/bridges/__init__.py +1 -0
  25. narractive-2.0.0/video_automation/bridges/f5_tts_bridge.py +140 -0
  26. narractive-2.0.0/video_automation/cli.py +550 -0
  27. narractive-2.0.0/video_automation/core/__init__.py +6 -0
  28. narractive-2.0.0/video_automation/core/app_automator.py +499 -0
  29. narractive-2.0.0/video_automation/core/diagram_generator.py +378 -0
  30. narractive-2.0.0/video_automation/core/frame_capturer.py +533 -0
  31. narractive-2.0.0/video_automation/core/narrator.py +287 -0
  32. narractive-2.0.0/video_automation/core/obs_controller.py +327 -0
  33. narractive-2.0.0/video_automation/core/qgis_automator.py +9 -0
  34. narractive-2.0.0/video_automation/core/timeline.py +339 -0
  35. narractive-2.0.0/video_automation/core/video_assembler.py +603 -0
  36. narractive-2.0.0/video_automation/diagrams/__init__.py +0 -0
  37. narractive-2.0.0/video_automation/diagrams/template.html +228 -0
  38. narractive-2.0.0/video_automation/scripts/__init__.py +0 -0
  39. narractive-2.0.0/video_automation/scripts/_recal_sidebar.py +34 -0
  40. narractive-2.0.0/video_automation/scripts/calibrate.py +1392 -0
  41. narractive-2.0.0/video_automation/scripts/setup_obs.py +196 -0
  42. narractive-2.0.0/video_automation/sequences/__init__.py +15 -0
  43. narractive-2.0.0/video_automation/sequences/base.py +255 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Simon Ducorneau
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ include LICENSE
2
+ include README.md
3
+ include config.template.yaml
4
+ include requirements.txt
5
+
6
+ recursive-include video_automation/diagrams *.html
@@ -0,0 +1,218 @@
1
+ Metadata-Version: 2.4
2
+ Name: narractive
3
+ Version: 2.0.0
4
+ Summary: Modular framework for automating desktop application demo video production
5
+ Author: Simon Ducorneau
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/imagodata/narractive
8
+ Project-URL: Repository, https://github.com/imagodata/narractive
9
+ Keywords: video,automation,pyautogui,obs,tts,ffmpeg,demo,screencast,narractive
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Multimedia :: Video
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: pyautogui>=0.9.54
23
+ Requires-Dist: Pillow>=10.0
24
+ Requires-Dist: pyyaml>=6.0
25
+ Requires-Dist: click>=8.1
26
+ Requires-Dist: edge-tts>=6.1.0
27
+ Requires-Dist: mutagen>=1.47.0
28
+ Provides-Extra: obs
29
+ Requires-Dist: obsws-python>=1.7.0; extra == "obs"
30
+ Provides-Extra: windows
31
+ Requires-Dist: pywin32>=306; extra == "windows"
32
+ Provides-Extra: png
33
+ Requires-Dist: playwright>=1.40; extra == "png"
34
+ Provides-Extra: elevenlabs
35
+ Requires-Dist: elevenlabs; extra == "elevenlabs"
36
+ Provides-Extra: all
37
+ Requires-Dist: obsws-python>=1.7.0; extra == "all"
38
+ Requires-Dist: pywin32>=306; extra == "all"
39
+ Requires-Dist: playwright>=1.40; extra == "all"
40
+ Provides-Extra: headless
41
+ Requires-Dist: python-xlib>=0.33; extra == "headless"
42
+ Provides-Extra: dev
43
+ Requires-Dist: pytest>=7.0; extra == "dev"
44
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
45
+ Requires-Dist: ruff>=0.4; extra == "dev"
46
+ Dynamic: license-file
47
+
48
+ # Narractive
49
+
50
+ A modular Python framework for automated video production — from narration to final cut.
51
+
52
+ Narractive orchestrates the full pipeline: UI interaction (PyAutoGUI), screen recording (OBS or headless), text-to-speech narration, Mermaid diagram generation, and FFmpeg assembly. Script your sequences, define narration cues, and let the framework produce polished demo videos hands-free.
53
+
54
+ ## Features
55
+
56
+ - **Dual recording backends**: OBS WebSocket (desktop) or headless frame capture (Docker/Xvfb)
57
+ - **Multi-engine TTS narration**: edge-tts (free), ElevenLabs (premium), F5-TTS (voice cloning)
58
+ - **Timeline-synchronized sequences**: Narration cues paired with UI actions
59
+ - **Mermaid diagram slides**: HTML + PNG generation with dark theme
60
+ - **FFmpeg post-production**: Clip concatenation, narration mixing, timecode-based assembly
61
+ - **Interactive calibration**: Record UI element positions for pixel-perfect automation
62
+ - **Docker support**: Reproducible headless production in CI/CD
63
+
64
+ ## Quick Start
65
+
66
+ ```bash
67
+ # Install
68
+ pip install -e .
69
+
70
+ # Copy and configure
71
+ cp config.template.yaml config.yaml
72
+
73
+ # Calibrate UI positions (interactive)
74
+ video-automation --calibrate --config config.yaml
75
+
76
+ # Generate narration
77
+ video-automation --narration --narrations-file narrations.yaml
78
+
79
+ # Generate diagrams
80
+ video-automation --diagrams --diagrams-module my_project.diagrams.mermaid_definitions
81
+
82
+ # Record all sequences
83
+ video-automation --all --sequences-package my_project.sequences --config config.yaml
84
+
85
+ # Or headless (Docker)
86
+ docker compose run --rm video --all --sequences-package my_project.sequences
87
+ ```
88
+
89
+ ## Architecture
90
+
91
+ ```
92
+ narractive/
93
+ ├── video_automation/ # Framework (pip-installable)
94
+ │ ├── core/ # Generic modules
95
+ │ │ ├── app_automator.py # PyAutoGUI + window control
96
+ │ │ ├── obs_controller.py # OBS WebSocket 5.x
97
+ │ │ ├── frame_capturer.py # Headless Xvfb capture
98
+ │ │ ├── narrator.py # TTS (edge-tts/ElevenLabs/F5-TTS)
99
+ │ │ ├── timeline.py # Narration-synchronized cues
100
+ │ │ ├── diagram_generator.py # Mermaid → HTML/PNG
101
+ │ │ └── video_assembler.py # FFmpeg post-production
102
+ │ ├── sequences/
103
+ │ │ └── base.py # VideoSequence + TimelineSequence
104
+ │ ├── scripts/
105
+ │ │ ├── calibrate.py # Interactive UI calibration
106
+ │ │ └── setup_obs.py # OBS auto-configuration
107
+ │ └── cli.py # Click-based CLI
108
+
109
+ ├── examples/
110
+ │ └── filtermate/ # Example project (QGIS plugin demo)
111
+ │ ├── sequences/ # 11 original + 7 v01 sequences
112
+ │ ├── diagrams/ # 20 Mermaid diagram definitions
113
+ │ ├── narrations.yaml # French narration scripts
114
+ │ └── config.yaml # Calibrated UI positions
115
+
116
+ ├── config.template.yaml # Configuration template
117
+ ├── Dockerfile # Headless Docker image
118
+ ├── docker-compose.yml
119
+ └── pyproject.toml
120
+ ```
121
+
122
+ ## Creating Sequences for Your App
123
+
124
+ ### 1. Simple sequence (manual timing)
125
+
126
+ ```python
127
+ from video_automation.sequences.base import VideoSequence
128
+
129
+ class MyIntro(VideoSequence):
130
+ name = "Introduction"
131
+ sequence_id = "seq00"
132
+ duration_estimate = 30.0
133
+ obs_scene = "Main"
134
+
135
+ def execute(self, obs, app, config):
136
+ app.focus_app()
137
+ app.click_at("my_button")
138
+ app.wait(2.0)
139
+ app.scroll_down(3)
140
+ ```
141
+
142
+ ### 2. Timeline sequence (narration-synchronized)
143
+
144
+ ```python
145
+ from video_automation.sequences.base import TimelineSequence
146
+ from video_automation.core.timeline import NarrationCue
147
+
148
+ class MyDemo(TimelineSequence):
149
+ name = "Live Demo"
150
+ sequence_id = "seq01"
151
+ duration_estimate = 60.0
152
+
153
+ def build_timeline(self, obs, app, config):
154
+ return [
155
+ NarrationCue(
156
+ text="Welcome to the demo.",
157
+ actions=lambda: app.wait(1.0),
158
+ sync="during",
159
+ ),
160
+ NarrationCue(
161
+ text="Let's open the settings.",
162
+ actions=lambda: app.click_at("settings_button"),
163
+ sync="after",
164
+ ),
165
+ ]
166
+ ```
167
+
168
+ ### 3. Register sequences
169
+
170
+ Create `my_project/sequences/__init__.py`:
171
+
172
+ ```python
173
+ from video_automation.sequences.base import VideoSequence
174
+ # Import your sequence modules here to register them
175
+ from my_project.sequences.seq00_intro import MyIntro
176
+ from my_project.sequences.seq01_demo import MyDemo
177
+
178
+ SEQUENCES = [MyIntro, MyDemo]
179
+ ```
180
+
181
+ Then run:
182
+ ```bash
183
+ video-automation --list --sequences-package my_project.sequences
184
+ video-automation --all --sequences-package my_project.sequences
185
+ ```
186
+
187
+ ## Configuration
188
+
189
+ See `config.template.yaml` for all available options. Key sections:
190
+
191
+ | Section | Purpose |
192
+ |---------|---------|
193
+ | `obs` | OBS WebSocket connection, scenes, output directory |
194
+ | `app` | Window title, panel name, calibrated UI positions |
195
+ | `timing` | Click/type/scroll delays, transition pauses |
196
+ | `diagrams` | Mermaid rendering (resolution, theme, colors) |
197
+ | `narration` | TTS engine, voice, speed, F5-TTS options |
198
+ | `capture` | Headless frame capture (FPS, resolution, display) |
199
+ | `output` | Final video encoding (resolution, fps, codec) |
200
+
201
+ ## TTS Engines
202
+
203
+ | Engine | Cost | Quality | Setup |
204
+ |--------|------|---------|-------|
205
+ | edge-tts | Free | Good | `pip install edge-tts` |
206
+ | ElevenLabs | Paid | Excellent | `pip install elevenlabs` + API key |
207
+ | F5-TTS | Free | Excellent | Conda env + GPU recommended |
208
+
209
+ ## Requirements
210
+
211
+ - Python 3.10+
212
+ - FFmpeg (for video assembly)
213
+ - OBS Studio (desktop mode) or Docker (headless mode)
214
+ - Your target application installed and running
215
+
216
+ ## License
217
+
218
+ MIT
@@ -0,0 +1,171 @@
1
+ # Narractive
2
+
3
+ A modular Python framework for automated video production — from narration to final cut.
4
+
5
+ Narractive orchestrates the full pipeline: UI interaction (PyAutoGUI), screen recording (OBS or headless), text-to-speech narration, Mermaid diagram generation, and FFmpeg assembly. Script your sequences, define narration cues, and let the framework produce polished demo videos hands-free.
6
+
7
+ ## Features
8
+
9
+ - **Dual recording backends**: OBS WebSocket (desktop) or headless frame capture (Docker/Xvfb)
10
+ - **Multi-engine TTS narration**: edge-tts (free), ElevenLabs (premium), F5-TTS (voice cloning)
11
+ - **Timeline-synchronized sequences**: Narration cues paired with UI actions
12
+ - **Mermaid diagram slides**: HTML + PNG generation with dark theme
13
+ - **FFmpeg post-production**: Clip concatenation, narration mixing, timecode-based assembly
14
+ - **Interactive calibration**: Record UI element positions for pixel-perfect automation
15
+ - **Docker support**: Reproducible headless production in CI/CD
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # Install
21
+ pip install -e .
22
+
23
+ # Copy and configure
24
+ cp config.template.yaml config.yaml
25
+
26
+ # Calibrate UI positions (interactive)
27
+ video-automation --calibrate --config config.yaml
28
+
29
+ # Generate narration
30
+ video-automation --narration --narrations-file narrations.yaml
31
+
32
+ # Generate diagrams
33
+ video-automation --diagrams --diagrams-module my_project.diagrams.mermaid_definitions
34
+
35
+ # Record all sequences
36
+ video-automation --all --sequences-package my_project.sequences --config config.yaml
37
+
38
+ # Or headless (Docker)
39
+ docker compose run --rm video --all --sequences-package my_project.sequences
40
+ ```
41
+
42
+ ## Architecture
43
+
44
+ ```
45
+ narractive/
46
+ ├── video_automation/ # Framework (pip-installable)
47
+ │ ├── core/ # Generic modules
48
+ │ │ ├── app_automator.py # PyAutoGUI + window control
49
+ │ │ ├── obs_controller.py # OBS WebSocket 5.x
50
+ │ │ ├── frame_capturer.py # Headless Xvfb capture
51
+ │ │ ├── narrator.py # TTS (edge-tts/ElevenLabs/F5-TTS)
52
+ │ │ ├── timeline.py # Narration-synchronized cues
53
+ │ │ ├── diagram_generator.py # Mermaid → HTML/PNG
54
+ │ │ └── video_assembler.py # FFmpeg post-production
55
+ │ ├── sequences/
56
+ │ │ └── base.py # VideoSequence + TimelineSequence
57
+ │ ├── scripts/
58
+ │ │ ├── calibrate.py # Interactive UI calibration
59
+ │ │ └── setup_obs.py # OBS auto-configuration
60
+ │ └── cli.py # Click-based CLI
61
+
62
+ ├── examples/
63
+ │ └── filtermate/ # Example project (QGIS plugin demo)
64
+ │ ├── sequences/ # 11 original + 7 v01 sequences
65
+ │ ├── diagrams/ # 20 Mermaid diagram definitions
66
+ │ ├── narrations.yaml # French narration scripts
67
+ │ └── config.yaml # Calibrated UI positions
68
+
69
+ ├── config.template.yaml # Configuration template
70
+ ├── Dockerfile # Headless Docker image
71
+ ├── docker-compose.yml
72
+ └── pyproject.toml
73
+ ```
74
+
75
+ ## Creating Sequences for Your App
76
+
77
+ ### 1. Simple sequence (manual timing)
78
+
79
+ ```python
80
+ from video_automation.sequences.base import VideoSequence
81
+
82
+ class MyIntro(VideoSequence):
83
+ name = "Introduction"
84
+ sequence_id = "seq00"
85
+ duration_estimate = 30.0
86
+ obs_scene = "Main"
87
+
88
+ def execute(self, obs, app, config):
89
+ app.focus_app()
90
+ app.click_at("my_button")
91
+ app.wait(2.0)
92
+ app.scroll_down(3)
93
+ ```
94
+
95
+ ### 2. Timeline sequence (narration-synchronized)
96
+
97
+ ```python
98
+ from video_automation.sequences.base import TimelineSequence
99
+ from video_automation.core.timeline import NarrationCue
100
+
101
+ class MyDemo(TimelineSequence):
102
+ name = "Live Demo"
103
+ sequence_id = "seq01"
104
+ duration_estimate = 60.0
105
+
106
+ def build_timeline(self, obs, app, config):
107
+ return [
108
+ NarrationCue(
109
+ text="Welcome to the demo.",
110
+ actions=lambda: app.wait(1.0),
111
+ sync="during",
112
+ ),
113
+ NarrationCue(
114
+ text="Let's open the settings.",
115
+ actions=lambda: app.click_at("settings_button"),
116
+ sync="after",
117
+ ),
118
+ ]
119
+ ```
120
+
121
+ ### 3. Register sequences
122
+
123
+ Create `my_project/sequences/__init__.py`:
124
+
125
+ ```python
126
+ from video_automation.sequences.base import VideoSequence
127
+ # Import your sequence modules here to register them
128
+ from my_project.sequences.seq00_intro import MyIntro
129
+ from my_project.sequences.seq01_demo import MyDemo
130
+
131
+ SEQUENCES = [MyIntro, MyDemo]
132
+ ```
133
+
134
+ Then run:
135
+ ```bash
136
+ video-automation --list --sequences-package my_project.sequences
137
+ video-automation --all --sequences-package my_project.sequences
138
+ ```
139
+
140
+ ## Configuration
141
+
142
+ See `config.template.yaml` for all available options. Key sections:
143
+
144
+ | Section | Purpose |
145
+ |---------|---------|
146
+ | `obs` | OBS WebSocket connection, scenes, output directory |
147
+ | `app` | Window title, panel name, calibrated UI positions |
148
+ | `timing` | Click/type/scroll delays, transition pauses |
149
+ | `diagrams` | Mermaid rendering (resolution, theme, colors) |
150
+ | `narration` | TTS engine, voice, speed, F5-TTS options |
151
+ | `capture` | Headless frame capture (FPS, resolution, display) |
152
+ | `output` | Final video encoding (resolution, fps, codec) |
153
+
154
+ ## TTS Engines
155
+
156
+ | Engine | Cost | Quality | Setup |
157
+ |--------|------|---------|-------|
158
+ | edge-tts | Free | Good | `pip install edge-tts` |
159
+ | ElevenLabs | Paid | Excellent | `pip install elevenlabs` + API key |
160
+ | F5-TTS | Free | Excellent | Conda env + GPU recommended |
161
+
162
+ ## Requirements
163
+
164
+ - Python 3.10+
165
+ - FFmpeg (for video assembly)
166
+ - OBS Studio (desktop mode) or Docker (headless mode)
167
+ - Your target application installed and running
168
+
169
+ ## License
170
+
171
+ MIT
@@ -0,0 +1,99 @@
1
+ # =============================================================================
2
+ # Video Automation — Configuration Template
3
+ # =============================================================================
4
+ # Copy this file to config.yaml and adjust values for your project.
5
+ # Run `video-automation --calibrate` to set UI positions interactively.
6
+
7
+ obs:
8
+ host: localhost
9
+ port: 4455
10
+ password: ''
11
+ scenes:
12
+ main: Main
13
+ app_with_panel: App + Panel
14
+ diagram_overlay: Diagram Overlay
15
+ intro_scene: Intro
16
+ outro_scene: Outro
17
+ output_dir: ~/Videos/MyProject
18
+ recording_format: mkv
19
+
20
+ app:
21
+ window_title: '' # Title (or substring) of your target application
22
+ panel_name: '' # Name of a dock panel to focus (optional)
23
+ startup_wait: 5
24
+ regions:
25
+ # ── Side panel / dock widget ──────────────────────────────────
26
+ plugin_dock:
27
+ x: 1941
28
+ y: 247
29
+ width: 610
30
+ height: 1231
31
+ # ── Main canvas / viewport ────────────────────────────────────
32
+ main_canvas:
33
+ x: 434
34
+ y: 236
35
+ width: 1500
36
+ height: 1246
37
+ # ── Application menus (example) ───────────────────────────────
38
+ # menu_extensions:
39
+ # x: 386
40
+ # y: 49
41
+ # menu_extensions_manage:
42
+ # x: 397
43
+ # y: 80
44
+ # ── Add your calibrated regions below ─────────────────────────
45
+ # my_button:
46
+ # x: 2000
47
+ # y: 500
48
+
49
+ timing:
50
+ click_delay: 0.3
51
+ type_delay: 0.05
52
+ scroll_delay: 0.2
53
+ action_pause: 1.0
54
+ transition_pause: 2.0
55
+ mouse_move_duration: 0.5
56
+
57
+ diagrams:
58
+ output_dir: output/diagrams
59
+ width: 2560
60
+ height: 1440
61
+ theme: dark
62
+ background_color: '#1a1a2e'
63
+ font_family: Segoe UI
64
+
65
+ narration:
66
+ engine: edge-tts # edge-tts | elevenlabs | f5-tts
67
+ voice: fr-FR-HenriNeural # Microsoft Neural TTS voice
68
+ output_dir: output/narration
69
+ speed: +0%
70
+ # F5-TTS options (optional):
71
+ # f5_ref_audio: output/narration/ref_voice.wav
72
+ # f5_ref_text: "Reference transcription text..."
73
+ # f5_model: F5TTS_v1_Base
74
+ # f5_speed: 1.0
75
+ # f5_conda_env: f5-tts
76
+ # f5_remove_silence: false
77
+
78
+ capture:
79
+ fps: 10
80
+ output_dir: output/captures
81
+ resolution: 2560x1440
82
+ display: ':99'
83
+ method: import # import | scrot | xdotool | ffmpeg
84
+ codec: libx264
85
+ quality: 23
86
+ format: mp4
87
+ scenes:
88
+ qgis_fullscreen: QGIS Fullscreen
89
+ qgis_with_plugin: QGIS + Plugin
90
+ diagram_overlay: Diagram Overlay
91
+ intro_scene: Intro
92
+ outro_scene: Outro
93
+
94
+ output:
95
+ final_dir: output/final
96
+ resolution: 2560x1440
97
+ fps: 30
98
+ codec: libx264
99
+ quality: '23'