Skill: wondershare-boop/tomoviee-image-to-video (version 1.0.3)

--- name: tomoviee-image-to-video description: Generate videos from image + text prompts using Tomoviee Image-to-Video API (`tm_img2video_b`) through Wondershare OpenAPI gateway (`https://openapi.wondershare.cc`). Use when users request animating a still image with motion and camera guidance. --- # Tomoviee AI Image-to-Video ## Overview Generate a 5-second video from a still image and prompt. - API capability: `tm_img2video_b` - Create endpoint: `https://openapi.wondershare.cc/v1/open/capacity/application/tm_img2video_b` - Result endpoint: `https://openapi.wondershare.cc/v1/open/pub/task` ## Provider and Endpoint Provenance Use this mapping to verify provider identity and endpoint provenance: - Vendor portals: `https://www.tomoviee.ai` and `https://www.tomoviee.cn` - Runtime gateway host used by this skill: `https://openapi.wondershare.cc` - Compatible gateway alias: `https://open-api.wondershare.cc` This skill sends runtime API calls only to `openapi.wondershare.cc`. ## Credential Handling - Sensitive credentials required: `app_key` and `app_secret`. - Credentials are only used to build `Authorization: Basic <base64(app_key:app_secret)>`. - Credentials are kept in process memory and are not written to disk by this skill. - Do not hardcode credentials in source files or commit them to git. ## Dependencies - Runtime dependency: `requests>=2.31.0,<3.0.0` - Install with: `pip install -r requirements.txt` ## Quick Start ### Authentication helper ```bash python scripts/generate_auth_token.py YOUR_APP_KEY YOUR_APP_SECRET ``` ### Python Client ```python from scripts.tomoviee_img2video_client import TomovieeImg2VideoClient client = TomovieeImg2VideoClient("app_key", "app_secret") ``` ## API Usage ### Basic Example ```python task_id = client.image_to_video( prompt="Camera slowly pushes in, gentle motion in the scene, cinematic lighting", image="https://example.com/landscape.jpg", resolution="720p", duration=5, aspect_ratio="original", ) result = client.poll_until_complete(task_id) import json video_url = json.loads(result["result"])["video_path"][0] print(video_url) ``` ### Parameters - `prompt` (required): motion and scene guidance text. - `image` (required): source image URL (`JPG/JPEG/PNG/WEBP`, `<200M`). - `resolution` (optional): `720p` or `1080p`, default `720p`. - `duration` (optional): only `5` supported. - `aspect_ratio` (optional): `16:9`, `9:16`, `4:3`, `3:4`, `1:1`, `original`. - `camera_move_index` (optional): camera movement type `1-46`. - `callback` (optional): callback URL. - `params` (optional): transparent callback parameter. ## Async Workflow 1. Create task and get `task_id` 2. Poll with `poll_until_complete(task_id)` 3. Parse video URL from `result` Status codes: - `1` queued - `2` processing - `3` success - `4` failed - `5` cancelled - `6` timeout ## Resources - `scripts/tomoviee_img2video_client.py` - main API client - `scripts/tomoviee_image_to_video_client.py` - compatibility import shim - `scripts/generate_auth_token.py` - auth token helper - `references/video_apis.md` - API reference and constraints - `references/camera_movements.md` - camera movement index reference - `references/prompt_guide.md` - prompt writing guidance ## External Resources - Developer portal (global): `https://www.tomoviee.ai/developers.html` - API docs (global): `https://www.tomoviee.ai/doc/ai-video/image-to-video.html` - Developer portal (mainland): `https://www.tomoviee.cn/developers.html` - API docs (mainland): `https://www.tomoviee.cn/doc/ai-video/image-to-video.html`

path: requirements.txt
content: requests>=2.31.0,<3.0.0

path: _meta.json
content: ownerId: kn7bn8fv79mjtchs17087tdtsx82fc86
slug: tomoviee-image-to-video
version: 1.0.1
publishedAt: 1772934161125

