AgentSkillsCN

video-resource-finder

自动搜索并下载素材资源(视频、图片、音乐、音效),生成 AI 图像,并在网页上为视频项目寻找合适的素材。

SKILL.md
--- frontmatter
name: video-resource-finder
description: Tự động tìm kiếm, tải về stock resources (video, image, music, sfx), tạo ảnh AI, và tìm ảnh trên web cho video project.

VIDEO RESOURCE FINDER SKILL

MỤC ĐÍCH

Tự động tìm kiếm FREE resources cho video production từ nhiều nguồn:

  • Stock Videos (B-roll) - Từ Pexels, Pixabay
  • Stock Images - Từ Pexels, Unsplash, Pixabay
  • Web Images - Từ DuckDuckGo web search (với cảnh báo bản quyền)
  • AI Generated Images - Từ Gemini Nano Banana (cho nội dung sáng tạo/minh họa)
  • Background Music - Từ Pixabay Music
  • Sound Effects - Từ Pixabay SFX

🆕 v2.0 - URL-Only Mode (Default):

  • Mặc định KHÔNG download - chỉ trả về URLs trong resources.json
  • Resources được download trong bước Import (resource-import.js)
  • Tiết kiệm băng thông và thời gian (chỉ download file đã chọn)
  • User preview từ remote URL trong Script Planner
  • Download staging vẫn có thể bật với --download flag nếu cần

🆕 AI Image Generation:

  • Tự động generate ảnh khi scene có type: "ai-generated" hoặc type: "illustration"
  • Fallback sang AI generation khi stock search không có kết quả phù hợp
  • Hỗ trợ tạo ảnh liên hoàn cho story/slideshow với style nhất quán

🆕 Pinned Resources (User-provided assets):

  • Scene có type: "pinned" → skip API search, dùng file/URL user cung cấp
  • Local files ngoài project tự động copy vào imports/{videos,images,music,sfx}/
  • Hỗ trợ path: relative to project, hoặc remote URL
  • Tên file được expand rõ ràng: import_{sceneId}_{description}_{originalName}.ext
  • Kết quả lưu trong resources.pinnedResources[] trong resources.json

WORKFLOW

NEW Workflow (v2.0 - URL-Only Mode - Default)

code
script.json → Read Scenes → Extract Queries → Call APIs/AI → Build resources.json (URLs only)
                                ↓
                    [Stock Queries]    [AI Queries]
                          ↓                  ↓
                   Pexels/Pixabay      Gemini Nano Banana
                          ↓                  ↓
                      Fallback ────────→ AI Generation
                          ↓
                    📄 resources.json (URLs, không có localPath)
                          ↓
                    👀 Script Planner (preview từ remote URL)
                          ↓
                    ✅ User Select → resource-import.js
                          ↓
                    📥 Download về imports/ (chỉ file đã chọn)

Chi tiết:

  1. Đọc script.json từ project directory
  2. Extract visual queries từ scenes:
    • type="stock" → Search Pexels/Pixabay
    • type="ai-generated" hoặc type="illustration" → Gemini AI
    • type="pinned" → User-provided file/URL (skip search, auto-import local files)
  3. Extract music query từ music.mood
  4. Tạo standard SFX queries (whoosh, pop, ding)
  5. Call Pexels API cho videos/images (stock)
  6. Call Pixabay API cho music/SFX (và backup cho videos/images)
  7. Call Gemini API cho AI-generated images
  8. Fallback sang Gemini nếu stock search không có kết quả
  9. Lưu kết quả vào resources.json với downloadUrls (KHÔNG download file)
  10. Download trong Import step (resource-import.js) - chỉ file đã chọn

Legacy Workflow (với --download flag)

Nếu cần download staging area (10 options/scene để preview local):

bash
node scripts/find-resources.js --projectDir "..." --download

Workflow cũ: tìm → download 10 results/scene → downloads/ → select → import → cleanup

INPUT PARAMETERS

Required

  • --projectDir: Đường dẫn đến folder chứa script.json (bắt buộc)

