1 ---
2 name: video-editing
3 description: Edit video files with FFmpeg — trim, merge, add subtitles, effects, voiceovers, and reformat.
4 ---
5
6 # Video Editing
7
8 Edit existing video files server-side using FFmpeg. This skill covers the full editing workflow: trimming, splicing, concatenating, transitions, text overlays, subtitles, audio mixing, effects, and format conversion.
9
10 ## When to Use
11
12 ### Trimming & Cutting
13
14 - "Trim this video to 0:30-1:15" / "Cut out the first 10 seconds"
15 - "Extract a clip from 2:00 to 3:30"
16
17 - "Remove the intro" / "Cut the ending"
18
19 #### Merging & Compositing
20
21 - "Merge these clips together" / "Concatenate these videos"
22 - "Put two videos side by side" / "Split screen"
23
24 - "Picture-in-picture"
25
26 ##### Text, Titles & Subtitles
27
28 - "Add subtitles" / "Add captions"
29 - "Put a title card at the beginning"
30
31 - "Add text overlay"
32
33 ###### Audio
34
35 - "Add background music" / "Mix in this audio track"
36 - "Add a voiceover" / "Narrate this video" (uses ElevenLabs)
37
38 - "Mute this video" / "Remove the audio"
39 - "Replace the audio with this track"
40
41 ###### Speed & Motion
42
43 - "Speed up this video 2x" / "Slow motion"
44 - "Make this part slow-mo"
45
46 - "Reverse this clip"
47 - "Loop this clip 3 times"
48
49 ###### Visual Effects & Fixes
50
51 - "Rotate this video 90 degrees" / "Flip horizontally"
52 - "Stabilize this shaky footage"
53
54 - "Crop out the watermark" / "Remove the watermark"
55 - "Add my logo to this video" (image overlay / branding)
56
57 - "Color correct" / "Make it brighter" / "Adjust contrast"
58
59 ###### Format & Size
60
61 - "Convert this MP4 to WebM" / "Change format"
62 - "Compress this video" / "Make this file smaller"
63
64 - "Resize to 720p" / "Downscale" / "Change resolution"
65 - "Extract the audio as MP3"
66
67 - "Create a GIF from this clip"
68 - "Make a thumbnail from this video" (frame extraction as image)
69
70 ###### Social Media & Platform
71
72 - "Make TikTok clips from this" / "Break this into Reels"
73 - "Make this vertical for Shorts"
74
75 - "Reframe for Instagram" / "LinkedIn" / "Pinterest" / "Facebook" / "Snapchat"
76 - "Convert this to square for Instagram feed"
77
78 ###### AI-Powered Analysis
79
80 - "Find the best moments" / "Auto-trim for virality"
81 - "Extract the highlights" / "Score these clips"
82
83 - "Which parts are most engaging?"
84
85 ###### Cleanup & Optimization
86
87 - "Remove dead space" / "Remove silence"
88 - "Shorten this by cutting out boring parts"
89
90 - "Tighten up this video"
91
92 ###### Chunking & Splitting
93
94 - "Split this into short clips" / "Chunk this for TikTok"
95 - "Break this talk into Reels-length videos"
96
97 - "Make 15-second clips from this"
98
99 ###### No Direction (user just uploads a video)
100
101 - Probe the file, report what it is, and ask what they want to do
102
103 ## When NOT to Use
104
105 - User wants to create an animated video from scratch using code (use the `video-js` skill instead)
106 - User wants a browser-based video editor UI (build as a `react-vite` artifact with this skill powering the backend)
107
108 ## User Interaction — ALWAYS Ask Before Acting
109
110 **When a user uploads a video without specific instructions, you MUST ask what they want to do with it.** Do NOT assume a workflow or start processing automatically.
111
112 Probe the video first (to report basic info), then ask the user what they'd like. Here's a good pattern:
113
114 1. Probe the file and tell the user what they uploaded (duration, resolution, format)
115 2. Ask what they want to do. Offer common options like:
116
117 - Trim or cut specific sections
118 - Find the best/most viral moments
119
120 - Break it into short clips for a specific platform (TikTok, Reels, Shorts, X)
121 - Remove dead space / silence
122
123 - Add text, subtitles, or a voiceover
124 - Reframe for a different aspect ratio
125
126 - Convert to a different format
127 - Something else
128
129 **When the user specifies a platform, the full pipeline includes reframing to that platform's native format.** Do not just chunk the video and leave it in the original aspect ratio. Always deliver platform-ready output — correct aspect ratio, resolution, and duration range.
130
131 ### Platform Specifications
132
133 | Platform | Aspect Ratio | Resolution | Duration Range | Ideal Length | Max File Size |
134
135 |----------|-------------|------------|---------------|-------------|--------------|
136
137 | **TikTok** | 9:16 vertical | 1080×1920 | 10–45s | 25s | 287 MB |
138
139 | **Instagram Reels** | 9:16 vertical | 1080×1920 | 10–30s | 20s | 250 MB |
140
141 | **Instagram Stories** | 9:16 vertical | 1080×1920 | 1–60s | 15s | 250 MB |
142
143 | **Instagram Feed** | 1:1 square or 4:5 portrait | 1080×1080 or 1080×1350 | 3–60s | 30s | 250 MB |
144
145 | **YouTube Shorts** | 9:16 vertical | 1080×1920 | 15–60s | 40s | 256 MB |
146
147 | **YouTube (standard)** | 16:9 landscape | 1920×1080 | any | any | 256 GB |
148
149 | **X / Twitter** | 16:9 landscape | 1280×720 | 10–45s | 25s | 512 MB |
150
151 | **X / Twitter (square)** | 1:1 square | 720×720 | 10–45s | 25s | 512 MB |
152
153 | **Facebook Reels** | 9:16 vertical | 1080×1920 | 10–30s | 20s | 250 MB |
154
155 | **Facebook Feed** | 16:9 or 1:1 | 1920×1080 or 1080×1080 | any | 15–60s | 4 GB |
156
157 | **LinkedIn** | 16:9 landscape or 1:1 | 1920×1080 or 1080×1080 | 10–60s | 30s | 5 GB |
158
159 | **Pinterest** | 9:16 or 2:3 vertical | 1080×1920 or 1000×1500 | 6–60s | 15–30s | 2 GB |
160
161 | **Snapchat Spotlight** | 9:16 vertical | 1080×1920 | 5–60s | 15–30s | 250 MB |
162
163 **When the user says a platform name, apply both the correct duration targets AND the correct aspect ratio/resolution.** For example:
164
165 - "Make TikTok clips" → chunk to 10-45s AND reframe to 9:16 (1080×1920)
166 - "Instagram feed posts" → chunk to 3-60s AND reframe to 1:1 (1080×1080) or 4:5 (1080×1350)
167
168 - "YouTube Shorts" → chunk to 15-60s AND reframe to 9:16 (1080×1920)
169 - "Clips for X" → chunk to 10-45s, keep 16:9 (1280×720)
170
171 **When the user asks for clips or chunking without specifying a platform, ask which platform they're targeting** so you can apply the right duration targets and reframing.
172
173 **When you deliver results, always present the output files** so the user can download and preview them. Never just describe what was done — show the files.
174
175 ## Environment
176
177 FFmpeg 6.1.2 is pre-installed in Replit with full codec support:
178
179 - **Video codecs:** H.264 (libx264), H.265 (libx265), VP8/VP9 (libvpx), AV1 (libaom, libsvtav1, librav1e), Theora
180 - **Audio codecs:** AAC, MP3 (libmp3lame), Opus, Vorbis, FLAC, WAV
181
182 - **Image formats:** PNG, JPEG, WebP, JPEG XL (libjxl)
183 - **Subtitle rendering:** libass (for styled subtitles), libfreetype + libfontconfig (for drawtext)
184
185 - **Filters:** All standard filters available — scale, crop, overlay, drawtext, concat, fade, crossfade, etc.
186 - **Tools:** `ffmpeg`,`ffprobe` (both available on PATH)
187
188 No additional installation is needed for FFmpeg itself.
189
190 ## Architecture Decisions
191
192 ### Script-based editing (simple tasks)
193
194 For one-off or single-operation tasks (trim a clip, convert a format, extract audio), write a Node.js script in `scripts/src/`using`fluent-ffmpeg`or direct`child_process.execFile` calls to FFmpeg.
195
196 ```bash
197
198 pnpm --filter @workspace/scripts add fluent-ffmpeg
199
200 pnpm --filter @workspace/scripts add -D @types/fluent-ffmpeg
201
202 ```
203
204 ### API-based editing (complex workflows or UI)
205
206 For multi-step editing workflows or when building a video editor UI, add routes to the API server (`artifacts/api-server/`) that accept video files, process them with FFmpeg, and return results.
207
208 ```bash
209
210 pnpm --filter @workspace/api-server add fluent-ffmpeg multer
211
212 pnpm --filter @workspace/api-server add -D @types/fluent-ffmpeg @types/multer
213
214 ```
215
216 ### Choosing the right approach
217
218 | Scenario | Approach |
219
220 |----------|----------|
221
222 | "Trim this video to 0:30-1:15" | Script in `scripts/src/` |
223
224 | "Convert this MP4 to WebM" | Script in `scripts/src/` |
225
226 | "Build me a video editor app" | React-vite artifact + API routes |
227
228 | "Add subtitles to all my videos" | Script in `scripts/src/` |
229
230 | "Merge these 5 clips with transitions" | Script in `scripts/src/` (or API if repeated) |
231
232 ## Instructions
233
234 ### 1. Probe Before Processing
235
236 Always probe the input file first to understand its properties. This prevents errors from wrong assumptions about codecs, resolution, frame rate, or duration.
237
238 ```typescript
239
240 import { execFile } from 'child_process';
241
242 import { promisify } from 'util';
243
244 const execFileAsync = promisify(execFile);
245
246 async function probeVideo(filePath: string) {
247
248 const { stdout } = await execFileAsync('ffprobe', [
249
250 '-v', 'quiet',
251
252 '-print_format', 'json',
253
254 '-show_format',
255
256 '-show_streams',
257
258 filePath
259
260 ]);
261
262 return JSON.parse(stdout);
263
264 }
265
266 ```
267
268 ### 2. Use fluent-ffmpeg for Complex Operations
269
270 fluent-ffmpeg provides a chainable API that is easier to maintain than raw command strings. Use it for multi-step operations.
271
272 ```typescript
273
274 import ffmpeg from 'fluent-ffmpeg';
275
276 function trimVideo(input: string, output: string, start: string, duration: string): Promise<void> {
277
278 return new Promise((resolve, reject) => {
279
280 ffmpeg(input)
281
282 .setStartTime(start)
283
284 .setDuration(duration)
285
286 .output(output)
287
288 .on('end', resolve)
289
290 .on('error', reject)
291
292 .run();
293
294 });
295
296 }
297
298 ```
299
300 ### 3. Use execFile for Simple One-Liners
301
302 For straightforward operations where the FFmpeg command is well-known, calling FFmpeg directly is cleaner.
303
304 ```typescript
305
306 await execFileAsync('ffmpeg', [
307
308 '-i', inputPath,
309
310 '-vf', 'scale=1280:720',
311
312 '-c:a', 'copy',
313
314 outputPath
315
316 ]);
317
318 ```
319
320 ### 4. File Management
321
322 - Store uploaded/input files in a `tmp/`or`uploads/` directory
323 - Store output files where the user can access them — either `public/` for web serving or a known output directory
324
325 - Clean up temporary files after processing
326 - For large files, stream the output rather than buffering in memory
327
328 ### 5. Progress Reporting
329
330 FFmpeg outputs progress to stderr. Parse it for progress reporting in longer operations:
331
332 ```typescript
333
334 ffmpeg(input)
335
336 .output(output)
337
338 .on('progress', (progress) => {
339
340 console.log(`Processing: ${progress.percent?.toFixed(1)}% done`);
341
342 })
343
344 .on('end', () => console.log('Done'))
345
346 .run();
347
348 ```
349
350 ### 6. Error Handling
351
352 FFmpeg errors are often cryptic. Always:
353
354 - Log the full stderr output on failure
355 - Validate input files exist before processing
356
357 - Check that output codecs are compatible with the output container
358 - Use `-y` flag to overwrite output files without prompting
359
360 ## AI-Powered Virality Scoring
361
362 Use AI vision to analyze video content and score it on viral potential. This feature has two modes depending on the workflow.
363
364 This feature requires an AI integration (OpenAI or Gemini) to be set up. Set up the AI integration following the `ai-integrations-openai`or`ai-integrations-gemini` skill before proceeding. OpenAI is preferred because gpt-5.2 handles image analysis well and is the default for most tasks. Gemini (gemini-2.5-flash) is a good alternative, especially for high-volume analysis since it supports video/image input natively.
365
366 ### Two Scoring Modes
367
368 **Mode 1: Segment scoring (find the best moments)** — For when the user says "find the best clips" or "auto-trim for virality." Detects scenes, scores small segments, and exports the top moments. Good for finding highlights in raw footage.
369
370 #### Mode 2: Clip scoring (rank ready-to-post clips)**— For when clips already exist (from chunking, manual trimming, etc.) and the user wants to know which ones to post first. Scores each complete clip with a richer evaluation including narrative arc and standalone quality.**This is the preferred mode when used with the chunking pipeline
371
372 ### Recommended Pipeline
373
374 When the user has a long video and wants social-ready clips, use this order:
375
376 ```text
377
378 Long Video → Dead Space Removal → Chunking (10-60s clips) → Clip-Level Scoring → Reframe for Platform → Output
379
380 ```
381
382 This way the AI scores complete, self-contained clips rather than tiny scene fragments. The scores are much more meaningful because each clip is what will actually be posted.
383
384 For "find the best moment in this video" requests (no chunking), use the original segment-level pipeline:
385
386 ```text
387
388 Video → Scene Detection → Frame Extraction → Segment Scoring → Rank → Trim/Export
389
390 ```
391
392 ### When the user asks for auto-trim, ask which output they want
393
394 Present these three options and let the user choose each time. Do not assume a default:
395
396 - **Best clip** — The single highest-scoring segment/clip, trimmed and exported
397 - **Multiple clips** — Several top segments/clips exported as separate files, ranked by score
398
399 - **Highlight reel** — Top moments stitched together with crossfade transitions into one video
400
401 ### Scoring Criteria
402
403 **Segment scoring** evaluates: visual dynamism, emotional impact, hook potential, pacing/energy, uniqueness, and shareability. Each factor gets a 1-10 score, weighted to produce a final virality score.
404
405 **Clip scoring** adds three additional criteria for complete clips:
406
407 - **Narrative completeness** (weight: 15%) — Does the clip tell a complete micro-story? Does it have a clear beginning, middle, and end? Would a viewer feel satisfied or intrigued, not confused?
408 - **Hook-to-payoff flow** (weight: 10%) — Does the clip open with something that grabs attention and deliver on that promise? Or does it start slow and meander?
409
410 - **Standalone quality** (weight: 10%) — Would this clip make sense to someone who hasn't seen the full video? Can it be posted without context?
411
412 These three criteria reduce the weights of the original six factors proportionally so the total still sums to 100%.
413
414 ### Frame Extraction
415
416 - **Segments (2-10s):** Extract 3 frames evenly spread across the segment.
417 - **Clips (10-60s):** Extract 5-8 frames to capture the full arc. Always include the first frame (hook evaluation) and last frame (payoff evaluation).
418
419 ### Workflow
420
421 For the complete step-by-step implementation with code examples, see:
422
423 - `virality-scoring.md` — Full virality analysis pipeline, AI prompts, scoring criteria, and output assembly
424
425 ### Key Gotchas (learned from testing)
426
427 - **Scene detection:** Use `ffmpeg`with`select`+`showinfo`filters and parse stderr — the`ffprobe -f lavfi` approach doesn't work reliably in Replit.
428 - **Content safety:** OpenAI vision may reject frames from documentary/medical/news content. Always wrap AI calls in try/catch and skip failed segments gracefully.
429
430 - **Segment indexing:** Use `index: segments.length`when filtering short segments, not the loop counter`i`.
431 - **Package setup:** For scripts, install `openai`directly (`pnpm add -w openai`) and create the client with`AI_INTEGRATIONS_OPENAI_BASE_URL`/`AI_INTEGRATIONS_OPENAI_API_KEY` env vars. No need for the full workspace integration library.
432
433 - **Timeouts:** A 90-second video with ~13 segments takes 1-2 minutes for AI analysis. Warn the user and set generous timeouts.
434 - **Minimum segment duration:** Use 2.0s minimum — segments under 2 seconds waste API calls and don't produce useful scores.
435
436 - **Prefer clip-level scoring:** When the video has already been chunked, always score the chunks rather than re-running segment detection. The clips are what will actually be posted.
437
438 ## Dead Space Removal
439
440 Automatically detect and remove silence, dead air, and filler from a video to produce a tighter, more engaging cut. This is especially useful for talks, interviews, podcasts, tutorials, and raw footage.
441
442 ### How It Works
443
444 1. **Silence detection** — Use FFmpeg's `silencedetect` filter to find all silent intervals (configurable threshold and minimum duration)
445 2. **Segment extraction** — Extract all non-silent segments as individual clips
446
447 3. **Reassembly** — Concatenate the non-silent segments back together with optional brief crossfade transitions
448 4. **Optional: AI-assisted filler removal** — For more aggressive editing (removing "ums", filler words, repetitive sections), combine silence detection with AI transcription analysis
449
450 ### When the user asks to remove dead space
451
452 Ask these clarifying questions if not clear from context:
453
454 - **How aggressive?** Light (remove only true silence, > 1s gaps) vs. aggressive (remove short pauses > 0.3s for a fast-paced edit)
455 - **Transitions?** Hard cuts between segments (default) or brief crossfades (0.2-0.5s) for smoother flow
456
457 ### Configuration
458
459 | Preset | Silence Threshold | Min Silence Duration | Use Case |
460
461 |--------|------------------|---------------------|----------|
462
463 | Light | -40dB | 1.0s | Talks, interviews — remove obvious dead air |
464
465 | Medium | -35dB | 0.5s | Podcasts, tutorials — tighter pacing |
466
467 | Aggressive | -30dB | 0.3s | Fast-paced edits, social media — maximum tightness |
468
469 ### Implementation
470
471 For the complete FFmpeg commands and Node.js pipeline, see:
472
473 - `dead-space-and-chunking.md` — See the "Dead Space Removal" section
474
475 ### Quick Summary
476
477 ```text
478
479 Video → Silence Detection (FFmpeg silencedetect) → Identify Non-Silent Ranges → Extract Segments → Concatenate → Output
480
481 ```
482
483 ## Social Media Chunking
484
485 Break a longer video (ad, promo, talk, presentation, livestream) into self-contained clips suitable for TikTok, Reels, and Shorts. Each clip should be 10-60 seconds and feel complete on its own.
486
487 ### How It Works (2)
488
489 1. **Scene detection + silence detection** — Find natural break points using both visual scene changes and audio silence gaps
490 2. **Smart boundary selection** — Merge adjacent segments into clips targeting 10-60 seconds, preferring to break at silence or scene changes rather than mid-sentence
491
492 3. **AI content analysis (optional)** — Score each potential clip with AI to identify which ones are worth posting, suggest captions, and recommend clip order
493 4. **Export** — Output each clip as a separate file, numbered and ranked
494
495 ### Clip Length Guidelines
496
497 | Platform | Ideal Length | Max Length | Notes |
498
499 |----------|-------------|------------|-------|
500
501 | TikTok | 15-45s | 10 min | 15-30s performs best for new accounts |
502
503 | Instagram Reels | 15-30s | 90s | Under 30s gets more reach |
504
505 | YouTube Shorts | 30-60s | 60s | Hard cap at 60 seconds |
506
507 | X / Twitter | 15-45s | 2m 20s | Shorter gets more engagement |
508
509 ### When the user asks to chunk a video
510
511 Ask which platform they're targeting (or default to TikTok at 15-45s). The chunking algorithm should:
512
513 - **Never cut mid-sentence** — Always break at silence gaps or natural pauses
514 - **Prefer scene boundaries** — Break where the visual content changes
515
516 - **Ensure each clip stands alone** — Each clip should have a clear beginning, not start mid-thought
517 - **Target the platform's sweet spot** — Not just "under 60s" but actually the ideal range for that platform
518
519 ### Implementation (2)
520
521 For the complete pipeline with code examples, see:
522
523 - `dead-space-and-chunking.md` — See the "Social Media Chunking" section
524
525 ### Quick Summary (2)
526
527 ```text
528
529 Video → Scene Detection + Silence Detection → Merge into 10-60s Clips at Natural Boundaries → (Optional) AI Scoring → Export Individual Clips
530
531 ```
532
533 ### Combining with Other Features
534
535 These features work well together in a pipeline:
536
537 ```text
538
539 Long Video → Dead Space Removal → Chunking into Clips → Virality Scoring → Reframe for TikTok → Output
540
541 ```
542
543 This takes a raw long-form video and produces polished, platform-ready social clips end to end.
544
545 ## Voiceovers with ElevenLabs
546
547 Add AI-generated voiceovers to videos using ElevenLabs text-to-speech, then mix the audio into the video with FFmpeg.
548
549 ### Prerequisites
550
551 ElevenLabs is available as a Replit integration (connector). The user needs to connect their ElevenLabs account through Replit's integration system — no manual API keys needed. Search for the integration and propose it to the user:
552
553 ```javascript
554
555 const results = await searchIntegrations("elevenlabs");
556
557 // Then propose the connector so the user can authorize
558
559 await proposeIntegration("connector:ccfg_elevenlabs_...");
560
561 ```
562
563 After authorization, use `addIntegration`to wire it to the project, then use`listConnections('elevenlabs')` in the code execution sandbox to get the credentials.
564
565 ### Workflow (2)
566
567 1. **Generate voiceover audio** — Send text to ElevenLabs TTS API, receive audio file
568 2. **Mix into video** — Use FFmpeg to add the voiceover as a new audio track, optionally ducking (lowering volume of) existing audio
569
570 ### Voiceover Modes
571
572 When the user asks for a voiceover, they may want one of these:
573
574 - **Replace audio** — Remove existing audio entirely, use only the voiceover
575 - **Mix over** — Layer voiceover on top of existing audio (with existing audio volume reduced)
576
577 - **Add as track** — Keep existing audio at full volume, add voiceover on top
578
579 Ask which mode the user prefers if not clear from context.
580
581 ### Implementation (3)
582
583 For the complete step-by-step implementation with code examples, see:
584
585 - `voiceover.md` — ElevenLabs TTS integration, voice selection, audio mixing with FFmpeg, and timed voiceover segments
586
587 ### Quick Summary (3)
588
589 ```text
590
591 Text Script → ElevenLabs TTS → Audio File → FFmpeg Mix with Video → Output
592
593 ```
594
595 Key capabilities:
596
597 - Choose from ElevenLabs' voice library or cloned voices
598 - Control voice settings (stability, similarity boost, style)
599
600 - Generate voiceover for the full video or specific time segments
601 - Duck existing audio under voiceover sections
602
603 - Support for multiple languages
604
605 ## Social Media Reframing
606
607 Automatically reframe videos for different social media platforms. Each platform has a preferred aspect ratio and resolution — this feature handles the conversion intelligently.
608
609 ### Platform Specs
610
611 | Platform | Aspect Ratio | Resolution | Notes |
612
613 |----------|-------------|------------|-------|
614
615 | YouTube | 16:9 | 1920x1080 | Standard landscape, also supports 4K (3840x2160) |
616
617 | TikTok / Reels | 9:16 | 1080x1920 | Vertical video, max 60s for Reels, 10min for TikTok |
618
619 | Instagram Feed | 1:1 | 1080x1080 | Square format |
620
621 | X / Twitter | 16:9 or 1:1 | 1280x720 or 720x720 | Supports both, 2min 20s max |
622
623 ### Reframing Strategies
624
625 When converting between aspect ratios, there are three strategies:
626
627 1. **Center crop** (default) — Crop from the center to fill the target ratio. Fast, works well for most content. May cut off edges.
628 2. **Letterbox/pillarbox** — Add black bars (or blurred background) to fit without cropping. Preserves all content but adds empty space.
629
630 3. **Blurred fill** — Use a blurred, scaled-up version of the video as the background behind the original. Looks much better than black bars, especially for vertical reframing. This is the recommended approach for going from 16:9 to 9:16.
631
632 When the user asks to reframe, ask which platform they're targeting. Use **blurred fill**by default for aspect ratio changes that would lose significant content (e.g., landscape to portrait). Use**center crop**when the content is center-focused. Use**letterbox** only if the user explicitly asks for it.
633
634 ### Implementation (4)
635
636 For the complete FFmpeg commands for each reframing strategy, see:
637
638 - `operations.md` — See the "Social Media Reframing" section
639
640 ### Multi-platform Export
641
642 When the user wants to export for multiple platforms at once, generate all versions in a batch:
643
644 ```text
645
646 Input (16:9) → YouTube (copy) + TikTok (9:16 blurred fill) + Instagram (1:1 center crop) + X (1280x720 copy)
647
648 ```
649
650 This is a common workflow — the user shoots in landscape and needs versions for every platform.
651
652 ## Common Operations Reference
653
654 For detailed FFmpeg commands and patterns for each operation type, see:
655
656 - `operations.md` — Complete command reference for all supported editing operations
657 - `virality-scoring.md` — AI-powered virality analysis and auto-trim pipeline
658
659 - `voiceover.md` — ElevenLabs voiceover generation and audio mixing
660 - `dead-space-and-chunking.md` — Dead space removal and social media chunking pipelines
661
662 ## Building a Video Editor UI
663
664 If the user wants a visual editor interface:
665
666 1. Create a `react-vite` artifact for the frontend
667 2. Add API routes to `artifacts/api-server/` for video processing
668
669 3. Use `multer` for file uploads to the API
670 4. Process videos with FFmpeg on the server
671
672 5. Return processed files for download or preview
673 6. Use the `object-storage` skill for persisting uploaded and processed files if needed
674
675 Key frontend considerations:
676
677 - Use `<video>` element for preview playback
678 - Show a timeline UI for trim/cut operations
679
680 - Display progress during processing (poll an API status endpoint or use Server-Sent Events)
681 - Provide download links for processed output
682
683 ## Tested Bugs & Caveats (Do Not Regress)
684
685 These issues were discovered during real-world testing and are documented here to prevent regressions:
686
687 - **Scene detection:** The `ffprobe -f lavfi`approach does NOT work in Replit. Use`ffmpeg`with`select='gt(scene,threshold)',showinfo`and parse`pts_time` from stderr.
688 - **Segment indexing:** Use `index: segments.length`when building segments, NOT the loop counter`i` — filtered segments cause index mismatches.
689
690 - **Content safety:** OpenAI vision may reject frames (medical/documentary content). Always wrap AI calls in try/catch and skip gracefully.
691 - **Frame extraction timestamp clamping:** Clamp the last frame timestamp to `segment.endTime - 0.1`. Without this, the last clip in a video fails because`startTime + 1.0 * duration` can exceed the actual file duration due to floating point arithmetic.
692
693 - **`silenceremove` filter:** Only strips audio silence, NOT video frames. Must use segmented extract+concat approach for proper dead space removal.
694 - **Dead space with many segments:** Videos with lots of short dialogue (50+ speaking segments) can be very slow to process with re-encoding. Use `-preset ultrafast` for testing, or skip dead space removal for dialogue-heavy content where there's little dead space anyway.
695
696 - **OpenAI for scripts:** Install with `pnpm add -w openai`, create client with`AI_INTEGRATIONS_OPENAI_BASE_URL`and`AI_INTEGRATIONS_OPENAI_API_KEY` env vars.
697 - **AI scoring duration:** A 90-second video with ~13 segments takes 1-2 minutes for AI analysis. A 3.5-minute video with 9 clips takes ~3 minutes. Always warn the user.
698
699 ## Limitations
700
701 - **No GPU acceleration** — Replit containers do not have GPU access, so hardware encoding (NVENC, VAAPI) is unavailable. Use software encoding (libx264, libx265, libvpx-vp9).
702 - **Memory and CPU** — Very large files or high-resolution encoding (4K+) may be slow or hit memory limits. For large files, prefer stream-copy (`-c copy`) where possible and avoid unnecessary re-encoding.
703
704 - **Disk space** — Video files are large. Clean up temporary files after processing. Monitor disk usage for batch operations.
705 - **No real-time preview** — FFmpeg processes offline. Users cannot preview effects in real-time during editing (unlike desktop NLEs). Generate short previews of segments instead.