Skill: gullish42069/seamless-looper (version 1.0.1)

--- name: seamless-looper description: Create seamless looping video files with smooth crossfade transitions at the loop junction. Use when asked to loop a video, make a seamless loop, create ambient video loops, crossfade video loops, or loop background footage. Output is visual-only (no audio). Trigger phrases: "loop video", "seamless loop", "video loop", "crossfade loop", "ambient video", "background loop", "loop MP4". --- # Seamless Looper Create seamless looping versions of ambient/background videos with smooth crossfade transitions at the junction. **Limitations:** Output is visual-only (no audio). Input must be MP4. Videos under 2 seconds are skipped. ## Quick Start ```bash cd ~/.openclaw/skills/seamless-looper bash scripts/loop.sh <source_dir> <output_dir> [crossfade_seconds] ``` **Example:** ```bash bash scripts/loop.sh ~/Videos/ambient ~/Videos/looped 1 ``` - Source dir must contain `.mp4` files - Output dir created automatically - Default crossfade: 1 second ## Output Looped files saved as `<filename>_looped.mp4` in the output directory. ## How It Works 1. Takes each `.mp4` in source dir 2. Doubles the video (original + original via stream_loop) 3. Applies crossfade at the junction point (fade out tail, fade in head) 4. Outputs `<filename>_looped.mp4` — seamless loop of the original duration ## Requirements - `ffmpeg` (with libx264 and overlay filter support) - `ffprobe` (for duration detection) Install on macOS: `brew install ffmpeg` ## Tips | Use Case | Crossfade | |----------|-----------| | Fast cuts, high motion | 0.5s | | Default ambient | 1s | | Slow fades, nature footage | 2s | | Very slow drift | 3s | ## Limitations - Input must be `.mp4` - Videos <2s duration are skipped - No audio looping (visual-only output) - Output duration = 2x input duration ## File Structure ``` seamless-looper/ ├── SKILL.md ← you are here ├── scripts/ │ └── loop.sh ← main loop script └── references/ └── tips.md ← use cases + crossfade presets ```

path: references/tips.md
content: # Seamless Looper — Tips & Use Cases

## Best Crossfade Durations by Footage Type

| Footage Type | Crossfade | Why |
|---|---|---|
| Fast cuts / high motion | 0.5s | Longer causes ghosting on motion |
| Default ambient / lofi | 1s | Works for most backgrounds |
| Slow pan / nature | 2s | Smooth enough to not notice |
| Very slow drift / clouds | 3s | Seamless for slow-moving content |

## Input Requirements

- Format: `.mp4` (H.264 recommended)
- Duration: ≥2 seconds (shorter files skipped)
- Size: No hard limit, but longer = longer processing
- Audio: Not preserved in looped output (visual only)

## Common Workflows

**Batch loop all ambient videos in a folder:**
```bash
bash loop.sh ~/Downloads/ambient ~/Videos/looped 1
```

**Quick 2s crossfade for nature footage:**
```bash
bash loop.sh ./forest_footage ./output 2
```

**Preview before processing (dry run):**
```bash
for f in ~/Videos/*.mp4; do
  dur=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$f")
  echo "$(basename "$f"): ${dur}s"
done
```

## Output Notes

- Output is 2x the input duration (two copies joined at crossfade)
- File naming: `original_looped.mp4`
- CRF 18 = high quality, reasonable file size
- Preset `fast` = quick encoding

## Use Cases

- **Twitch/YouTube ambient backgrounds** — seamless 10-30min loops
- **Social media** — looped product reveal clips
- **Projection mapping** — continuous ambient backgrounds
- **Website hero video** — seamless background loops
- **Podcast video** — looped intro/outro bumper


path: scripts/loop.sh
content: #!/bin/bash
# Seamless Looper — create seamless looping videos with crossfade at junction
# Usage: bash loop.sh <source_dir> <output_dir> [crossfade_seconds]
# Requires: ffmpeg, ffprobe

set -e

if [ -z "$1" ] || [ -z "$2" ]; then
  echo "Usage: bash loop.sh <source_dir> <output_dir> [crossfade_seconds]"
  echo "Example: bash loop.sh ~/Videos/ambient ~/Videos/looped 1"
  exit 1
fi

SRC_DIR="$1"
DST_DIR="$2"
XFADE="${3:-1}"

mkdir -p "$DST_DIR"

if ! command -v ffmpeg &>/dev/null || ! command -v ffprobe &>/dev/null; then
  echo "ERROR: ffmpeg and ffprobe required. Install with: brew install ffmpeg"
  exit 1
fi

for f in "$SRC_DIR"/*.mp4; do
  if [ ! -f "$f" ]; then
    echo "No .mp4 files found in $SRC_DIR"
    exit 1
  fi

  filename=$(basename "$f")
  name="${filename%.mp4}"

  echo "Processing: $filename"

  dur=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$f")
  dur=${dur%.*}

  if [ -z "$dur" ] || [ "$dur" -lt 2 ]; then
    echo "  Skipping $filename — duration <2s or unknown"
    continue
  fi

  half_dur=$((dur - XFADE))

  echo "  Duration: ${dur}s | Crossfade: ${XFADE}s | Output: ${name}_looped.mp4"

  ffmpeg -y -stream_loop 1 -i "$f" -i "$f" \
    -filter_complex "[0:v]format=pix_fmts=yuva420p,fade=t=in:st=0:d=0.5:alpha=0[v0];[1:v]format=pix_fmts=yuva420p,fade=t=out:st=${half_dur}:d=${XFADE}:alpha=0[v1];[v0][v1]overlay=0:0:enable='between(t,${half_dur},'$(($half_dur + $XFADE))')'[out]" \
    -map "[out]" \
    -c:v libx264 -preset fast -crf 18 \
    -t "$((dur * 2))" \
    "$DST_DIR/${name}_looped.mp4" 2>/dev/null

  if [ $? -eq 0 ]; then
    echo "  ✓ Saved: ${name}_looped.mp4"
  else
    echo "  ✗ Failed: $filename"
  fi
done

echo ""
echo "Done! Looped videos → $DST_DIR"


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)