Search Options

  • --resultsPerQuery: Số lượng results mỗi query (default: 3, max: 80)
  • --provider: Provider cụ thể: "pexels", "pixabay", hoặc "unsplash" (default: null = multi-provider)
    • Multi-provider mode (default): Search TẤT CẢ providers có API key được cấu hình
    • Single provider mode: Chỉ search provider được chỉ định, KHÔNG fallback
  • --enableAI: Bật AI image generation (default: true nếu có GEMINI_API_KEY)
  • --noAI: Tắt AI image generation (chỉ dùng stock)

Download Options (v2.0 - Updated)

  • --download: Bật download staging (default: false - URL-only mode)
  • --skipDownload: Tắt download, chỉ lấy URLs (legacy, giống default mới)
  • --quality: Chọn quality khi download: best | hd | sd | medium (default: best)
    • best: Video 4K > HD, Image original > large
    • hd: Video HD, Image large
    • sd: Video SD, Image medium
  • --downloadCount: Số results tải mỗi scene nếu download enabled (default: 10)
  • --concurrency: Số download song song (default: 3)
  • --storage: Loại storage: local | cloud (default: local, cloud cho tương lai)

Lưu ý v2.0:

  • Mặc định KHÔNG download nữa
  • Resources được download trong bước Import (resource-import.js)
  • Chỉ file đã chọn mới được download về imports/
  • Không có downloads/ staging area → không cần cleanup

Execution Options (v1.2)

  • --batchSize: Giới hạn số lượng AI generation request mới (default: 0 = unlimited).
    • Dùng để tránh lỗi rate limit của Gemini API.
    • Ví dụ: --batchSize 3 sẽ chỉ tạo 3 ảnh AI mới, sau đó dừng.
  • Resume Capability (Tự động):
    • Skill sẽ tự động đọc resources.json cũ (nếu có).
    • Bỏ qua các scene đã có resource để tiết kiệm API quota.
    • Kết hợp với --batchSize để chạy lần lượt (batching).

Environment Variables (.env)

bash
# Stock Resources
PEXELS_API_KEY=your_pexels_api_key
PIXABAY_API_KEY=your_pixabay_api_key
UNSPLASH_API_KEY=your_unsplash_access_key

# AI Image Generation (optional but recommended)
GEMINI_API_KEY=your_gemini_api_key

Lưu ý: GEMINI_API_KEY có thể đặt ở:

  • File .env ở root project
  • File .env trong thư mục skill

SMART FEATURES (v1.3+)

1. Resource Type Selection

Control loại resource (image/video) cho từng scene bằng field resourceType trong visualSuggestion:

json
{
  "scenes": [
    {
      "id": "scene_1",
      "visualSuggestion": {
        "type": "stock",
        "resourceType": "video",  // "image", "video", or "auto" (default)
        "query": "parkour jumping"
      }
    }
  ]
}

Values:

  • "video" - Chỉ tìm video, bỏ qua images
  • "image" - Chỉ tìm images, bỏ qua videos
  • "auto" - Tự động (mặc định, tìm cả video và image)

2. Smart Filename Matching

Khi import files với pattern tên: {sceneId}_{description}.ext, skill tự động detect sceneId:

Examples:

  • scene_1_nature.mp4 → sceneId: scene_1
  • item1_workspace.jpg → sceneId: item1
  • hook_intro.mp4 → sceneId: hook

Supported patterns:

  • scene_\d+, item\d+ (numbered scenes)
  • hook, intro, cta, outro, conclusion (common scene names)
  • Bất kỳ text nào trước _ đầu tiên

Workflow:

  1. Đặt tên file: scene_1_my_video.mp4
  2. Import: local-asset-import --files scene_1_my_video.mp4
  3. Skill tự động map vào scene với id: "scene_1"

👉 Xem chi tiết: Resource Type Selection Guide


OUTPUT STRUCTURE

File resources.json được lưu trong projectDir:

json
{
  "projectName": "tai-sao-ngu-8-tieng-van-met",
  "generatedAt": "2026-01-24T20:00:00Z",
  "apiSources": {
    "pexels": { "used": true, "requestCount": 5 },
    "pixabay": { "used": true, "requestCount": 3 },
    "gemini": { "used": true, "requestCount": 2, "description": "AI image generation" }
  },
  "downloadSummary": {
    "enabled": true,
    "totalDownloaded": 7,
    "totalFailed": 0,
    "totalSkipped": 14,
    "storageLocation": "/path/to/project/downloads",
    "storageType": "local",
    "qualityPreference": "best"
  },
  "summary": {
    "totalVideos": 15,
    "totalImages": 6,
    "totalGeneratedImages": 2,
    "totalMusic": 6,
    "totalSoundEffects": 9,
    "totalScenes": 7,
    "successfulQueries": 9,
    "failedQueries": 0
  },
  "resources": {
    "videos": [
      {
        "sceneId": "hook",
        "sceneText": "Bạn ngủ đủ 8 tiếng...",
        "query": "tired waking up",
        "source": "pexels",
        "results": [
          {
            "id": "pexels-12345",
            "title": "Tired Woman Waking Up",
            "url": "https://www.pexels.com/video/12345",
            "downloadUrls": {
              "hd": "https://player.vimeo.com/.../hd.mp4",
              "sd": "https://player.vimeo.com/.../sd.mp4"
            },
            "width": 1920,
            "height": 1080,
            "duration": 12,
            "fps": 30,
            "user": {
              "name": "John Doe",
              "url": "https://www.pexels.com/@johndoe"
            },
            "license": "Pexels License (Free to use)",
            "rank": 1
          }
          // ... 2 more results
        ]
      }
    ],
    "images": [...],
    "generatedImages": [
      {
        "sceneId": "concept",
        "query": "brain illustration showing neural connections",
        "source": "gemini-ai",
        "type": "ai-generated",
        "results": [
          {
            "id": "gemini-concept-1706284800000",
            "title": "AI Generated: brain illustration",
            "localPath": "/projects/my-video/generated/concept_ai.png",
            "prompt": "brain illustration showing neural connections...",
            "source": "gemini-nano-banana",
            "generated": true,
            "license": "AI Generated"
          }
        ]
      }
    ],
    "music": [...],
    "soundEffects": [...]
  },
  "errors": []
}

Resources Structure Details

Videos

json
{
  "sceneId": "hook",
  "sceneText": "Scene text...",
  "query": "cleaned search query",
  "source": "pexels|pixabay",
  "results": [
    {
      "id": "pexels-12345",
      "title": "Video title",
      "url": "https://pexels.com/video/...",
      "downloadUrls": {
        "hd": "...",
        "sd": "...",
        "4k": "..."
      },
      "localPath": "/path/to/project/downloads/videos/hook_pexels-12345.mp4",
      "publicUrl": null,
      "downloadStatus": "success",
      "downloadedQuality": "4k",
      "fileSize": 15728640,
      "width": 1920,
      "height": 1080,
      "duration": 15,
      "fps": 30,
      "user": { "name": "...", "url": "..." },
      "tags": [],
      "license": "Pexels License (Free to use)",
      "rank": 1
    }
  ]
}

Images

json
{
  "sceneId": "solution",
  "query": "alarm clock",
  "source": "pexels",
  "results": [
    {
      "id": "pexels-67890",
      "title": "Modern Alarm Clock",
      "url": "https://pexels.com/photo/...",
      "downloadUrls": {
        "original": "...",
        "large": "...",
        "medium": "..."
      },
      "width": 1920,
      "height": 1080,
      "photographer": "Jane Smith",
      "tags": ["alarm", "clock"],
      "license": "Pexels License (Free to use)",
      "rank": 1
    }
  ]
}

Music

json
{
  "mood": "calm",
  "query": "calm ambient peaceful background music",
  "source": "pixabay",
  "results": [
    {
      "id": "pixabay-music-456",
      "title": "Calm Piano Meditation",
      "url": "https://pixabay.com/music/...",
      "downloadUrl": "https://cdn.pixabay.com/.../audio.mp3",
      "duration": 156,
      "genre": "Ambient",
      "tags": ["calm", "piano"],
      "license": "Pixabay Content License (Free to use)"
    }
  ]
}