path: scripts/generate_auth_token.py
content: #!/usr/bin/env python3
"""
Generate authentication token for Tomoviee API.

Usage:
    python generate_auth_token.py <app_key> <app_secret>

Output:
    Base64 encoded access_token in the format required by Authorization header
"""

import base64
import sys


def generate_access_token(app_key: str, app_secret: str) -> str:
    """
    Generate access token for Tomoviee API authentication.
    
    Args:
        app_key: Application key from Tomoviee console
        app_secret: Application secret from Tomoviee console
    
    Returns:
        Base64 encoded string in format: base64(app_key:app_secret)
    """
    credentials = f"{app_key}:{app_secret}"
    access_token = base64.b64encode(credentials.encode()).decode()
    return access_token


if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: python generate_auth_token.py <app_key> <app_secret>")
        sys.exit(1)
    
    app_key = sys.argv[1]
    app_secret = sys.argv[2]
    
    [REDACTED_SECRET], app_secret)
    print(f"Access [REDACTED_SECRET]")
    print(f"\nUse in Authorization header as: Basic {token}")


path: scripts/tomoviee_image_to_video_client.py
content: #!/usr/bin/env python3
"""Compatibility shim. Prefer importing TomovieeImg2VideoClient from tomoviee_img2video_client."""

try:
    from scripts.tomoviee_img2video_client import TomovieeClient, TomovieeImg2VideoClient
except Exception:
    from tomoviee_img2video_client import TomovieeClient, TomovieeImg2VideoClient

__all__ = ["TomovieeClient", "TomovieeImg2VideoClient"]

path: scripts/tomoviee_img2video_client.py
content: #!/usr/bin/env python3
"""Tomoviee AI - Image-to-Video API client."""

import base64
import json
import time
from typing import Any, Dict, Optional

import requests


class TomovieeImg2VideoClient:
    """Image-to-Video API client for Tomoviee AI."""

    BASE_URL = "https://openapi.wondershare.cc/v1/open/capacity/application"
    RESULT_ENDPOINT = "https://openapi.wondershare.cc/v1/open/pub/task"
    ENDPOINT = "tm_img2video_b"
    REQUEST_TIMEOUT = 60

    def __init__(self, app_key: str, app_secret: str):
        self.app_key = app_key
        self.access_token = self._generate_token(app_key, app_secret)

    def _generate_token(self, app_key: str, app_secret: str) -> str:
        credentials = f"{app_key}:{app_secret}"
        return base64.b64encode(credentials.encode()).decode()

    def _get_headers(self) -> Dict[str, str]:
        return {
            "Content-Type": "application/json",
            "X-App-Key": self.app_key,
            "Authorization": f"Basic {self.access_token}",
        }

    def _safe_json(self, response: requests.Response) -> Dict[str, Any]:
        try:
            return response.json()
        except ValueError as exc:
            raise Exception(f"Invalid JSON response: {response.text}") from exc

    def _make_request(self, payload: Dict[str, Any]) -> str:
        url = f"{self.BASE_URL}/{self.ENDPOINT}"
        response = requests.post(
            url,
            headers=self._get_headers(),
            json=payload,
            timeout=self.REQUEST_TIMEOUT,
        )
        response.raise_for_status()
        result = self._safe_json(response)

        if result.get("code") != 0:
            raise Exception(f"API Error: {result.get('msg', 'Unknown error')}")

        task_id = result.get("data", {}).get("task_id")
        if not task_id:
            raise Exception(f"Missing task_id in response: {result}")
        return task_id

    def image_to_video(
        self,
        prompt: str,
        image: str,
        resolution: str = "720p",
        duration: int = 5,
        aspect_ratio: str = "16:9",
        camera_move_index: Optional[int] = None,
        callback: Optional[str] = None,
        params: Optional[str] = None,
    ) -> str:
        """Create an image-to-video task and return task_id."""
        if duration != 5:
            raise ValueError("duration must be 5 for tm_img2video_b")

        payload: Dict[str, Any] = {
            "prompt": prompt,
            "image": image,
            "resolution": resolution,
            "duration": duration,
            "aspect_ratio": aspect_ratio,
        }

        if camera_move_index is not None:
            payload["camera_move_index"] = camera_move_index
        if callback:
            payload["callback"] = callback
        if params:
            payload["params"] = params

        return self._make_request(payload)

    def get_result(self, task_id: str) -> Dict[str, Any]:
        response = requests.post(
            self.RESULT_ENDPOINT,
            headers=self._get_headers(),
            json={"task_id": task_id},
            timeout=self.REQUEST_TIMEOUT,
        )
        response.raise_for_status()
        result = self._safe_json(response)

        if result.get("code") != 0 and not result.get("data"):
            raise Exception(f"API Error: {result.get('msg', 'Unknown error')}")

        data = result.get("data")
        if not data:
            raise Exception(f"Missing task data in response: {result}")
        return data

    def poll_until_complete(
        self,
        task_id: str,
        poll_interval: int = 10,
        timeout: int = 600,
    ) -> Dict[str, Any]:
        elapsed = 0

        while elapsed < timeout:
            result = self.get_result(task_id)
            status = result.get("status")

            if status == 3:
                return result
            if status in [4, 5, 6]:
                raise Exception(f"Task failed: {result.get('reason', 'Unknown error')}")

            time.sleep(poll_interval)
            elapsed += poll_interval

        raise TimeoutError(f"Task did not complete within {timeout} seconds")


