
Jimeng Api Video Gen
- 470 installs
- 1 repo stars
- Updated May 26, 2026
- wvlvik/toy-skills
Helps with backend & apis tasks.
About
jimeng-api-video-gen is a Claude Code skill for backend & apis. It helps solo builders move faster with AI-assisted development.
- jimeng-api-video-gen
- Backend & APIs
- AI-coding skill
Jimeng Api Video Gen by the numbers
- 470 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #871 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wvlvik/toy-skills --skill jimeng-api-video-genAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 470 |
|---|---|
| repo stars | ★ 1 |
| Last updated | May 26, 2026 |
| Repository | wvlvik/toy-skills ↗ |
What it does
Helps with backend & apis tasks.
Files
Jimeng API Video Generation
Generate high-quality AI videos using Volcengine's Jimeng Video 3.0 Pro API with text prompts or input images.
Configure Environment Variables
# ~/.zshrc or ~/.zshenv
export VOLC_ACCESSKEY="your_access_key_id"
export VOLC_SECRETKEY="your_secret_access_key"Output Behavior (Important)
After video generation succeeds, you MUST display the video directly to the user!
When generation completes, output in the following format:
\\\`markdown Generated Video:
Download Video
Generation Info:
- Prompt: [User's original prompt]
- Duration: [Video length in seconds]
- Mode: [Generation mode used]
- FPS: [Frames per second]
- Save Path: [Local file path, if applicable]
\\\`
Example Output
\\\`markdown Generated Video:
Generation Info:
- Prompt: A golden retriever running through a field of sunflowers, warm afternoon sunlight
- Duration: 5 seconds
- Mode: t2v_720p
- FPS: 24
- Save Path: /generated_videos/dog_sunflowers.mp4
## API Configuration
| Parameter | Value | Description |
|-----------|-------|-------------|
| Endpoint | \`https://visual.volcengineapi.com\` | API base URL |
| Submit Action | \`CVSync2AsyncSubmitTask\` | Submit async generation task |
| Query Action | \`CVSync2AsyncGetResult\` | Query task result |
| Version | \`2022-08-31\` | API version |
| Service | \`cv\` | Service name for signing |
| Region | \`cn-north-1\` | Region for signing |
## Generation Modes
### Pro Version (1080P HD)
| Mode | req_key | Description |
|------|---------|-------------|
| `ti2v_pro` | `jimeng_ti2v_v30_pro` | Text-to-video + Image-to-video (first frame) Pro |
### 1080P Version
| Mode | req_key | Description |
|------|---------|-------------|
| `t2v_1080p` | `jimeng_t2v_v30_1080p` | Text-to-video 1080P |
| `i2v_first_1080p` | `jimeng_i2v_first_v30_1080` | Image-to-video (first frame) 1080P |
| `i2v_first_tail_1080p` | `jimeng_i2v_first_tail_v30_1080` | Image-to-video (first & last frame) 1080P |
### 720P Version
| Mode | req_key | Description |
|------|---------|-------------|
| `t2v_720p` | `jimeng_t2v_v30` | Text-to-video 720P |
| `i2v_first_720p` | `jimeng_i2v_first_v30` | Image-to-video (first frame) 720P |
| `i2v_first_tail_720p` | `jimeng_i2v_first_tail_v30` | Image-to-video (first & last frame) 720P |
| `i2v_recamera_720p` | `jimeng_i2v_recamera_v30` | Image-to-video (camera movement) 720P |
## Command-Line Options
\`\`\`
scripts/generate_video.py PROMPT [OPTIONS]
Arguments:
PROMPT Text prompt for video generation (required)
Options:
--mode MODE Generation mode (default: t2v_720p)
Pro: ti2v_pro
1080P: t2v_1080p, i2v_first_1080p, i2v_first_tail_1080p
720P: t2v_720p, i2v_first_720p, i2v_first_tail_720p, i2v_recamera_720p
--duration SECS Video duration: 4, 5, 6, 8, 10 (default: 5)
--fps FPS Frames per second: 24, 25, 30 (default: 24)
--image URL Input image URL for image-to-video (first frame)
--tail-image URL Tail image URL for first & last frame mode
--seed INT Random seed for reproducibility
--output PATH Download video to file
--json Output raw JSON response
Environment Variables:
VOLC_ACCESSKEY Access Key ID (required)
VOLC_SECRETKEY Secret Access Key (required)
JIMENG_VIDEO_API_URL API endpoint (default: https://visual.volcengineapi.com)
JIMENG_VIDEO_API_TIMEOUT Request timeout seconds (default: 300)
JIMENG_VIDEO_POLL_INTERVAL Polling interval seconds (default: 5)
JIMENG_VIDEO_MAX_POLL_ATTEMPTS Max polling attempts (default: 120)
\`\`\`
## Video Specifications
### Duration Options
| Duration | Use Case |
|----------|----------|
| 4s | Quick clips, social media |
| 5s | Default, general purpose |
| 6s | Short scenes |
| 8s | Medium-length content |
| 10s | Longer narratives |
### FPS Options
| FPS | Use Case |
|-----|----------|
| 24 | Cinematic look (default) |
| 25 | PAL video standard |
| 30 | Smooth motion, NTSC standard |
## Authentication
This skill uses Volcengine IAM v4 signature authentication (HMAC-SHA256). The signing process:
1. Build canonical request with headers: \`content-type;host;x-content-sha256;x-date\`
2. Calculate SHA256 hash of canonical request
3. Derive signing key: secret_key → date → region → service → "request"
4. Sign the string-to-sign with derived key
5. Add \`Authorization\` header to request
Reference: [HTTP请求示例](https://www.volcengine.com/docs/6444/1390583)
## Error Codes
| Code | Message | Description |
|------|---------|-------------|
| 10000 | Success | Request successful |
| 50411 | Pre Img Risk Not Pass | Input image failed content check |
| 50511 | Post Video Risk Not Pass | Output video failed content check |
| 50412 | Text Risk Not Pass | Input text failed content check |
| 50429 | Request Has Reached API Limit | Rate limit exceeded, retry later |
| 50500 | Internal Error | Server error |
| timeout | Request timeout | Increase JIMENG_VIDEO_API_TIMEOUT |
## Input/Output Limits
**Input Images (for image-to-video):**
- Format: JPEG, PNG only
- Max size: 15MB per image
- Max resolution: 4096×4096
**Output:**
- Format: MP4
- URL validity: 24 hours
- Generation time: 2-10 minutes depending on duration and mode
## Reference Documentation
- [Jimeng Video 3.0 Pro API Documentation](https://www.volcengine.com/docs/85621/1777001)
- [Jimeng Video 3.0 720P API](https://www.volcengine.com/docs/85621/1792710)
- [Jimeng Video 3.0 1080P API](https://www.volcengine.com/docs/85621/1792711)
- [HTTP Request Example](https://www.volcengine.com/docs/6444/1390583)
- [Volcengine Console](https://console.volcengine.com)
- [API Key Management](https://console.volcengine.com/iam/key_manage/)
# Role: Jimeng AI Video Generation Expert
## Core Principles
- You are an AI Video Generation Specialist using Volcengine Jimeng Video API 3.0 Pro
- Priority: Quality, Speed, and User Experience
- Always display generated video links directly to users
## Output Behavior (Important)
**After video generation succeeds, you MUST display the video directly to the user!**
When generation completes, output in the following format:
```markdown
**Generated Video:**
[Download Video](VIDEO_URL)
**Generation Info:**
- Prompt: [User's original prompt]
- Duration: [Video length in seconds]
- Mode: [Generation mode used]
- FPS: [Frames per second]
- Save Path: [Local file path, if applicable]
```
## Technical Specifications
### API Configuration
- Endpoint: `https://visual.volcengineapi.com`
- Model: `jimeng_high_aes` (Text-to-video Pro)
- Authentication: Volcengine IAM v4 signature (HMAC-SHA256)
### Generation Modes
| Mode | Description |
|------|-------------|
| t2v_pro | Text-to-video Pro (highest quality, default) |
| t2v_720p | Text-to-video 720P |
| t2v_1080p | Text-to-video 1080P |
| i2v_pro | Image-to-video Pro |
| i2v_720p | Image-to-video 720P |
| i2v_1080p | Image-to-video 1080P |
### Video Options
- Duration: 4, 5, 6, 8, 10 seconds
- FPS: 24 (cinematic), 25 (PAL), 30 (smooth)
## Command Usage
```bash
# Text-to-video (Pro quality)
scripts/generate_video.py "your prompt here"
# Specify duration and FPS
scripts/generate_video.py "prompt" --duration 10 --fps 30
# Image-to-video
scripts/generate_video.py "motion description" --image https://example.com/input.jpg
# Save to file
scripts/generate_video.py "prompt" --output generated_videos/video.mp4
```
## Constraints
**Input:**
- Prompt: text description of the video
- Images: JPEG/PNG only, ≤15MB, ≤4096×4096
**Output:**
- Format: MP4
- URL validity: 24 hours
- Generation time: 2-10 minutes
## Error Handling
| Code | Message | Action |
|------|---------|--------|
| 50411 | Pre Img Risk Not Pass | Check input image content |
| 50511 | Post Video Risk Not Pass | Modify prompt, retry |
| 50412 | Text Risk Not Pass | Modify sensitive words |
| 50429 | Rate limit | Wait and retry |
| timeout | Request timeout | Increase JIMENG_VIDEO_API_TIMEOUT |
## Environment Variables
Required:
- `VOLC_ACCESSKEY` - Access Key ID
- `VOLC_SECRETKEY` - Secret Access Key
Optional:
- `JIMENG_VIDEO_API_URL` - API endpoint
- `JIMENG_VIDEO_API_TIMEOUT` - Timeout seconds (default: 300)
- `JIMENG_VIDEO_POLL_INTERVAL` - Poll interval (default: 5)
# Role: Jimeng AI Video Generation Expert
## Core Principles
- You are an AI Video Generation Specialist using Volcengine Jimeng Video API 3.0 Pro
- Priority: Quality, Speed, and User Experience
- Always display generated video links directly to users
## Output Behavior (Important)
**After video generation succeeds, you MUST display the video directly to the user!**
When generation completes, output in the following format:
```markdown
**Generated Video:**
[Download Video](VIDEO_URL)
**Generation Info:**
- Prompt: [User's original prompt]
- Duration: [Video length in seconds]
- Mode: [Generation mode used]
- FPS: [Frames per second]
- Save Path: [Local file path, if applicable]
```
## Technical Specifications
### API Configuration
- Endpoint: `https://visual.volcengineapi.com`
- Model: `jimeng_high_aes` (Text-to-video Pro)
- Authentication: Volcengine IAM v4 signature (HMAC-SHA256)
### Generation Modes
| Mode | Description |
|------|-------------|
| t2v_pro | Text-to-video Pro (highest quality, default) |
| t2v_720p | Text-to-video 720P |
| t2v_1080p | Text-to-video 1080P |
| i2v_pro | Image-to-video Pro |
| i2v_720p | Image-to-video 720P |
| i2v_1080p | Image-to-video 1080P |
### Video Options
- Duration: 4, 5, 6, 8, 10 seconds
- FPS: 24 (cinematic), 25 (PAL), 30 (smooth)
## Command Usage
```bash
# Text-to-video (Pro quality)
scripts/generate_video.py "your prompt here"
# Specify duration and FPS
scripts/generate_video.py "prompt" --duration 10 --fps 30
# Image-to-video
scripts/generate_video.py "motion description" --image https://example.com/input.jpg
# Save to file
scripts/generate_video.py "prompt" --output generated_videos/video.mp4
```
## Constraints
**Input:**
- Prompt: text description of the video
- Images: JPEG/PNG only, ≤15MB, ≤4096×4096
**Output:**
- Format: MP4
- URL validity: 24 hours
- Generation time: 2-10 minutes
## Error Handling
| Code | Message | Action |
|------|---------|--------|
| 50411 | Pre Img Risk Not Pass | Check input image content |
| 50511 | Post Video Risk Not Pass | Modify prompt, retry |
| 50412 | Text Risk Not Pass | Modify sensitive words |
| 50429 | Rate limit | Wait and retry |
| timeout | Request timeout | Increase JIMENG_VIDEO_API_TIMEOUT |
## Environment Variables
Required:
- `VOLC_ACCESSKEY` - Access Key ID
- `VOLC_SECRETKEY` - Secret Access Key
Optional:
- `JIMENG_VIDEO_API_URL` - API endpoint
- `JIMENG_VIDEO_API_TIMEOUT` - Timeout seconds (default: 300)
- `JIMENG_VIDEO_POLL_INTERVAL` - Poll interval (default: 5)
# Role: Jimeng AI Video Generation Expert
## Core Principles
- You are an AI Video Generation Specialist using Volcengine Jimeng Video API 3.0 Pro
- Priority: Quality, Speed, and User Experience
- Always display generated video links directly to users
## Output Behavior (Important)
**After video generation succeeds, you MUST display the video directly to the user!**
When generation completes, output in the following format:
```markdown
**Generated Video:**
[Download Video](VIDEO_URL)
**Generation Info:**
- Prompt: [User's original prompt]
- Duration: [Video length in seconds]
- Mode: [Generation mode used]
- FPS: [Frames per second]
- Save Path: [Local file path, if applicable]
```
## Technical Specifications
### API Configuration
- Endpoint: `https://visual.volcengineapi.com`
- Model: `jimeng_high_aes` (Text-to-video Pro)
- Authentication: Volcengine IAM v4 signature (HMAC-SHA256)
### Generation Modes
| Mode | Description |
|------|-------------|
| t2v_pro | Text-to-video Pro (highest quality, default) |
| t2v_720p | Text-to-video 720P |
| t2v_1080p | Text-to-video 1080P |
| i2v_pro | Image-to-video Pro |
| i2v_720p | Image-to-video 720P |
| i2v_1080p | Image-to-video 1080P |
### Video Options
- Duration: 4, 5, 6, 8, 10 seconds
- FPS: 24 (cinematic), 25 (PAL), 30 (smooth)
## Command Usage
```bash
# Text-to-video (Pro quality)
scripts/generate_video.py "your prompt here"
# Specify duration and FPS
scripts/generate_video.py "prompt" --duration 10 --fps 30
# Image-to-video
scripts/generate_video.py "motion description" --image https://example.com/input.jpg
# Save to file
scripts/generate_video.py "prompt" --output generated_videos/video.mp4
```
## Constraints
**Input:**
- Prompt: text description of the video
- Images: JPEG/PNG only, ≤15MB, ≤4096×4096
**Output:**
- Format: MP4
- URL validity: 24 hours
- Generation time: 2-10 minutes
## Error Handling
| Code | Message | Action |
|------|---------|--------|
| 50411 | Pre Img Risk Not Pass | Check input image content |
| 50511 | Post Video Risk Not Pass | Modify prompt, retry |
| 50412 | Text Risk Not Pass | Modify sensitive words |
| 50429 | Rate limit | Wait and retry |
| timeout | Request timeout | Increase JIMENG_VIDEO_API_TIMEOUT |
## Environment Variables
Required:
- `VOLC_ACCESSKEY` - Access Key ID
- `VOLC_SECRETKEY` - Secret Access Key
Optional:
- `JIMENG_VIDEO_API_URL` - API endpoint
- `JIMENG_VIDEO_API_TIMEOUT` - Timeout seconds (default: 300)
- `JIMENG_VIDEO_POLL_INTERVAL` - Poll interval (default: 5)
{
"name": "jimeng-api-video-gen",
"version": "1.0.0",
"description": "AI video generation skill using Volcengine Jimeng Video API 3.0 Pro",
"author": "workspace",
"license": "MIT",
"keywords": [
"jimeng",
"ai-video",
"video-generation",
"volcengine",
"text-to-video",
"image-to-video",
"cursor-rules",
"opencode-skill"
],
"main": "index.js",
"files": [
".antigravityrules",
".cursorrules",
".opencode-rules",
"README.md",
"SKILL.md"
]
}
Jimeng API Video Generation
Generate high-quality AI videos using Volcengine's Jimeng Video 3.0 Pro API.
Features
- Text-to-video generation with customizable prompts
- Image-to-video (first frame as reference)
- Image-to-video (first and last frame)
- Camera movement control for image-to-video
- Multiple resolution presets (720P, 1080P, Pro)
- Configurable duration (4-10 seconds) and FPS (24-30)
- Local file output support
Setup
1. Get API Credentials
2. Configure Environment Variables
# ~/.zshrc or ~/.zshenv
export VOLC_ACCESSKEY="your_access_key_id"
export VOLC_SECRETKEY="your_secret_access_key"Optional Configuration
export JIMENG_VIDEO_API_URL="https://visual.volcengineapi.com"
export JIMENG_VIDEO_API_TIMEOUT=300
export JIMENG_VIDEO_POLL_INTERVAL=5
export JIMENG_VIDEO_MAX_POLL_ATTEMPTS=120Usage
Text-to-Video
# Basic usage (720P, 5 seconds, 24 FPS)
scripts/generate_video.py "A golden retriever running through a field of sunflowers"
# 1080P HD video
scripts/generate_video.py "Ocean waves crashing on a beach at sunset" --mode t2v_1080p
# Longer video with higher FPS
scripts/generate_video.py "A butterfly landing on a flower" --duration 10 --fps 30
# Save to file
scripts/generate_video.py "City timelapse at night" --output city_timelapse.mp4Image-to-Video
# First frame as reference
scripts/generate_video.py "Make the image come to life" --image https://example.com/photo.jpg
# First and last frame (transition)
scripts/generate_video.py "Smooth transition" --image https://example.com/start.jpg --tail-image https://example.com/end.jpg
# Camera movement effect
scripts/generate_video.py "Zoom in slowly" --image https://example.com/landscape.jpg --mode i2v_recamera_720pPro Mode
# High quality Pro mode (supports both text and image input)
scripts/generate_video.py "Cinematic drone shot of mountains" --mode ti2v_pro --duration 8
scripts/generate_video.py "Animate this scene" --mode ti2v_pro --image https://example.com/scene.jpgCommand-Line Options
scripts/generate_video.py PROMPT [OPTIONS]
Arguments:
PROMPT Text prompt for video generation (required)
Options:
--mode MODE Generation mode (default: t2v_720p)
Pro: ti2v_pro
1080P: t2v_1080p, i2v_first_1080p, i2v_first_tail_1080p
720P: t2v_720p, i2v_first_720p, i2v_first_tail_720p, i2v_recamera_720p
--duration SECS Video duration: 4, 5, 6, 8, 10 (default: 5)
--fps FPS Frames per second: 24, 25, 30 (default: 24)
--image URL Input image URL for image-to-video (first frame)
--tail-image URL Tail image URL for first & last frame mode
--seed INT Random seed for reproducibility
--output PATH Download video to file
--json Output raw JSON responseGeneration Modes
Pro Version (1080P HD)
| Mode | Description |
|---|---|
ti2v_pro | Text-to-video + Image-to-video (first frame) Pro |
1080P Version
| Mode | Description |
|---|---|
t2v_1080p | Text-to-video 1080P |
i2v_first_1080p | Image-to-video (first frame) 1080P |
i2v_first_tail_1080p | Image-to-video (first & last frame) 1080P |
720P Version
| Mode | Description |
|---|---|
t2v_720p | Text-to-video 720P |
i2v_first_720p | Image-to-video (first frame) 720P |
i2v_first_tail_720p | Image-to-video (first & last frame) 720P |
i2v_recamera_720p | Image-to-video (camera movement) 720P |
Video Specifications
Duration Options
| Duration | Use Case |
|---|---|
| 4s | Quick clips, social media |
| 5s | Default, general purpose |
| 6s | Short scenes |
| 8s | Medium-length content |
| 10s | Longer narratives |
FPS Options
| FPS | Use Case |
|---|---|
| 24 | Cinematic look (default) |
| 25 | PAL video standard |
| 30 | Smooth motion, NTSC standard |
Limits
Input (for image-to-video)
- Format: JPEG, PNG only
- Max size: 15MB per image
- Max resolution: 4096×4096
Output
- Format: MP4
- URL validity: 24 hours
- Generation time: 2-10 minutes depending on duration and mode
Error Handling
| Code | Message | Solution |
|---|---|---|
| 50411 | Pre Img Risk Not Pass | Check input image content |
| 50511 | Post Video Risk Not Pass | Modify prompt and retry |
| 50412 | Text Risk Not Pass | Remove sensitive words |
| 50429 | Rate limit exceeded | Wait and retry |
| timeout | Request timeout | Increase JIMENG_VIDEO_API_TIMEOUT |
Reference Documentation
#!/usr/bin/env python3
"""
Volcengine Jimeng Video Generation 3.0 Pro Script
API Flow: Submit task → Poll for results
Docs: https://www.volcengine.com/docs/85621/1777001
"""
import requests
import os
import sys
import json
import argparse
import time
from typing import Optional, List, Dict, Any
from urllib.parse import urlparse
from pathlib import Path
script_dir = Path(__file__).parent
sys.path.insert(0, str(script_dir))
try:
from volcengine_signer import VolcengineSigner
HAS_SIGNER = True
except ImportError:
HAS_SIGNER = False
VolcengineSigner = None
class JimengVideoGenerator:
"""Client for Volcengine Jimeng Video Generation 3.0 Pro API"""
SUBMIT_ACTION = "CVSync2AsyncSubmitTask"
QUERY_ACTION = "CVSync2AsyncGetResult"
API_VERSION = "2022-08-31"
# Video generation req_key options
# Pro version: jimeng_high_aes (text-to-video Pro)
# Standard: jimeng_t2v_v30 (text-to-video 3.0)
# Image-to-video: jimeng_i2v_v30
REQ_KEYS = {
"t2v_pro": "jimeng_high_aes", # Text-to-video Pro (high quality)
"t2v_720p": "jimeng_t2v_v30", # Text-to-video 720P
"t2v_1080p": "jimeng_t2v_v30_1080p", # Text-to-video 1080P
"i2v_pro": "jimeng_i2v_pro", # Image-to-video Pro
"i2v_720p": "jimeng_i2v_v30", # Image-to-video 720P
"i2v_1080p": "jimeng_i2v_v30_1080p", # Image-to-video 1080P
}
# Video duration options (in seconds)
DURATION_OPTIONS = [4, 5, 6, 8, 10]
# FPS options
FPS_OPTIONS = [24, 25, 30]
# Resolution options
RESOLUTION_OPTIONS = {
"720p": (1280, 720),
"1080p": (1920, 1080),
"pro": (1920, 1080), # Pro uses 1080p base
}
def __init__(
self,
access_key: Optional[str] = None,
secret_key: Optional[str] = None,
):
self.access_key = access_key or os.environ.get("VOLC_ACCESSKEY")
self.secret_key = secret_key or os.environ.get("VOLC_SECRETKEY")
if not self.access_key or not self.secret_key:
raise ValueError(
"Access Key and Secret Key required. "
"Set VOLC_ACCESSKEY and VOLC_SECRETKEY environment variables."
)
if not HAS_SIGNER:
raise ImportError(
"volcengine_signer module not found. "
"Make sure volcengine_signer.py is in the same directory."
)
self.service = "cv"
self.region = "cn-north-1"
self.base_url = os.environ.get(
"JIMENG_VIDEO_API_URL", "https://visual.volcengineapi.com"
)
self.timeout = int(os.environ.get("JIMENG_VIDEO_API_TIMEOUT", "300"))
self.poll_interval = int(os.environ.get("JIMENG_VIDEO_POLL_INTERVAL", "5"))
self.max_poll_attempts = int(
os.environ.get("JIMENG_VIDEO_MAX_POLL_ATTEMPTS", "120")
)
def _make_request(
self,
action: str,
payload: Dict[str, Any],
) -> Dict[str, Any]:
body = json.dumps(payload).encode("utf-8")
parsed_url = urlparse(self.base_url)
path = parsed_url.path or "/"
headers = {
"Content-Type": "application/json",
"Host": parsed_url.netloc,
}
if VolcengineSigner is None:
raise RuntimeError("VolcengineSigner not available")
assert self.access_key is not None
assert self.secret_key is not None
query_params = {
"Action": action,
"Version": self.API_VERSION,
}
headers = VolcengineSigner.sign_request(
method="POST",
url=path,
headers=headers,
body=body,
access_key=self.access_key,
secret_key=self.secret_key,
service=self.service,
region=self.region,
query_params=query_params,
)
try:
response = requests.post(
self.base_url,
params=query_params,
data=body,
headers=headers,
timeout=self.timeout,
)
result = response.json()
return result
except requests.exceptions.Timeout:
return {
"code": "timeout",
"message": f"Request timed out after {self.timeout} seconds",
}
except requests.exceptions.RequestException as e:
return {
"code": "request_failed",
"message": str(e),
}
except json.JSONDecodeError as e:
return {
"code": "json_error",
"message": f"Failed to parse response: {e}",
}
def submit_task(
self,
prompt: str,
req_key: str = "jimeng_high_aes",
video_duration: int = 5,
fps: int = 24,
input_image: Optional[str] = None,
seed: Optional[int] = None,
) -> Dict[str, Any]:
"""Submit a video generation task"""
payload: Dict[str, Any] = {
"req_key": req_key,
"prompt": prompt,
}
# Video duration (default 5 seconds)
if video_duration in self.DURATION_OPTIONS:
payload["video_duration"] = video_duration
else:
payload["video_duration"] = 5
# FPS setting
if fps in self.FPS_OPTIONS:
payload["fps"] = fps
# Input image for image-to-video
if input_image:
payload["image_url"] = input_image
# Random seed for reproducibility
if seed is not None:
payload["seed"] = seed
result = self._make_request(self.SUBMIT_ACTION, payload)
if result.get("code") != 10000:
return {
"success": False,
"error": {
"code": result.get("code", "unknown"),
"message": result.get("message", str(result)),
},
}
return {
"success": True,
"task_id": result.get("data", {}).get("task_id"),
}
def query_task(
self,
task_id: str,
req_key: str = "jimeng_high_aes",
) -> Dict[str, Any]:
"""Query the status of a video generation task"""
payload: Dict[str, Any] = {
"req_key": req_key,
"task_id": task_id,
}
return self._make_request(self.QUERY_ACTION, payload)
def generate(
self,
prompt: str,
mode: str = "t2v_720p",
video_duration: int = 5,
fps: int = 24,
input_image: Optional[str] = None,
seed: Optional[int] = None,
) -> Dict[str, Any]:
"""Generate a video from text or image"""
# Determine req_key based on mode
req_key = self.REQ_KEYS.get(mode, "jimeng_high_aes")
submit_result = self.submit_task(
prompt=prompt,
req_key=req_key,
video_duration=video_duration,
fps=fps,
input_image=input_image,
seed=seed,
)
if not submit_result.get("success"):
return submit_result
task_id = submit_result.get("task_id")
if not task_id:
return {
"success": False,
"error": {
"code": "no_task_id",
"message": "No task_id returned from submit",
},
}
print(f"Task submitted: {task_id}", file=sys.stderr)
for attempt in range(self.max_poll_attempts):
result = self.query_task(task_id, req_key=req_key)
if result.get("code") != 10000:
return {
"success": False,
"error": {
"code": result.get("code", "unknown"),
"message": result.get("message", str(result)),
},
"task_id": task_id,
}
status = result.get("data", {}).get("status", "")
if status == "done":
video_url = result.get("data", {}).get("video_url")
return {
"success": True,
"task_id": task_id,
"video_url": video_url,
"data": result.get("data", {}),
}
elif status in ["not_found", "expired"]:
return {
"success": False,
"error": {
"code": status,
"message": f"Task {status}",
},
"task_id": task_id,
}
# Show progress
if attempt % 12 == 0: # Every minute (at 5s intervals)
elapsed = attempt * self.poll_interval
print(f"Still processing... ({elapsed}s elapsed)", file=sys.stderr)
time.sleep(self.poll_interval)
return {
"success": False,
"error": {
"code": "timeout",
"message": f"Polling timed out after {self.max_poll_attempts} attempts",
},
"task_id": task_id,
}
def download_video(self, url: str, output_path: str) -> bool:
"""Download generated video to local file"""
try:
response = requests.get(url, timeout=120, stream=True)
response.raise_for_status()
with open(output_path, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
return True
except Exception as e:
print(f"Failed to download video: {e}", file=sys.stderr)
return False
def main():
parser = argparse.ArgumentParser(
description="Generate videos using Volcengine Jimeng 3.0 Pro API",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Text-to-video (Pro quality)
%(prog)s "一只可爱的柴犬在樱花树下奔跑,阳光温暖,治愈系风格"
# Specify duration and FPS
%(prog)s "A serene lake at sunset" --duration 10 --fps 30
# Image-to-video
%(prog)s "The character starts walking forward" --image https://example.com/character.png
# Use 720P mode
%(prog)s "A beautiful sunset" --mode t2v_720p
# Save to file
%(prog)s "Mountain landscape timelapse" --output video.mp4
Modes:
t2v_pro - Text-to-video Pro (highest quality)
t2v_720p - Text-to-video 720P (default)
t2v_1080p - Text-to-video 1080P
i2v_pro - Image-to-video Pro
i2v_720p - Image-to-video 720P
i2v_1080p - Image-to-video 1080P
Environment Variables:
VOLC_ACCESSKEY Volcengine Access Key ID (required)
VOLC_SECRETKEY Volcengine Secret Access Key (required)
JIMENG_VIDEO_API_URL API endpoint (default: https://visual.volcengineapi.com)
JIMENG_VIDEO_API_TIMEOUT Request timeout seconds (default: 300)
JIMENG_VIDEO_POLL_INTERVAL Polling interval seconds (default: 5)
JIMENG_VIDEO_MAX_POLL_ATTEMPTS Max polling attempts (default: 120)
""",
)
parser.add_argument("prompt", help="Text prompt for video generation")
parser.add_argument(
"--mode",
default="t2v_720p",
choices=list(JimengVideoGenerator.REQ_KEYS.keys()),
help="Generation mode (default: default)",
)
parser.add_argument(
"--duration",
type=int,
default=5,
choices=JimengVideoGenerator.DURATION_OPTIONS,
help="Video duration in seconds (default: 5)",
)
parser.add_argument(
"--fps",
type=int,
default=24,
choices=JimengVideoGenerator.FPS_OPTIONS,
help="Frames per second (default: 24)",
)
parser.add_argument(
"--image",
help="Input image URL for image-to-video generation",
)
parser.add_argument(
"--seed",
type=int,
help="Random seed for reproducibility",
)
parser.add_argument("--output", "-o", help="Download video to specified file path")
parser.add_argument("--json", action="store_true", help="Output raw JSON response")
args = parser.parse_args()
try:
client = JimengVideoGenerator()
print(f"Generating video with prompt: {args.prompt}", file=sys.stderr)
print(
f"Mode: {args.mode}, Duration: {args.duration}s, FPS: {args.fps}",
file=sys.stderr,
)
result = client.generate(
prompt=args.prompt,
mode=args.mode,
video_duration=args.duration,
fps=args.fps,
input_image=args.image,
seed=args.seed,
)
if args.json:
print(json.dumps(result, indent=2, ensure_ascii=False))
return
if result.get("success"):
video_url = result.get("video_url")
task_id = result.get("task_id")
print(f"✓ Generated video [task: {task_id}]")
if video_url:
print(f" URL: {video_url}")
if args.output and video_url:
print(f" Downloading to: {args.output}...", file=sys.stderr)
if client.download_video(video_url, args.output):
print(f" Saved to: {args.output}")
else:
error = result.get("error", {})
print(
f"✗ Error [{error.get('code')}]: {error.get('message')}",
file=sys.stderr,
)
sys.exit(1)
except ValueError as e:
print(f"✗ Configuration error: {e}", file=sys.stderr)
sys.exit(1)
except KeyboardInterrupt:
print("\n✗ Interrupted by user", file=sys.stderr)
sys.exit(130)
except Exception as e:
print(f"✗ Unexpected error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Volcengine IAM v4 Signature Authentication
Based on official Volcengine HTTP request example
Reference: https://www.volcengine.com/docs/6444/1390583
"""
import hashlib
import hmac
import datetime
from typing import Dict, Optional
class VolcengineSigner:
"""Volcengine IAM v4 signature authentication"""
ALGORITHM = "HMAC-SHA256"
@staticmethod
def sign_request(
method: str,
url: str,
headers: Dict[str, str],
body: bytes,
access_key: str,
secret_key: str,
service: str = "cv",
region: str = "cn-north-1",
query_params: Optional[Dict[str, str]] = None,
) -> Dict[str, str]:
"""
Sign HTTP request with Volcengine IAM v4 signature
Args:
method: HTTP method (GET, POST, etc.)
url: Request URL path (without query string)
headers: Request headers dict
body: Request body as bytes
access_key: Volcengine Access Key ID
secret_key: Volcengine Secret Access Key
service: Service name (default: cv for 即梦AI)
region: Region name (default: cn-north-1)
query_params: Query parameters dict (optional)
Returns:
Updated headers dict with X-Date and Authorization
"""
# Get current UTC time
now = datetime.datetime.utcnow()
x_date = now.strftime("%Y%m%dT%H%M%SZ")
short_date = x_date[:8]
# Calculate payload hash
payload_hash = hashlib.sha256(body).hexdigest()
# Build headers dict - MUST include these headers per official docs
headers = headers.copy()
headers["X-Date"] = x_date
headers["X-Content-Sha256"] = payload_hash
# Signed headers MUST be in this exact order per official documentation
# content-type;host;x-content-sha256;x-date
signed_headers_list = ["content-type", "host", "x-content-sha256", "x-date"]
# Build canonical query string
canonical_query_string = ""
if query_params:
# Sort by parameter name and encode
sorted_params = sorted(query_params.items())
canonical_query_string = "&".join(
f"{VolcengineSigner._uri_encode(str(k))}={VolcengineSigner._uri_encode(str(v))}"
for k, v in sorted_params
)
# Build canonical headers string - must match signed_headers_list order
canonical_headers_parts = []
for h in signed_headers_list:
if h == "content-type":
canonical_headers_parts.append(
f"content-type:{headers.get('Content-Type', 'application/json')}"
)
elif h == "host":
canonical_headers_parts.append(f"host:{headers.get('Host', '')}")
elif h == "x-content-sha256":
canonical_headers_parts.append(f"x-content-sha256:{payload_hash}")
elif h == "x-date":
canonical_headers_parts.append(f"x-date:{x_date}")
canonical_headers = "\n".join(canonical_headers_parts) + "\n"
signed_headers = ";".join(signed_headers_list)
# Build canonical request
canonical_request = "\n".join(
[
method,
url, # path
canonical_query_string, # query string
canonical_headers,
signed_headers,
payload_hash,
]
)
# Calculate canonical request hash
canonical_request_hash = hashlib.sha256(
canonical_request.encode("utf-8")
).hexdigest()
# Build string to sign
credential_scope = f"{short_date}/{region}/{service}/request"
string_to_sign = "\n".join(
[
VolcengineSigner.ALGORITHM,
x_date,
credential_scope,
canonical_request_hash,
]
)
# Calculate signature
signing_key = VolcengineSigner._get_signing_key(
secret_key, short_date, region, service
)
signature = hmac.new(
signing_key, string_to_sign.encode("utf-8"), hashlib.sha256
).hexdigest()
# Build Authorization header
authorization = (
f"{VolcengineSigner.ALGORITHM} "
f"Credential={access_key}/{credential_scope}, "
f"SignedHeaders={signed_headers}, "
f"Signature={signature}"
)
headers["Authorization"] = authorization
return headers
@staticmethod
def _uri_encode(s: str) -> str:
"""URI encode following AWS v4 signing spec"""
# Safe characters that don't need encoding
safe = "-_.~"
result = []
for c in s:
if c.isalnum() or c in safe:
result.append(c)
else:
for byte in c.encode("utf-8"):
result.append(f"%{byte:02X}")
return "".join(result)
@staticmethod
def _get_signing_key(
secret_key: str, date: str, region: str, service: str
) -> bytes:
"""Derive signing key from secret key"""
k_date = hmac.new(
secret_key.encode("utf-8"), date.encode("utf-8"), hashlib.sha256
).digest()
k_region = hmac.new(k_date, region.encode("utf-8"), hashlib.sha256).digest()
k_service = hmac.new(k_region, service.encode("utf-8"), hashlib.sha256).digest()
k_signing = hmac.new(k_service, b"request", hashlib.sha256).digest()
return k_signing