Sound Effects

json
{
  "type": "whoosh",
  "query": "whoosh transition swoosh",
  "description": "For scene transitions and text animations",
  "source": "pixabay",
  "results": [
    {
      "id": "pixabay-sfx-whoosh",
      "title": "Whoosh Transition 1",
      "url": "https://pixabay.com/sound-effects/...",
      "downloadUrl": "https://cdn.pixabay.com/.../sfx.mp3",
      "duration": 2,
      "tags": ["whoosh", "transition"],
      "license": "Pixabay Content License (Free to use)"
    }
  ]
}

AI Generated Images (NEW)

json
{
  "sceneId": "metaphor",
  "sceneText": "Imagine your mind as a garden...",
  "query": "surreal garden inside a human brain, illustration",
  "source": "gemini-ai",
  "type": "ai-generated",
  "results": [
    {
      "id": "gemini-metaphor-1706284800000",
      "title": "AI Generated: surreal garden inside brain",
      "localPath": "/projects/video/generated/metaphor_ai.png",
      "prompt": "surreal garden inside a human brain, illustration...",
      "source": "gemini-nano-banana",
      "generated": true,
      "license": "AI Generated (usage follows Gemini Terms of Service)",
      "rank": 1
    }
  ]
}

API SETUP

1. Pexels API Key

Lấy key miễn phí:

  1. Truy cập: https://www.pexels.com/api/
  2. Click "Get Started" / "Sign Up"
  3. Đăng ký tài khoản (email + password)
  4. Verify email
  5. Vào API Dashboard → Copy API Key

Rate Limits:

  • 200 requests/hour
  • 50 requests/15 minutes

2. Pixabay API Key

Lấy key miễn phí:

  1. Truy cập: https://pixabay.com/api/docs/
  2. Sign up for an account
  3. Verify email
  4. Vào profile → API → Copy API Key

Rate Limits:

  • 5000 requests/day
  • 100 requests/minute

3. Unsplash API Key

Lấy key miễn phí:

  1. Truy cập: https://unsplash.com/developers
  2. Click "Register as a Developer"
  3. Đăng ký tài khoản (email + password)
  4. Tạo "New Application"
  5. Điền thông tin ứng dụng (tên, mô tả, chọn "Demo" nếu là test)
  6. Chấp nhận API Terms
  7. Copy Access Key (không phải Secret Key)

Rate Limits:

  • 50 requests/hour (Demo/Development mode)
  • 5000 requests/hour (Production - cần submit app để review)

Lưu ý:

  • Free tier đủ cho hầu hết use case
  • Ảnh chất lượng cao, phù hợp cho commercial use
  • Bắt buộc credit photographer theo license

4. Gemini API Key (cho AI Image Generation)

Lấy key miễn phí:

  1. Truy cập: https://aistudio.google.com/apikey
  2. Đăng nhập Google account
  3. Click "Create API key"
  4. Copy API Key

Model sử dụng: Gemini 2.0 Flash (Imagen 3)

  • Hỗ trợ image generation chất lượng cao
  • Free tier có rate limit

4. Tạo file .env

Copy .env.example thành .env:

bash
cd .claude/skills/video-resource-finder
cp .env.example .env

Hoặc thêm vào file .env ở root project:

bash
# Stock Resources
PEXELS_API_KEY=abc123xyz...
PIXABAY_API_KEY=def456uvw...
UNSPLASH_API_KEY=ghi789rst...

# AI Image Generation
GEMINI_API_KEY=AIza...your_gemini_key...

USAGE EXAMPLES

Example 1: Basic Usage (URL-only mode - Default)

bash
cd .claude/skills/video-resource-finder

# Install dependencies (first time only)
npm install

# Run skill - mặc định chỉ trả về URLs, không download
node scripts/find-resources.js \
  --projectDir "../../public/projects/tai-sao-ngu-8-tieng-van-met"

Output:

code
📥 Download: disabled (URL-only mode)
   → Resources will be downloaded during Import step (resource-import.js)