# Backward-compatible alias
TomovieeClient = TomovieeImg2VideoClient


if __name__ == "__main__":
    import sys

    if len(sys.argv) < 5:
        print(
            "Usage: python scripts/tomoviee_img2video_client.py "
            "<app_key> <app_secret> <prompt> <image_url> [resolution] [aspect_ratio]"
        )
        sys.exit(1)

    app_key = sys.argv[1]
    app_secret = sys.argv[2]
    prompt = sys.argv[3]
    image = sys.argv[4]
    resolution = sys.argv[5] if len(sys.argv) > 5 else "720p"
    aspect_ratio = sys.argv[6] if len(sys.argv) > 6 else "16:9"

    client = TomovieeImg2VideoClient(app_key, app_secret)

    try:
        print("Creating image-to-video task...")
        task_id = client.image_to_video(
            prompt=prompt,
            image=image,
            resolution=resolution,
            aspect_ratio=aspect_ratio,
        )
        print(f"Task created: {task_id}")
        print("Polling for result...")

        result = client.poll_until_complete(task_id)

        print("\nTask completed")
        print(f"Progress: {result.get('progress', 'N/A')}%")

        result_data = json.loads(result["result"])
        print(json.dumps(result_data, indent=2, ensure_ascii=False))

    except Exception as exc:
        print(f"Error: {exc}")
        sys.exit(1)

path: references/camera_movements.md
content: # Camera Movement Types Reference

Complete list of camera movement types for `camera_move_index` parameter.

## Movement Types (1-46)

