åç»çæAPIã®äœ¿ãæ¹ïŒãžã§ããæããŠãåŸ ã£ãŠãåãåã
åç»çæã¯ããªã¯ãšã¹ããæããŠãã®å Žã§çµæãè¿ãAPIã§ã¯ãããŸããã ã¬ã³ããªã³ã°ã«æ°åãããããããžã§ããäœæããŠIDãåãåãã宿ãããŸã§ããŒãªã³ã°ãã宿ãããMP4ãããŠã³ããŒãããââãšãã3段æ§ãã«ãªããŸãã
ãã£ãããç»åçæãšã¯äœããéãã®ã§ããã®èšäºã§ã¯æµããšå®è£ äžã®æ³šæç¹ãæŽçããŸãã
3ã€ã®ã¹ããã
1. POST /v1/videos/create â job_id ãè¿ãïŒããã§èª²éïŒ
â
2. GET /v1/videos/jobs/<id> â status ã確èªïŒç¡æã»ç¹°ãè¿ãïŒ
â
3. GET /v1/videos/jobs/<id>/content?index=0 â MP4ïŒç¡æïŒ
ãã£ããã® /v1/chat/completions ãšã¯ãã¹ã®ç³»çµ±ãéãç¹ã«æ³šæããŠãã ãããèªèšŒã¯åãAPIããŒã§ãã
ã¹ããã1ïŒãžã§ããäœæãã
curl -X POST https://api.fastmetal.ai/v1/videos/create \
-H "Authorization: Bearer $FASTMETAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bytedance/seedance-2.0-fast",
"prompt": "溶ããéå±ãåã«æµãèŸŒãæ§åã®ã¯ããŒãºã¢ãã"
}'
æåæã¯ HTTP 202 ãè¿ããããã£ã« idïŒãžã§ãIDïŒãš status ãå
¥ã£ãŠããŸãã200ã§ã¯ãªãã®ã§ãstatus_code == 200 ã§å€å®ããŠããã³ãŒãã¯å€±ææ±ãã«ããŠããŸããŸãã
è¿ã£ãŠãããžã§ãIDãä¿åããŠãã ããããã®IDããæ¯æã£ã1æ¬ã¶ãã®åŒãæãåžã§ãã 倱ããšãçæäžã®åç»ãåãåºãææ®µããªããªããŸãã
è§£å床ãé·ããšãã£ããã©ã¡ãŒã¿ã¯ãã¢ãã«ããšã«ãµãŒããŒåŽã§åºå®ãããŠããŸããprompt ãš model ãéãã ãã§ããããã¯èª²éã1æ¬ãããã®å®é¡ã«åºå®ããããã®èšèšã§ããã©ã¡ãŒã¿æ¬¡ç¬¬ã§äŸ¡æ Œãå€ããããšããããŸããã
ã¹ããã2ïŒå®æãŸã§ããŒãªã³ã°ãã
curl https://api.fastmetal.ai/v1/videos/jobs/<JOB_ID> \
-H "Authorization: Bearer $FASTMETAL_API_KEY"
status ãå®äºã瀺ããŸã§ç¹°ãè¿ããŸããããŒãªã³ã°ã¯ç¡æã§ãã 課éã¯ã¹ããã1ã§ç¢ºå®ããŠããã®ã§ãäœåç¶æ
ã確èªããŠã远å è²»çšã¯çºçããŸããã
ãšã¯ããã1ç§ééã§å©ãç¶ããå¿ èŠã¯ãããŸãããã¬ã³ããªã³ã°ã¯ååäœãªã®ã§ã5ã10ç§ééã§ååã§ãã
ã¹ããã3ïŒMP4ãããŠã³ããŒããã
curl https://api.fastmetal.ai/v1/videos/jobs/<JOB_ID>/content?index=0 \
-H "Authorization: Bearer $FASTMETAL_API_KEY" \
-o out.mp4
ãã¡ããç¡æã§ããindex=0 ã1æ¬ç®ã®åç»ãæããŸãã
Pythonã§ãŸãšããŠ
import os, time, requests
BASE = "https://api.fastmetal.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['FASTMETAL_API_KEY']}"}
def generate_video(prompt: str, model: str = "bytedance/seedance-2.0-fast",
timeout_s: int = 900, interval_s: int = 10) -> bytes:
# 1. ãžã§ããäœæïŒããã§èª²éãããïŒ
r = requests.post(
f"{BASE}/v1/videos/create",
headers=HEADERS,
json={"model": model, "prompt": prompt},
timeout=60,
)
r.raise_for_status()
job_id = r.json()["id"]
print(f"job_id={job_id}") # â å¿
ãèšé²ãã
# 2. 宿ãŸã§ããŒãªã³ã°ïŒç¡æïŒ
deadline = time.time() + timeout_s
while time.time() < deadline:
s = requests.get(f"{BASE}/v1/videos/jobs/{job_id}",
headers=HEADERS, timeout=30)
s.raise_for_status()
status = s.json().get("status")
print(status)
if status in ("completed", "succeeded"):
break
if status in ("failed", "cancelled"):
raise RuntimeError(f"çæã«å€±æããŸãã: {s.json()}")
time.sleep(interval_s)
else:
raise TimeoutError(f"ã¿ã€ã ã¢ãŠããjob_id={job_id} ã§åŸããååŸã§ããŸã")
# 3. ããŠã³ããŒãïŒç¡æïŒ
c = requests.get(f"{BASE}/v1/videos/jobs/{job_id}/content",
headers=HEADERS, params={"index": 0}, timeout=300)
c.raise_for_status()
return c.content
open("out.mp4", "wb").write(generate_video("溶ããéå±ãåã«æµãèŸŒãæ§åã®ã¯ããŒãºã¢ãã"))
status ã®æååã¯ã¢ãã«ãäžæµã®ä»æ§ã§å€ããããã®ã§ãå®éã«äžåºŠå©ããŠç¢ºèªããŠããå€å®æ¡ä»¶ãåºããŠãã ãããäžã®ã³ãŒããå®äºãè€æ°ã®å€ã§èŠãŠããã®ã¯ãã®ããã§ãã
課éã¯1æ¬ãããã®å®é¡
æéäœç³»ããã£ãããšãŸã£ããéããŸãã
| æäœ | 課é |
|---|---|
| ãžã§ãäœæ | 1æ¬ãããã®å®é¡ïŒã¢ãã«ããšã«åºå®ïŒ |
| ããŒãªã³ã° | ç¡æ |
| ããŠã³ããŒã | ç¡æ |
ããŒã¯ã³æ°ãããã³ããã®é·ããäŸ¡æ Œã«åœ±é¿ããŸããã課éãããã®ã¯ã¹ããã1ã®ç¬éã§ãããããå ã¯äœåºŠç¢ºèªããŠãç¡æã§ããçŸåšã®1æ¬ãããã®äŸ¡æ Œã¯æéããŒãžã§ç¢ºèªããŠãã ããã
å®è£
äžãããã¯éèŠãªæå³ãæã¡ãŸãããžã§ãäœæã®ã¬ã¹ãã³ã¹ãåãããŒããšãæ¯æãæžã¿ã®åç»ãååã§ããªããªããŸãã ãããã¯ãŒã¯ãåããŠããªãã©ã€ããªãã§ãã ããââãªãã©ã€ã¯æ°ãããžã§ãã«ãªããäºéã«èª²éãããŸããjob_id ã¯åãåã£ãçŽåŸã«ãã°ãªã DB ãªããžæžãåºãã®ãéåã§ãã
ãšãŒãžã§ã³ããã䜿ãå Žå
ã¿ã€ã ã¢ãŠãã®åé¡ããããŸããã¬ã³ããªã³ã°ã¯ååäœãªã®ã«ãå€ãã®MCPã¯ã©ã€ã¢ã³ãã¯ãªã¯ãšã¹ãã®ã¿ã€ã ã¢ãŠãã60ç§çšåºŠã«èšå®ããŠããŸãã宿ãåŸ ã¡åãåã«ã¯ã©ã€ã¢ã³ãåŽã諊ãããšãèª²éæžã¿ã®ãžã§ãIDãèŒããã¬ã¹ãã³ã¹ããšæšãŠãããŸãã
ãã®ããMCPãµãŒããŒã® generate_video ã¯ãäžå®æéã ãåŸ
ã£ãŠãéã«åããªããã° job_id ãè¿ããŸããåŸãã get_video ã§åãã«è¡ãèšèšã§ããèªåã§å®è£
ããå Žåãåãèãæ¹ââåŸ
ã¡æéã¯ã¯ã©ã€ã¢ã³ãã®ã¿ã€ã ã¢ãŠãããçãããŠãã ããã
ã€ãŸãããããç¹
åæã§è¿ããšæã£ãŠå®è£ ãã ãžã§ãæ¹åŒã§ãã1åã®ãªã¯ãšã¹ãã§MP4ã¯è¿ããŸããã
job_id ãä¿åããŠããªã
課éã¯äœææç¹ã§ç¢ºå®ããŠããŸããIDã倱ããšåç»ã¯åãåºããŸããã
倱æãããšæã£ãŠãªãã©ã€ãã ã¬ã¹ãã³ã¹ãå±ããªãã£ãã ãã§ããžã§ãã¯åããŠããå¯èœæ§ããããŸãããªãã©ã€ãããšäºé課éã§ãããŸãæ¢åã®ãžã§ãã確èªããŠãã ããã
ããŒãªã³ã°ééãçããã ç¡æã§ãããååäœã®åŠçã1ç§ééã§å©ãæå³ã¯ãããŸããã5ã10ç§ã§ååã§ãã
ãã£ããã®æå·åäŒè©±ã§äœ¿ãããšãã ãã£ããUIã§ã¯ãæå·åãããäŒè©±ã§åç»çæã¯äœ¿ããŸãããçæããã倧ããªãã¡ã€ã«ãã¯ã©ã€ã¢ã³ãåŽã§æå·åããä»çµã¿ãæªæŽåãªããã§ãã
次ã®ã¹ããã
鿢ç»ãªãç»åçæAPIã®äœ¿ãæ¹ã®ã»ããåçŽã§ãåæã§è¿ããŸãããŸãç»åã§è©ŠããŠããåç»ã«é²ããšçè§£ãæ©ãã¯ãã§ãã
åç»çæã®æäŸéå§ã®ãç¥ããã¯ãã¡ããAPIã®è©³çްã¯ããã¥ã¡ã³ãã«ãããŸãã
ãããã質å
Q. åç»çæã¯1åã®ãªã¯ãšã¹ãã§å®çµããŸããïŒ ãããããžã§ããäœæããŠIDãåãåãã宿ãŸã§ããŒãªã³ã°ããMP4ãããŠã³ããŒããã3ã¹ãããã§ããã¬ã³ããªã³ã°ã«ã¯æ°åããããŸãã
Q. ããŒãªã³ã°ãããã³ã«èª²éãããŸããïŒ ãããŸããã課éã¯ãžã§ãäœææã®1åã ãã§ãç¶æ 確èªãšããŠã³ããŒãã¯ç¡æã§ãã
Q. ãªã¯ãšã¹ãã倱æããããã«èŠããããªãã©ã€ããŠããã§ããïŒ ãããŸãããã¬ã¹ãã³ã¹ãå±ããªãã£ãã ãã§ãžã§ãã¯é²è¡ããŠããå¯èœæ§ãããããªãã©ã€ã¯äºé課éã«ãªããŸããæ¢åã®ãžã§ããå ã«ç¢ºèªããŠãã ããã
Q. è§£å床ãé·ãã¯æå®ã§ããŸããïŒ ã¢ãã«ããšã«ãµãŒããŒåŽã§åºå®ãããŠããŸããããã«ãã1æ¬ãããã®äŸ¡æ Œãå€åããŸããã仿§ã¯ã¢ãã«ã«ã¿ãã°ãšæéããŒãžã確èªããŠãã ããã
ãŸãšã
åç»çæã¯ãäœæ â ããŒãªã³ã° â ããŠã³ããŒããã®éåæãžã§ãã§ãã課éã¯äœææã®1åã ãã§1æ¬ãããã®å®é¡ãããŒãªã³ã°ãšããŠã³ããŒãã¯ç¡æãã ãããã job_id ã®ä¿åãšã宿ã«ãªãã©ã€ããªãããšãå®è£
äžãã¡ã°ã倧äºã«ãªããŸãã
APIããŒãååŸããŠããŸã1æ¬äœã£ãŠã¿ãŠãã ããã