A Node.js CLI tool and library for combining video clips into podcasts with smooth FFmpeg-based transitions.
- 8 transition types: dissolve, fade, wipeleft, wiperight, wipeup, wipedown, slideleft, slideright
- Video trimming: Precise start/end times per clip
- Dual-use: Standalone CLI + importable library for integration
- Flexible config: Inline arguments or JSON configuration files
- Dry-run mode: Validate without executing FFmpeg
- Auto audio concatenation: Audio streams merged automatically
- Node.js >= 18.0.0
- FFmpeg with FFprobe installed
npm install autopodOr install globally for CLI usage:
npm install -g autopodCombine two videos with a dissolve transition:
autopod -f intro.mp4 dissolve main.mp4 -o podcast.mp4import { compose } from 'autopod';
await compose({
clips: [
{ path: './intro.mp4' },
{ path: './main.mp4' }
],
transitions: [
{ type: 'dissolve', duration: 1.0 }
],
output: { path: './podcast.mp4' }
});autopod [OPTIONS]| Option | Description |
|---|---|
-f, --files <items...> |
Video clips and transitions (alternating) |
-c, --config <path> |
Path to JSON config file |
-o, --output <path> |
Output file path (default: output.mp4) |
-d, --duration <seconds> |
Default transition duration (default: 1.0) |
--verbose |
Show detailed FFmpeg progress |
--dry-run |
Validate configuration without executing |
Note: Use either --files or --config, not both.
Three clips with different transitions:
autopod -f a.mp4 dissolve b.mp4 wipeleft c.mp4 -o output.mp4Custom transition duration:
autopod -f a.mp4 fade b.mp4 -d 2 -o output.mp4Using a JSON config:
autopod -c config.json -o output.mp4Dry run validation:
autopod -f a.mp4 dissolve b.mp4 --dry-runMain composition function.
import { compose } from 'autopod';
const result = await compose({
clips: [
{ path: './intro.mp4' },
{ path: './main.mp4', trim: { start: 5, end: 30 } }
],
transitions: [
{ type: 'dissolve', duration: 1.0 }
],
output: { path: './podcast.mp4' }
}, {
dryRun: false,
verbose: true,
defaultDuration: 1.0
});
// result: { outputPath, clipCount, totalDuration }Get video metadata.
import { probeVideo } from 'autopod';
const metadata = await probeVideo('./video.mp4');
// { duration, width, height, fps, codec }Validate configuration without executing.
import { validateConfig } from 'autopod';
const errors = validateConfig(config);
if (errors.length > 0) {
console.error('Invalid config:', errors);
}import { TRANSITIONS, getTransitionTypes, isValidTransition } from 'autopod';
console.log(TRANSITIONS); // ['dissolve', 'fade', 'wipeleft', ...]
console.log(isValidTransition('dissolve')); // true{
"clips": [
{ "path": "./intro.mp4" },
{ "path": "./main.mp4", "trim": { "start": 5, "end": 120 } },
{ "path": "./outro.mp4" }
],
"transitions": [
{ "type": "dissolve", "duration": 1.0 },
{ "type": "wipeleft", "duration": 0.5 }
],
"output": {
"path": "./podcast.mp4"
}
}- Minimum 2 clips required
- Number of transitions = number of clips - 1
- Trim times in seconds (optional per clip)
- Duration optional per transition (uses default if omitted)
| Type | Description |
|---|---|
dissolve |
Smooth dissolve effect |
fade |
Fade in/out |
wipeleft |
Wipe from right to left |
wiperight |
Wipe from left to right |
wipeup |
Wipe from bottom to top |
wipedown |
Wipe from top to bottom |
slideleft |
Slide from right to left |
slideright |
Slide from left to right |
Default duration: 1.0 second
| Variable | Description |
|---|---|
FFMPEG_PATH |
Custom FFmpeg binary path |
FFPROBE_PATH |
Custom FFprobe binary path |
AUTOPOD_DEBUG=1 |
Enable verbose logging |
AUTOPOD_TEMP_DIR |
Custom temp directory |
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | User error (validation, missing file) |
| 2 | System error (FFmpeg failure) |
import {
AutoPodError,
ValidationError,
FileNotFoundError,
FFmpegError,
FFmpegNotFoundError
} from 'autopod';
try {
await compose(config);
} catch (err) {
if (err instanceof ValidationError) {
console.error('Invalid input:', err.message);
} else if (err instanceof FFmpegNotFoundError) {
console.error('FFmpeg not installed');
}
}git clone https://github.com/your-username/autopod.git
cd autopod
npm installnpm test # Run tests
npm run lint # Run ESLint
npm run format # Format with PrettierUnit tests mock FFmpeg; integration tests require FFmpeg installed.
npm test # Run all tests
npm run test:watch # Watch modeMIT