| Index | Type | Description |
|-------|------|-------------|
| 1 | orbit | Camera circles around subject |
| 2 | spin | Rotating motion |
| 3 | pan left | Camera pans to the left |
| 4 | pan right | Camera pans to the right |
| 5 | tilt up | Camera tilts upward |
| 6 | tilt down | Camera tilts downward |
| 7 | push in | Camera moves closer to subject |
| 8 | pull out | Camera moves away from subject |
| 9 | static | No camera movement |
| 10 | tracking | Camera follows subject movement |
| 11 | others | Unspecified movement |
| 12 | object pov | Point of view from object perspective |
| 13 | super dolly in | Dramatic push into scene |
| 14 | super dolly out | Dramatic pull from scene |
| 15 | snorricam | Camera fixed to subject while rotating |
| 16 | head tracking | Follows head/face movement |
| 17 | car grip | Camera mounted on vehicle |
| 18 | screen transition | Transition effect movement |
| 19 | car chasing | Following vehicle action |
| 20 | fisheye | Wide-angle distortion effect |
| 21 | FPV drone | First-person drone perspective |
| 22 | crane over the head | Overhead crane shot |
| 23 | timelapse landscape | Time-lapse scenery |
| 24 | dolly in | Smooth push toward subject |
| 25 | dolly out | Smooth pull from subject |
| 26 | zoom in | Lens zooms closer |
| 27 | zoom out | Lens zooms further |
| 28 | full shot | Wide establishing shot |
| 29 | close-up shot | Tight framing on subject |
| 30 | extreme close-up | Very tight detail shot |
| 31 | Macro shot | Extreme close-up of small details |
| 32 | bird's-eye view | Overhead perspective |
| 33 | rule of thirds | Compositional guideline |
| 34 | symmetrical composition | Balanced framing |
| 35 | handheld | Shaky, documentary-style |
| 36 | FPV shot | First-person view |
| 37 | jib up | Crane moves upward |
| 38 | jib down | Crane moves downward |
| 39 | full shot | Complete subject in frame |
| 40 | Time lapse shot | Compressed time progression |
| 41 | aerial shot | High-altitude view |
| 42 | low angle shot | Camera positioned below subject |
| 43 | Eye-level shot | Camera at subject's eye level |
| 44 | diagonal composition | Angled framing |
| 45 | over shoulder shot | View from behind subject |
| 46 | crane down | Crane descends |

## Usage Example

```python
# Static shot with no camera movement
client.create_video(
    prompt="猫咪转头看向镜头",
    image="https://example.com/cat.jpg",
    camera_move_index=9  # static
)

# Dramatic push in shot
client.create_video(
    prompt="女孩突然转头,右手拿起无线耳机戴在耳朵上",
    image="https://example.com/girl.jpg",
    camera_move_index=13  # super dolly in
)
```


path: references/prompt_guide.md
content: # Tomoviee Prompt Engineering Guide

## Overview
This guide provides structured prompt formulas and best practices for all Tomoviee AI APIs to achieve optimal generation results.

---

## Video APIs

### Text-to-Video Prompt Formula
```
主体(描述) + 运动 + 场景(描述) + (镜头语言 + 光影 + 氛围)
Subject (description) + Motion + Scene (description) + (Camera + Lighting + Atmosphere)
```

**Component Breakdown**:

1. **Subject (主体)**: Main focus of the video
   - Who/what is in the scene
   - Key characteristics, appearance
   - Position and pose

2. **Motion (运动)**: Action and movement
   - What the subject is doing
   - Speed and direction of movement
   - Dynamic elements

3. **Scene (场景)**: Environment and context
   - Location and setting
   - Background elements
   - Time of day/season

4. **Camera (镜头语言)**: Optional camera work
   - Camera angle (wide, close-up, aerial, etc.)
   - Camera movement (pan, zoom, tracking, etc.)
   - Or specify `camera_move_index` parameter

5. **Lighting (光影)**: Optional lighting style
   - Natural/artificial light
   - Time of day (golden hour, blue hour, etc.)
   - Light direction and quality

6. **Atmosphere (氛围)**: Optional mood and tone
   - Overall feeling (dramatic, peaceful, energetic)
   - Color palette/grading
   - Weather/environmental effects

**Examples**:

**Minimal** (Subject + Motion + Scene):
```
"A red sports car driving fast on a coastal highway at sunset"
```

**Standard** (+ Camera + Lighting):
```
"A red sports car speeding along a winding coastal highway at golden hour, 
camera following from the side, warm orange sunlight reflecting off the car"
```

**Detailed** (+ Atmosphere):
```
"A sleek red Ferrari speeding along a dramatic coastal highway carved into cliffs, 
camera tracking smoothly from the side at car level, 
golden hour sunset casting long shadows and warm orange glow, 
cinematic and epic atmosphere with ocean waves crashing below"
```

