- name
- narrator-ai-cli-video-narration
- description
- Create AI-narrated movie commentary videos using the narrator-ai-cli tool with automated script generation, voice synthesis, and video composition
- triggers
- ["create a movie narration video","generate a film commentary video","make a video with AI narration","create narration for a movie","generate a short drama video","make a commentary video with AI voice","create a movie recap video","generate automated video narration"]
# narrator-ai-cli-video-narration
> Skill by [ara.so](https://ara.so) — Devtools Skills collection.
## What It Does
`narrator-ai-cli` is a command-line tool that automates the creation of movie narration and commentary videos. It handles the entire pipeline: searching movies, generating scripts, selecting background music and voiceovers, and composing final videos. The tool provides two workflow paths:
- **Original Narration**: Fast path for creating new commentary from scratch
- **Adapted Narration**: Standard path for adapting existing movie content
## Installation
Install via pip from the GitHub repository:
```bash
pip install "narrator-ai-cli @ git+https://github.com/NarratorAI-Studio/narrator-ai-cli.git"
```
**Requirements:**
- Python 3.10+
- Dependencies: typer, httpx[socks], httpx-sse, pyyaml, rich
## Configuration
### Set API Key
You must configure your API key before using the tool:
```bash
# Set the API key
narrator-ai-cli config set app_key YOUR_APP_KEY
# Verify configuration
narrator-ai-cli config show
```
The API key is stored in `~/.narrator-ai-cli/config.yaml` and can also be set via environment variable:
```bash
export NARRATOR_APP_KEY=your_api_key_here
```
### Configuration File Location
- **Linux/macOS**: `~/.narrator-ai-cli/config.yaml`
- **Windows**: `%USERPROFILE%\.narrator-ai-cli\config.yaml`
## Core Concepts
### Key Identifiers
- **file_id**: Unique identifier for uploaded or generated files (video clips, audio, scripts)
- **task_id**: Identifier for asynchronous tasks (script generation, video composition)
- **task_order_num**: Order number for tracking task status
- **movie_id**: Identifier for movies in the database
- **template_id**: Identifier for narration templates
- **bgm_id**: Background music identifier
- **dubbing_id**: Voice/dubbing identifier
### File Types
- **Video clips**: `.mp4`, `.mov`, `.avi` (source material)
- **Audio**: `.mp3`, `.wav` (BGM, voiceovers, TTS output)
- **Scripts**: `.txt`, `.json` (generated narration scripts)
- **Clip data**: `.json` (timeline and segment information)
## Key Commands
### Search and Browse
```bash
# Search for movies
narrator-ai-cli search-movie "Inception"
# List available templates
narrator-ai-cli list-template --page 1 --page_size 20
# List background music
narrator-ai-cli list-bgm --page 1 --page_size 50
# List available voices
narrator-ai-cli list-dubbing --page 1 --page_size 50
# List user templates
narrator-ai-cli list-user-template
```
### Original Narration Workflow (Fast Path)
This workflow creates new narration from scratch without adapting existing movies.
#### Step 0: Select Resources
```bash
# Select a template
narrator-ai-cli list-template --page 1
# Select BGM
narrator-ai-cli list-bgm --style "轻快" --page 1
# Select voice
narrator-ai-cli list-dubbing --gender "男" --page 1
```
#### Step 1: Generate Original Script
```bash
# Create a new original narration script task
narrator-ai-cli create-original-narration-script-task \
--drama_name "都市霸总复仇记" \
--drama_intro "一个被背叛的霸总重返巅峰的故事" \
--template_id 12345
# Poll task status
narrator-ai-cli query-original-narration-script-task \
--task_id abc123 \
--task_order_num 1
# Download the generated script (when task completes)
narrator-ai-cli download-file --file_id def456 --output script.txt
```
#### Step 2: Create Original Clip Data
```bash
# Generate clip/timeline data from the script
narrator-ai-cli create-original-clip-data-task \
--narration_script_file_id def456 \
--drama_name "都市霸总复仇记"
# Poll until complete
narrator-ai-cli query-original-clip-data-task \
--task_id xyz789 \
--task_order_num 2
# Download clip data
narrator-ai-cli download-file --file_id ghi012 --output clip_data.json
```
#### Step 3: Text-to-Speech
```bash
# Convert script to speech
narrator-ai-cli create-tts-task \
--text_file_id def456 \
--dubbing_id 67890
# Poll TTS task
narrator-ai-cli query-tts-task \
--task_id tts123 \
--task_order_num 3
# Download audio
narrator-ai-cli download-file --file_id jkl345 --output narration.mp3
```
#### Step 4: Compose Final Video
```bash
# Compose the final video
narrator-ai-cli create-original-compose-task \
--dubbing_file_id jkl345 \
--clip_data_file_id ghi012 \
--bgm_id 11111 \
--template_id 12345
# Poll compose task
narrator-ai-cli query-original-compose-task \
--task_id comp456 \
--task_order_num 4
# Download final video
narrator-ai-cli download-file --file_id mno678 --output final_video.mp4
```
### Adapted Narration Workflow (Standard Path)
This workflow adapts existing movie content into narration videos.
#### Step 0: Search and Select Movie
```bash
# Find the movie
narrator-ai-cli search-movie "The Shawshank Redemption"
# Record the movie_id from results
```
#### Step 1: Generate Adapted Script
```bash
# Create adapted narration script task
narrator-ai-cli create-adapted-narration-script-task \
--movie_id 99999 \
--template_id 12345
# Poll task
narrator-ai-cli query-adapted-narration-script-task \
--task_id adp123 \
--task_order_num 1
# Download script
narrator-ai-cli download-file --file_id scr789 --output adapted_script.txt
```
#### Step 2: Create Adapted Clip Data
```bash
# Generate clip data for adapted narration
narrator-ai-cli create-adapted-clip-data-task \
--narration_script_file_id scr789 \
--movie_id 99999
# Poll task
narrator-ai-cli query-adapted-clip-data-task \
--task_id clp456 \
--task_order_num 2
# Download clip data
narrator-ai-cli download-file --file_id cld123 --output adapted_clip_data.json
```
#### Step 3: Text-to-Speech
```bash
# Same as Original workflow
narrator-ai-cli create-tts-task \
--text_file_id scr789 \
--dubbing_id 67890
narrator-ai-cli query-tts-task \
--task_id tts789 \
--task_order_num 3
narrator-ai-cli download-file --file_id aud456 --output adapted_narration.mp3
```
#### Step 4: Upload Source Video
```bash
# Upload the source movie file
narrator-ai-cli upload-file --file_path /path/to/movie.mp4
# Record the returned file_id
```
#### Step 5: Compose Adapted Video
```bash
# Compose final video with source material
narrator-ai-cli create-adapted-compose-task \
--dubbing_file_id aud456 \
--clip_data_file_id cld123 \
--source_video_file_id vid789 \
--bgm_id 11111 \
--template_id 12345
# Poll compose task
narrator-ai-cli query-adapted-compose-task \
--task_id acp999 \
--task_order_num 5
# Download final video
narrator-ai-cli download-file --file_id fin000 --output adapted_final.mp4
```
### Standalone Tasks
#### Voice Cloning
```bash
# Upload reference audio for voice cloning
narrator-ai-cli upload-file --file_path reference_voice.mp3
# Create voice clone task
narrator-ai-cli create-voice-clone-task \
--audio_file_id ref123 \
--voice_name "Custom Voice"
# Poll task
narrator-ai-cli query-voice-clone-task \
--task_id vcl123 \
--task_order_num 1
# The cloned voice gets a new dubbing_id for future use
```
#### Direct TTS (without full pipeline)
```bash
# Upload a text file
narrator-ai-cli upload-file --file_path script.txt
# Generate speech
narrator-ai-cli create-tts-task \
--text_file_id txt123 \
--dubbing_id 67890
narrator-ai-cli query-tts-task \
--task_id tts456 \
--task_order_num 1
narrator-ai-cli download-file --file_id tts789 --output speech.mp3
```
## Common Patterns
### Complete Original Narration Pipeline
```python
#!/usr/bin/env python3
import subprocess
import json
import time
def run_cmd(cmd):
"""Run CLI command and return output"""
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
return result.stdout.strip()
def poll_task(query_cmd, task_id, order_num):
"""Poll task until completion"""
while True:
output = run_cmd(f"{query_cmd} --task_id {task_id} --task_order_num {order_num}")
data = json.loads(output)
if data['status'] == 'completed':
return data['file_id']
elif data['status'] == 'failed':
raise Exception(f"Task failed: {data.get('error')}")
time.sleep(5)
# Step 1: Generate script
print("Generating script...")
script_task = json.loads(run_cmd(
'narrator-ai-cli create-original-narration-script-task '
'--drama_name "复仇之路" '
'--drama_intro "一个关于复仇的故事" '
'--template_id 12345'
))
script_file_id = poll_task(
'narrator-ai-cli query-original-narration-script-task',
script_task['task_id'],
script_task['task_order_num']
)
# Step 2: Generate clip data
print("Generating clip data...")
clip_task = json.loads(run_cmd(
f'narrator-ai-cli create-original-clip-data-task '
f'--narration_script_file_id {script_file_id} '
f'--drama_name "复仇之路"'
))
clip_file_id = poll_task(
'narrator-ai-cli query-original-clip-data-task',
clip_task['task_id'],
clip_task['task_order_num']
)
# Step 3: Generate TTS
print("Generating voice...")
tts_task = json.loads(run_cmd(
f'narrator-ai-cli create-tts-task '
f'--text_file_id {script_file_id} '
f'--dubbing_id 67890'
))
audio_file_id = poll_task(
'narrator-ai-cli query-tts-task',
tts_task['task_id'],
tts_task['task_order_num']
)
# Step 4: Compose video
print("Composing final video...")
compose_task = json.loads(run_cmd(
f'narrator-ai-cli create-original-compose-task '
f'--dubbing_file_id {audio_file_id} '
f'--clip_data_file_id {clip_file_id} '
f'--bgm_id 11111 '
f'--template_id 12345'
))
video_file_id = poll_task(
'narrator-ai-cli query-original-compose-task',
compose_task['task_id'],
compose_task['task_order_num']
)
# Download final video
print("Downloading video...")
run_cmd(f'narrator-ai-cli download-file --file_id {video_file_id} --output final.mp4')
print("Done! Video saved as final.mp4")
```
### Resource Selection Strategy
```bash
#!/bin/bash
# Function to select resources interactively
select_resources() {
echo "=== Selecting Template ==="
narrator-ai-cli list-template --page 1 | jq '.templates[] | {id, name, style}'
read -p "Enter template_id: " TEMPLATE_ID
echo -e "\n=== Selecting BGM ==="
narrator-ai-cli list-bgm --style "轻快" --page 1 | jq '.bgm[] | {id, name, style}'
read -p "Enter bgm_id: " BGM_ID
echo -e "\n=== Selecting Voice ==="
narrator-ai-cli list-dubbing --gender "男" --page 1 | jq '.voices[] | {id, name, gender}'
read -p "Enter dubbing_id: " DUBBING_ID
echo -e "\nSelected resources:"
echo "Template: $TEMPLATE_ID"
echo "BGM: $BGM_ID"
View on GitHub