✅ Found 15 videos, 6 images, 6 music tracks, 9 sound effects
📄 resources.json saved to: public/projects/tai-sao-ngu-8-tieng-van-met/resources.json

Example 2: Download Staging (Legacy workflow)

bash
node scripts/find-resources.js \
  --projectDir "../../public/projects/my-project" \
  --download

Sẽ download files về downloads/ staging area (workflow cũ).

Example 3: Tùy chỉnh số lượng results và download

bash
node scripts/find-resources.js \
  --projectDir "../../public/projects/my-project" \
  --resultsPerQuery 5 \
  --downloadCount 2 \
  --quality hd
  • Search 5 results mỗi query
  • Download 2 results tốt nhất mỗi scene
  • Ưu tiên quality HD (thay vì 4K)

Example 4: Multi-provider (mặc định)

bash
node scripts/find-resources.js \
  --projectDir "../../public/projects/my-project"

Mặc định sẽ search trên TẤT CẢ providers có API key (Pexels, Pixabay, Unsplash).

Example 5: Chỉ search Pixabay (không fallback)

bash
node scripts/find-resources.js \
  --projectDir "../../public/projects/my-project" \
  --provider "pixabay"

Chỉ search Pixabay. Nếu không tìm thấy, sẽ KHÔNG fallback sang providers khác.

Example 6: Với AI Image Generation

bash
node scripts/find-resources.js \
  --projectDir "../../public/projects/creative-story" \
  --enableAI

Scenes với type: "ai-generated" sẽ được generate bằng Gemini. Stock search không có kết quả sẽ fallback sang AI.

Example 7: Tắt AI Generation

bash
node scripts/find-resources.js \
  --projectDir "../../public/projects/my-project" \
  --noAI

Chỉ dùng stock resources, bỏ qua AI generation.

ADD MUSIC TO PROJECT (NEW)

Script riêng để tìm và thêm nhạc nền vào project đã có sẵn.

Tại sao cần script riêng?

  • Pixabay Music API không hỗ trợ tìm kiếm trực tiếp
  • Script này dùng PixabayScraper (Puppeteer) để tìm và tải nhạc thực sự
  • Tự động cập nhật resources.json và project.otio

Cách sử dụng

bash
# Cơ bản - tự động đọc music query từ script.json
node scripts/add-music-to-project.js \
  --projectDir "../../public/projects/my-project"

# Custom query
node scripts/add-music-to-project.js \
  --projectDir "../../public/projects/my-project" \
  --query "epic cinematic"

# Cập nhật cả OTIO timeline
node scripts/add-music-to-project.js \
  --projectDir "../../public/projects/my-project" \
  --updateOtio

# Ghi đè file nhạc đã có
node scripts/add-music-to-project.js \
  --projectDir "../../public/projects/my-project" \
  --force

Options

OptionDefaultMô tả
--projectDir(required)Đường dẫn đến thư mục project
--querytừ script.jsonCustom music search query
--limit3Số lượng kết quả tìm kiếm
--outputFilebackground-music.mp3Tên file output
--updateOtiofalseCập nhật project.otio với music track
--forcefalseGhi đè file nhạc đã có

Output

code
public/projects/my-project/
├── audio/
│   └── background-music.mp3    ← File nhạc tải về
├── resources.json              ← Cập nhật với music info
└── project.otio                ← (nếu --updateOtio) Thêm Music track

Music Query Tips

Script sử dụng 3 từ đầu tiên của query để tìm kiếm. Nên dùng các từ khóa:

MoodQuery gợi ý
Calmpiano ambient calm
Epicepic cinematic orchestral
Happyupbeat happy cheerful
Sademotional piano melancholy
Inspiringmotivational inspiring corporate

WEB IMAGE SEARCH (NEW - v1.4)

Tìm kiếm ảnh trên web bằng DuckDuckGo khi user yêu cầu chủ động hoặc không tìm được ảnh phù hợp từ stock APIs.

⚠️ COPYRIGHT WARNING