**More Examples by Use Case**:

**Product Showcase**:
```
"White wireless headphones slowly rotating on a minimalist white surface, 
studio lighting with soft shadows, clean and modern atmosphere"
```

**Nature/Travel**:
```
"Majestic waterfall cascading down mossy rocks in a lush rainforest, 
slow zoom in from wide to medium shot, 
dappled sunlight filtering through the canopy, 
serene and peaceful atmosphere"
```

**Action/Sports**:
```
"Professional skateboarder performing a kickflip on urban street ramp, 
slow motion capture from low angle, 
bright daylight with high contrast shadows, 
energetic and dynamic atmosphere"
```

### Image-to-Video Prompt Formula
```
主体 + 运动 + 镜头语言
Subject + Motion + Camera
```

**Why simpler?** The image already provides:
- Scene and environment
- Lighting and color palette
- Composition and framing
- Atmosphere and mood

**Your prompt should focus on**:
- Motion to add to the static image
- Camera movement to apply
- Any new dynamic elements

**Examples**:

```
"Camera slowly zooming in, subject's hair gently blowing in the wind"
```

```
"Slow pan from left to right, leaves rustling, golden hour lighting"
```

```
"Camera orbiting around the subject, dramatic lighting, cinematic feel"
```

```
"Gentle push in toward the subject's face, bokeh background, emotional atmosphere"
```

### Video Continuation Prompt Formula
```
延续的动作 + 场景变化 + 镜头延续
Continued action + Scene evolution + Camera continuation
```

**Focus on**:
- How the action continues from the last frame
- Natural progression of movement
- Scene changes or transitions
- Camera movement consistency

**Examples**:

```
"The bird continues flying higher, soaring into the clouds, 
camera following the ascent"
```

```
"The car continues down the road, passing through a tunnel, 
maintaining tracking shot"
```

```
"The person continues walking, entering a brightly lit room, 
camera follows smoothly"
```

---

## Image APIs

### Image-to-Image Prompt Formula
```
参考图描述 + 保留要素 + 修改/新增指令
Reference description + Elements to preserve + Modifications/additions
```

**Component Breakdown**:

1. **Reference Description**: What's in the original image
2. **Preserve**: Explicitly state what to keep unchanged
3. **Modify/Add**: What to change or add

**Examples**:

```
"A woman in business attire at a modern office, 
preserve facial features and body pose, 
change background to outdoor garden with natural lighting, 
add warm sunset atmosphere"
```

```
"Portrait of a man wearing a blue shirt, 
keep facial features and expression, 
change clothing to formal black suit with tie, 
maintain studio lighting"
```

```
"Kitchen interior with white cabinets, 
preserve layout and appliance positions, 
change color scheme to navy blue cabinets with gold hardware, 
add marble countertops"
```

### Image Redrawing Prompt Formula
```
替换区域的新内容描述
Description of what replaces the masked area
```

**Focus on**:
- What should appear in the masked region
- Style/texture matching surrounding areas
- Lighting consistency
- Natural integration

**Examples**:

```
"Clear blue sky with white fluffy clouds"
(for replacing background)
```

```
"Natural grass texture with small wildflowers"
(for replacing foreground)
```

```
"Modern glass windows with reflections of cityscape"
(for replacing building facade)
```

```
"Empty wooden table surface with subtle wood grain"
(for removing objects from table)
```

### Image Recognition Prompt Formula
```
要识别的对象/区域描述
Description of objects/regions to identify
```

**Focus on**:
- Clear object identification
- Specific vs. general (depending on need)
- Spatial context if helpful

**Examples**:

```
"person" / "all people"
```

```
"the red car in the foreground"
```

```
"sky and clouds"
```

```
"text and logos"
```

```
"background behind the main subject"
```

---

## Audio APIs

### Text-to-Music Prompt Formula
```
主体 + 场景(氛围/风格)
Subject/Theme + Scene (Atmosphere/Style)
```

**Component Breakdown**:

1. **Subject/Theme**: Purpose or topic of the music
2. **Atmosphere**: Mood and emotional quality
3. **Style/Genre**: Musical style and genre
4. **Instruments** (optional): Key instruments to feature

**Examples**:

**Simple**:
```
"Upbeat electronic music, energetic and modern"
```

**Standard**:
```
"Corporate presentation background music, professional and clean, 
soft piano and ambient synth"
```

**Detailed**:
```
"Epic cinematic orchestral score, dramatic and heroic, 
soaring strings and powerful brass, 
Hans Zimmer style, for action scene"
```

**By Genre**:

**Electronic/Pop**:
```
"Energetic EDM track, festival atmosphere, heavy bass and synth drops"
```

**Jazz**:
```
"Smooth jazz for evening ambience, sophisticated and relaxed, 
piano trio with double bass"
```

**Orchestral**:
```
"Emotional film score, contemplative and moving, 
piano and string ensemble"
```

**Ambient**:
```
"Peaceful meditation music, calm and spacious, 
soft pads and gentle chimes"
```

### Text-to-Sound-Effect Prompt Formula
```
声音来源 + 动作/环境 + 特征
Sound source + Action/Context + Characteristics
```

**Component Breakdown**:

1. **Sound Source**: What's making the sound
2. **Action/Context**: What's happening / where it is
3. **Characteristics**: Sound qualities (loud, soft, sharp, etc.)

**Examples**:

**Single Events**:
```
"Glass bottle shattering on concrete, sharp and crisp"
```

```
"Car door closing, solid thunk, reverb in garage"
```

```
"Notification bell sound, soft and pleasant"
```

**Continuous Sounds**:
```
"Heavy rain on metal roof, steady and rhythmic"
```

```
"City traffic ambience, cars passing, distant sirens"
```

```
"Forest birds chirping, peaceful morning atmosphere"
```

**By Category**:

**Nature**:
```
"Ocean waves crashing on beach, powerful and continuous"
```

**Mechanical**:
```
"Old typewriter keys typing, mechanical clicks and dings"
```

**Human**:
```
"Crowd cheering and applauding, enthusiastic and loud"
```

**UI/Digital**:
```
"Futuristic UI beep, high-tech and clean"
```

### Text-to-Speech Tips

**Structure**:
- Write naturally as you would speak
- Use punctuation for pacing and pauses
- Spell out numbers and abbreviations

**Examples**:

**With Pacing**:
```
"Welcome to our platform... Let me show you around."
(Ellipsis adds natural pause)
```

**With Emphasis**:
```
"This is extremely important. Pay close attention."
(Period creates strong pause for emphasis)
```

**Numbers**:
```
"Call one, eight hundred, five five five, zero one two three"
(Instead of "Call 1-800-555-0123")
```

### Video Soundtrack Prompt Formula
```
风格/类型 + 情绪 + (节奏/能量)
Style/Genre + Mood + (Optional: pacing/energy)
```

**Why simpler?** The API analyzes video content automatically.

**Examples**:

**Minimal** (let API analyze):
```
(no prompt - fully automatic based on video)
```

**Guided Style**:
```
"Upbeat travel vlog music, adventurous and inspiring"
```

```
"Corporate tech presentation music, modern and professional"
```

```
"Emotional documentary score, contemplative and moving"
```

---

## General Best Practices

### Do's ✅

1. **Be Specific**: Clear descriptions yield better results
   - Good: "Golden retriever puppy playing with red ball"
   - Bad: "Dog playing"

2. **Use Descriptive Adjectives**: Add relevant details
   - Good: "Sleek modern smartphone with edge-to-edge display"
   - Bad: "Phone"

3. **Specify Mood/Atmosphere**: Set the tone
   - Good: "Dramatic sunset with vibrant orange and purple clouds"
   - Bad: "Sunset"