QUAN TRỌNG: Ảnh tìm được từ web search CÓ THỂ CÓ VẤN ĐỀ VỀ BẢN QUYỀN.

  • Luôn confirm với user trước khi search web images
  • Nhắc nhở: "Images from web search may have copyright restrictions"
  • Khuyến nghị ưu tiên dùng stock APIs (Pexels, Pixabay, Unsplash) trước
  • Chỉ dùng web search khi:
    • User yêu cầu chủ động search web
    • Stock APIs không có kết quả phù hợp
    • Cần ảnh cụ thể, niche content

Tool: search_web_images

Tìm kiếm ảnh trên web bằng DuckDuckGo.

Usage:

bash
# Basic search
python tools/search_web_images.py "cat playing piano" \
  --max-results 20 \
  --confirm-copyright

# Save to JSON file
python tools/search_web_images.py "sunset beach" \
  --max-results 10 \
  --output search-results.json \
  --confirm-copyright

# Search High Quality Images (No GIFs)
python tools/search_web_images.py "cyberpunk city" \
  --size Wallpaper \
  --type-image photo \
  --confirm-copyright

Parameters:

  • query (required): Search keywords
  • --max-results: Số lượng kết quả (default: 20)
  • --output: Output JSON file path (optional)
  • --confirm-copyright: Hiển thị cảnh báo bản quyền trước khi search
  • --size: Kích thước ảnh (Small, Medium, Large, Wallpaper)
  • --type-image: Loại ảnh (photo, clipart, gif, transparent, line)

Output Structure (Images):

json
{
  "query": "cat playing piano",
  "total": 20,
  "source": "duckduckgo",
  "results": [
    {
      "id": "ddg-1",
      "title": "Cat Playing Piano",
      "image_url": "https://example.com/cat-piano.jpg",
      "thumbnail": "https://example.com/thumb.jpg",
      "source": "example.com",
      "width": 1920,
      "height": 1080,
      "rank": 1
    }
  ],
  "copyright_warning": "Images may have copyright restrictions. Verify usage rights before use."
}

Tool: download_web_image

Download ảnh từ web URL với error handling và security validation.

Usage:

bash
# Download single image
python tools/download_web_image.py \
  "https://example.com/image.jpg" \
  --output "downloads/images/my-image.jpg" \
  --timeout 30

Parameters:

  • url (required): Image URL to download
  • --output (required): Output file path
  • --timeout: Request timeout in seconds (default: 30)

Features:

  • ✅ User-Agent header để tránh bị block
  • ✅ Filename sanitization (path traversal protection)
  • ✅ Timeout và error handling
  • ✅ Content-type validation
  • ✅ Stream download cho files lớn

Workflow: Web Image Search + Download

bash
# Step 1: Search images
python tools/search_web_images.py "nature landscape" \
  --max-results 10 \
  --output search-results.json \
  --confirm-copyright

# Step 2: Review results (manual)
# Open search-results.json and choose images

# Step 3: Download selected images
# Option A: Manual download with download_web_image.py
python tools/download_web_image.py \
  "https://example.com/nature.jpg" \
  --output "downloads/images/nature_1.jpg"

# Option B: Use local-asset-import skill to import vào project
# (Recommended - tự động đổi tên và update resources.json)

Integration với local-asset-import

Sau khi download ảnh, dùng skill local-asset-import để import vào project:

bash
# Import downloaded images
local-asset-import \
  --projectDir "public/projects/my-video" \
  --files "downloads/images/*.jpg" \
  --type images

Skill sẽ:

  • Tự động đổi tên theo format: scene_{id}_{description}.jpg
  • Copy vào imports/images/
  • Update resources.json với pinnedResources

Python Dependencies

Cài đặt dependencies:

bash
cd .claude/skills/video-resource-finder
pip install -r requirements.txt

Requirements:

  • duckduckgo-search>=7.0.0 - DuckDuckGo search API
  • requests>=2.31.0 - HTTP downloads

CONVERSATION FLOW

Flow 1: Simple Flow (Đã có script.json)

code
User: "Tìm resources cho video tai-sao-ngu-8-tieng-van-met"