4. **Include Context**: Where, when, why
   - Good: "Professional product photography on white background"
   - Bad: "Product"

5. **Mention Key Visual Elements**:
   - Lighting conditions
   - Color palette
   - Composition style
   - Movement characteristics

### Don'ts ❌

1. **Don't Be Vague**:
   - Bad: "Nice video"
   - Bad: "Good music"
   - Bad: "Cool image"

2. **Don't Contradict**:
   - Bad: "Bright and dark scene"
   - Bad: "Fast and slow motion"
   - Bad: "Happy sad music"

3. **Don't Over-specify Technical Details**:
   - Bad: "1920x1080 resolution 24fps H.264 codec"
   - Bad: "120 BPM in C major with I-V-vi-IV progression"
   - (API handles technical parameters automatically)

4. **Don't Use Negations**:
   - Bad: "Not blurry, not dark, not boring"
   - Good: "Sharp, bright, engaging"

5. **Don't Mix Multiple Unrelated Concepts**:
   - Bad: "Cat playing piano in space while cooking pasta"
   - Better: Split into multiple generations or choose one focus

---

## Advanced Techniques

### Chaining Outputs

Use output from one API as input to another:

```python
# 1. Generate image
img_task = client.image_to_image(
    prompt="Modern office space, clean and minimal",
    image="reference.jpg"
)
img_url = get_result_url(img_task)

# 2. Animate image
video_task = client.image_to_video(
    prompt="Camera slowly panning right, golden hour lighting",
    image=img_url
)
video_url = get_result_url(video_task)

# 3. Add soundtrack
audio_task = client.video_soundtrack(
    video=video_url,
    prompt="Professional corporate music"
)
```

### Iterative Refinement

1. **Start Simple**: Test with minimal prompt
2. **Evaluate Output**: What's missing or wrong?
3. **Add Details**: Incrementally add specificity
4. **Test Again**: Compare results

**Example Iteration**:
```
V1: "Car driving"
→ Too generic

V2: "Red sports car driving fast on highway"
→ Better, but lighting unclear

V3: "Red Ferrari speeding on coastal highway, golden hour sunset, dramatic"
→ Good result!
```

### A/B Testing

Generate multiple variations to compare:

```python
# Test different camera movements
variants = [
    client.image_to_video(image=img, prompt="Slow zoom in", camera_move_index=5),
    client.image_to_video(image=img, prompt="Pan right", camera_move_index=12),
    client.image_to_video(image=img, prompt="Orbit around subject", camera_move_index=23)
]
```

### Consistency Across Assets

For cohesive content, maintain consistent prompt elements:

```python
# Consistent style keywords across multiple generations
style_guide = "cinematic, golden hour lighting, dramatic atmosphere"

video1 = client.text_to_video(f"Mountain landscape, {style_guide}")
video2 = client.text_to_video(f"Forest scene, {style_guide}")
video3 = client.text_to_video(f"Beach sunset, {style_guide}")
```

---

## Prompt Templates by Use Case

### Marketing/Commercial
```
"[Product name] showcased on [surface/background], 
[camera movement], 
studio lighting with soft shadows, 
premium and elegant atmosphere"
```

### Social Media
```
"[Subject] [action], 
[camera angle/movement], 
vibrant colors and high energy, 
engaging and eye-catching for [platform]"
```

### Documentary/Educational
```
"[Subject] in [environment], 
[natural action], 
natural documentary style cinematography, 
informative and authentic atmosphere"
```

### Artistic/Creative
```
"[Abstract concept] visualized as [imagery], 
[unique camera work], 
[lighting style], 
[artistic mood/style reference]"
```

---

## Troubleshooting

### Problem: Output doesn't match prompt
**Solutions**:
- Simplify prompt to core elements
- Remove contradictory instructions
- Be more specific about key aspects
- Check for typos or ambiguous terms

### Problem: Output quality is poor
**Solutions**:
- Add style keywords (cinematic, professional, high quality)
- Specify lighting conditions
- Mention camera quality/style
- Add atmosphere/mood descriptors

### Problem: Inconsistent results
**Solutions**:
- Use more specific prompts
- Reference specific styles or examples
- Test with variations to find optimal wording
- Use consistent style keywords across generations

### Problem: Generation fails (status=4)
**Solutions**:
- Check prompt for inappropriate content
- Simplify overly complex prompts
- Verify input files (images/videos) are valid
- Ensure parameters are within valid ranges
- Try with default parameters first

---

## Language Considerations

Tomoviee supports both **Chinese** and **English** prompts.

**Tips**:
- Use language you're most comfortable with
- Be aware of cultural/contextual nuances
- Technical terms may work better in English
- Artistic descriptions may vary by language interpretation

**Example Comparisons**:

Chinese:
```
"一只金毛寻回犬在阳光明媚的草地上奔跑,镜头跟随,电影级画质"
```

English:
```
"A golden retriever running through a sunlit meadow, camera following, cinematic quality"
```

Both can produce excellent results - choose based on your fluency and precision needs.

---

## Summary Checklist

Before submitting your prompt, verify:

- [ ] **Clear Subject**: What's the main focus?
- [ ] **Specific Action**: What's happening?
- [ ] **Scene Context**: Where is this taking place?
- [ ] **Visual Style**: What's the look and feel?
- [ ] **Technical Parameters**: Resolution, duration, aspect ratio set correctly?
- [ ] **No Contradictions**: All elements work together?
- [ ] **Appropriate Specificity**: Not too vague, not over-specified?

A well-crafted prompt is the foundation of excellent AI-generated content. Take time to refine your prompts for best results!


path: references/video_apis.md
content: # Tomoviee Image-to-Video API Reference

## Provenance and Endpoint Mapping

- Vendor portals: `https://www.tomoviee.ai` and `https://www.tomoviee.cn`
- Runtime gateway host used by this skill package: `https://openapi.wondershare.cc`
- Compatible gateway alias: `https://open-api.wondershare.cc`
- Primary capability in this skill: `tm_img2video_b`

All runtime requests from this skill target only:

1. `https://openapi.wondershare.cc/v1/open/capacity/application/tm_img2video_b`
2. `https://openapi.wondershare.cc/v1/open/pub/task`

## Image-to-Video (tm_img2video_b)

Generate a 5-second video from a still image and prompt.

### Parameters

- `prompt` (required): motion guidance text
- `image` (required): source image URL
- `resolution` (optional): `720p` or `1080p`, default `720p`
- `duration` (optional): only `5` supported
- `aspect_ratio` (optional): `16:9`, `9:16`, `4:3`, `3:4`, `1:1`, `original`
- `camera_move_index` (optional): camera movement index `1-46`
- `callback` (optional): callback URL
- `params` (optional): transparent callback passthrough

### Input Constraints

- Maximum file size: `<200M`
- Formats: `JPG`, `JPEG`, `PNG`, `WEBP`

### Result Endpoint

`https://openapi.wondershare.cc/v1/open/pub/task`

### Status Codes

- `1` queued
- `2` processing
- `3` success
- `4` failed
- `5` cancelled
- `6` timeout

## Credential and Dependency Notes

- Sensitive credentials required: `app_key`, `app_secret`
- Auth pattern: `Authorization: Basic <base64(app_key:app_secret)>`
- Runtime dependency: `requests>=2.31.0,<3.0.0`

### Example

```python
from scripts.tomoviee_img2video_client import TomovieeImg2VideoClient

client = TomovieeImg2VideoClient("app_key", "app_secret")
task_id = client.image_to_video(
    prompt="Camera slowly pushes in with natural movement",
    image="https://example.com/image.jpg",
    resolution="720p",
    duration=5,
    aspect_ratio="original",
)
result = client.poll_until_complete(task_id)
```

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