اپنی ایپ میں ویڈیو جنریشن شامل کرنا، امیج جنریشن شامل کرنے جیسا نہیں ہے۔ API کال فوراً جواب لوٹا دیتی ہے — لیکن ویڈیو ابھی تیار نہیں ہوتی۔ آپ کو ایک ٹاسک ID ملتی ہے، اور آپ کو یہ پوچھتے رہنا پڑتا ہے کہ "کیا یہ مکمل ہوگیا؟" جب تک کہ ہو نہ جائے۔
زیادہ تر ڈویلپر پہلی بار جب ویڈیو API کو کال کرتے ہیں تو یہ صورتحال پیش آتی ہے: وہ ویڈیو URL کے ساتھ ریسپانس باڈی کا انتظار کرتے ہیں، مگر اس کے بجائے ایک ٹاسک ID ملتی ہے۔ یہ گائیڈ پورے فلو سے گزارتی ہے: ٹاسک جمع کرانا، نتائج کے لیے پولنگ کرنا، ناکامیوں کو ہینڈل کرنا، اور URL کی معیاد ختم ہونے سے پہلے آؤٹ پٹ محفوظ کرنا۔
آپ کیا بنائیں گے
ایک بیک اینڈ سروس جو ٹیکسٹ پرامپٹ یا امیج قبول کرتی ہے، ویڈیو جنریشن ٹاسک جمع کراتی ہے، مکمل ہونے تک پول کرتی ہے، اور آخر میں ویڈیو کا URL واپس کرتی ہے۔ آپ چار ماڈلز کے ساتھ کام کریں گے — Veo 3 Fast، Sora 2، Kling Video، اور Runway — سب ایک ہی API key کے ذریعے۔
پیشگی ضروریات:
- Python 3.8+ یا Node.js 18+
- ایک CometAPI key
- REST APIs کی بنیادی واقفیت
یہ سمجھیں کہ ویڈیو جنریشن مختلف کیوں ہے
امیج جنریشن میں، آپ ریکویسٹ بھیجتے ہیں اور اسی ریسپانس میں امیج واپس مل جاتی ہے۔ ویڈیو جنریشن ایک ایسِنک ٹاسک قطار استعمال کرتی ہے:
- Submit ایک جنریشن ریکویسٹ → ایک
task_idواپس ملتا ہے - ہر چند سیکنڈ بعد ایک اسٹیٹس اینڈ پوائنٹ کو Poll کریں
- جب اسٹیٹس ٹرمینل حالت تک پہنچ جائے، آپ کو ویڈیو URL ملتا ہے
- ویڈیو کو Download اور store کریں — URL عارضی ہوتا ہے
اگر آپ ویڈیو جنریشن کو امیج جنریشن کی طرح ٹریٹ کریں اور پہلے ریسپانس میں ویڈیو آنے کا انتظار کریں، تو آپ کی ریکویسٹ ہر بار ٹائم آؤٹ ہو جائے گی۔
پروڈکشن ویب سروس میں، یہ پولنگ لوپ آپ کے ریکویسٹ ہینڈلر میں نہیں بلکہ ایک بیک گراؤنڈ ورکر (Celery، Bull یا اسی طرح) میں چلنا چاہیے۔ ذیل کی مثالیں ہم وقت پولنگ استعمال کرتی ہیں — اسکرپٹس اور پروٹوٹائپس کے لیے ٹھیک ہیں، مگر کثیر صارفین کو ہینڈل کرنے کے لیے موزوں نہیں۔
ماڈل منتخب کریں
| Model | Provider | Max duration | Price (via CometAPI) | Best for |
|---|---|---|---|---|
| Veo 3 Fast | 8 سیکنڈ | $0.05/sec | تیز پروٹوٹائپنگ، سوشل کلپس | |
| Sora 2 | OpenAI (via CometAPI model ID) | ~10 سیکنڈ | $0.08/sec | اعلیٰ معیار کی تخلیقی شارٹس |
| Kling Video | Kuaishou | 10 سیکنڈ | $0.13–$2.64/task | مارکیٹنگ مواد، باریک کنٹرول |
| Runway Gen-3A Turbo | Runway | 5 یا 10 سیکنڈ | $0.32/task | امیج ٹو ویڈیو، کمرشل کنٹینٹ |
Source*:* CometAPI ماڈل صفحات، مئی 2026۔ نوٹ: "Sora 2" CometAPI کا ماڈل شناخت کار ہے — ان کے model page سے بنیادی ماڈل کی تفصیل دیکھیں۔
- Veo 3 Fast ٹیکسٹ ٹو ویڈیو اور امیج ٹو ویڈیو دونوں سپورٹ کرتا ہے۔ فی سیکنڈ سب سے سستا، آغاز کے لیے اچھا۔
- Sora 2 ویڈیو کے ساتھ نیٹو آڈیو بھی بناتا ہے — ڈائیلاگ، ایمبیئنٹ ساؤنڈ، اور ایفیکٹس، علیحدہ TTS قدم کے بغیر۔
- Kling Video آپ کو
negative_prompt،cfg_scale، کیمرہ موومنٹ سیٹنگز، اورproموڈ دیتا ہے۔ چاروں میں سب سے زیادہ کنٹرول۔ - Runway صرف CometAPI کے ذریعے امیج ٹو ویڈیو ہے۔ ایک ساکن امیج اور موشن کی تفصیل دیں، یہ اسے اینیمیٹ کر دیتا ہے۔
Veo ٹاسک جمع کرائیں
Veo multipart/form-data استعمال کرتا ہے۔ Python requests میں درست طریقے سے بھیجنے کے لیے files= استعمال کریں — data=dict application/x-www-form-urlencoded بھیجتا ہے، جو اس کے مترادف نہیں ہے:
import requestsimport osfrom dotenv import load_dotenvload_dotenv()def submit_veo_task(prompt: str, size: str = "16x9") -> str: """Submit a Veo 3 Fast text-to-video task. Returns task_id.""" api_key = os.getenv("COMETAPI_KEY") if not api_key: raise ValueError("COMETAPI_KEY environment variable is not set") response = requests.post( "https://api.cometapi.com/v1/videos", headers={"Authorization": f"Bearer {api_key}"}, files={ "prompt": (None, prompt), "model": (None, "veo3-fast"), "size": (None, size) }, timeout=30 ) response.raise_for_status() return response.json()["id"]task_id = submit_veo_task("A paper kite drifting above a wheat field on a windy afternoon")print(f"Task submitted: {task_id}")
نتیجہ کے لیے پول کریں
import timedef poll_veo_task(task_id: str, interval: int = 10, max_wait: int = 600) -> str: """Poll until Veo task completes. Returns video URL.""" api_key = os.getenv("COMETAPI_KEY") if not api_key: raise ValueError("COMETAPI_KEY environment variable is not set") headers = {"Authorization": f"Bearer {api_key}"} url = f"https://api.cometapi.com/v1/videos/{task_id}" elapsed = 0 while elapsed < max_wait: response = requests.get(url, headers=headers, timeout=30) response.raise_for_status() result = response.json() status = result.get("status") if status == "succeeded": return result["output"][0] elif status in ("failed", "cancelled"): raise RuntimeError( f"Task {task_id} failed with status '{status}': " f"{result.get('error', 'no error detail returned')}" ) time.sleep(interval) elapsed += interval raise TimeoutError(f"Task {task_id} did not complete within {max_wait} seconds")video_url = poll_veo_task(task_id)print(f"Video ready: {video_url}")
مزید کنٹرول کے لیے Kling Video استعمال کریں
Kling کا اینڈ پوائنٹ ڈھانچہ مختلف ہے اور یہ JSON استعمال کرتا ہے۔ نوٹ کریں کہ Kling کی ٹرمینل اسٹیٹس اسٹرنگ "succeed" ہوتی ہے (نہ کہ "succeeded") — یہ API کے اصل ریسپانس فارمیٹ سے مطابقت رکھتا ہے:
def submit_kling_task(prompt: str, duration: str = "5", mode: str = "std") -> str: """Submit a Kling text-to-video task. Returns task_id.""" api_key = os.getenv("COMETAPI_KEY") if not api_key: raise ValueError("COMETAPI_KEY environment variable is not set") response = requests.post( "https://api.cometapi.com/kling/v1/videos/text2video", headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" }, json={ "model_name": "kling-v1-6", "prompt": prompt, "negative_prompt": "blurry, low quality, watermark", "cfg_scale": 0.5, "mode": mode, # "std" or "pro" "aspect_ratio": "16:9", "duration": duration # "5" or "10" }, timeout=30 ) response.raise_for_status() return response.json()["data"]["task_id"]def poll_kling_task(task_id: str, interval: int = 10, max_wait: int = 600) -> str: """Poll Kling task until complete. Returns video URL.""" api_key = os.getenv("COMETAPI_KEY") if not api_key: raise ValueError("COMETAPI_KEY environment variable is not set") headers = {"Authorization": f"Bearer {api_key}"} url = f"https://api.cometapi.com/kling/v1/videos/text2video/{task_id}" elapsed = 0 while elapsed < max_wait: response = requests.get(url, headers=headers, timeout=30) response.raise_for_status() result = response.json() status = result["data"]["task_status"] if status == "succeed": # Kling uses "succeed", not "succeeded" return result["data"]["task_result"]["videos"][0]["url"] elif status == "failed": error_detail = result.get("data", {}).get("task_result", "no detail") raise RuntimeError( f"Kling task {task_id} failed: {error_detail}" ) time.sleep(interval) elapsed += interval raise TimeoutError(f"Kling task {task_id} timed out after {max_wait}s")
Source*:* CometAPI Kling Video docs
Runway کے ساتھ ایک ساکن امیج کو اینیمیٹ کریں
Runway صرف امیج ٹو ویڈیو ہے۔ اسے ایک اضافی ہیڈر (X-Runway-Version) بھی درکار ہوتا ہے:
def submit_runway_task(image_url: str, motion_prompt: str, duration: int = 5) -> str: """Submit a Runway image-to-video task. Returns task_id.""" api_key = os.getenv("COMETAPI_KEY") if not api_key: raise ValueError("COMETAPI_KEY environment variable is not set") response = requests.post( "https://api.cometapi.com/runwayml/v1/image_to_video", headers={ "Authorization": f"Bearer {api_key}", "X-Runway-Version": "2024-11-06", "Content-Type": "application/json" }, json={ "model": "gen3a_turbo", "promptImage": image_url, # must be a stable HTTPS URL "promptText": motion_prompt, "duration": duration, "ratio": "1280:720", "watermark": False }, timeout=30 ) response.raise_for_status() return response.json()["id"]def poll_runway_task(task_id: str, interval: int = 5, max_wait: int = 600) -> str: """Poll Runway task. Returns video URL when done.""" api_key = os.getenv("COMETAPI_KEY") if not api_key: raise ValueError("COMETAPI_KEY environment variable is not set") headers = { "Authorization": f"Bearer {api_key}", "X-Runway-Version": "2024-11-06" } url = f"https://api.cometapi.com/runwayml/v1/tasks/{task_id}" elapsed = 0 while elapsed < max_wait: response = requests.get(url, headers=headers, timeout=30) response.raise_for_status() result = response.json() status = result.get("status") if status == "task_not_exist": # CometAPI-specific: task is still initializing, retry after a few seconds time.sleep(interval) elapsed += interval continue elif status == "succeeded": return result["output"][0] elif status in ("failed", "cancelled"): raise RuntimeError(f"Runway task {task_id} failed: {result.get('error', 'no detail')}") time.sleep(interval) elapsed += interval raise TimeoutError(f"Runway task {task_id} timed out after {max_wait}s")
Source*:* CometAPI Runway docs
URL کی معیاد ختم ہونے سے پہلے ویڈیو محفوظ کریں
جنریشن APIs کے ویڈیو URLs عارضی ہوتے ہیں۔ فائل فوراً ڈاؤن لوڈ کریں اور کہیں اپنے اختیار کے اسٹوریج میں محفوظ کریں:
import requestsimport pathlibdef download_video(url: str, output_path: str) -> None: """Download video from URL to local file using streaming.""" out = pathlib.Path(output_path) if out.parent != pathlib.Path("."): out.parent.mkdir(parents=True, exist_ok=True) with requests.get(url, stream=True, timeout=60) as r: r.raise_for_status() with open(out, "wb") as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk) print(f"Saved to {output_path}")# Full flowtask_id = submit_veo_task("A timelapse of clouds moving over a city skyline")video_url = poll_veo_task(task_id)download_video(video_url, "output/city_timelapse.mp4")
پروڈکشن میں، لوکل فائل لکھنے کے بجائے S3، Cloudflare R2، یا اپنی پسند کے اسٹوریج پر اپ لوڈ کریں۔ اسٹریمنگ پیٹرن ویسا ہی رہتا ہے — بائٹس کو براہِ راست پائپ کریں بجائے اس کے کہ پوری ویڈیو کو میموری میں لوڈ کریں۔
ناکامیوں کو ہینڈل کریں
| Symptom | Likely cause | Fix |
|---|---|---|
| Task queued میں 10+ منٹ تک اٹکا رہے | سرور لوڈ یا ماڈل دستیاب نہیں | کسی دوسرے ماڈل کے ساتھ دوبارہ کوشش کریں |
| task_not_exist پہلی Runway پول پر | ٹاسک ابھی انیشیالائز ہو رہا ہے | 5 سیکنڈ انتظار کریں اور دوبارہ کوشش کریں — CometAPI کا دستاویزی رویہ |
| failed بلا کسی error message | پرامپٹ نے کنٹینٹ فلٹر ٹرگر کیا | پرامپٹ کو دوبارہ الفاظ میں لکھیں |
| ویڈیو URL 403 واپس کرے | URL ڈاؤن لوڈ سے پہلے ہی ایکسپائر ہو گیا | URL ملتے ہی فوراً ڈاؤن لوڈ کریں |
| 10 منٹ بعد ٹائم آؤٹ | جنریشن میں زیادہ وقت لگا | max_wait بڑھائیں یا Veo 3 Fast پر سوئچ کریں |
| Kling "succeed" دیتا ہے "succeeded" نہیں | Kling کا API نان اسٹینڈرڈ اسٹیٹس اسٹرنگ دیتا ہے | یہ درست ہے — اوپر Kling پولنگ کوڈ دیکھیں |
Source: CometAPI ویڈیو جنریشن ڈاکس
Node.js ورژن
Node.js 18+ میں fetch اور FormData نیٹو شامل ہیں۔ یہ مثال چاروں ماڈلز کا احاطہ کرتی ہے:
// Node.js 18+ — no extra packages neededconst API_KEY = process.env.COMETAPI_KEY;if (!API_KEY) throw new Error('COMETAPI_KEY is not set');// --- Veo 3 Fast ---async function submitVeoTask(prompt, size = '16x9') { const form = new FormData(); form.append('prompt', prompt); form.append('model', 'veo3-fast'); form.append('size', size); const res = await fetch('https://api.cometapi.com/v1/videos', { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}` }, body: form }); if (!res.ok) throw new Error(`Veo submit failed: ${res.status}`); return (await res.json()).id;}async function pollVeoTask(taskId, intervalMs = 10000, maxWaitMs = 600000) { let elapsed = 0; while (elapsed < maxWaitMs) { const res = await fetch(`https://api.cometapi.com/v1/videos/${taskId}`, { headers: { 'Authorization': `Bearer ${API_KEY}` } }); if (!res.ok) throw new Error(`Poll failed: ${res.status}`); const result = await res.json(); if (result.status === 'succeeded') return result.output[0]; if (['failed', 'cancelled'].includes(result.status)) { throw new Error(`Task ${taskId} failed: ${result.error ?? 'no detail'}`); } await new Promise(r => setTimeout(r, intervalMs)); elapsed += intervalMs; } throw new Error(`Task ${taskId} timed out`);}// --- Kling Video ---async function submitKlingTask(prompt, duration = '5', mode = 'std') { const res = await fetch('https://api.cometapi.com/kling/v1/videos/text2video', { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model_name: 'kling-v1-6', prompt, negative_prompt: 'blurry, low quality, watermark', cfg_scale: 0.5, mode, aspect_ratio: '16:9', duration }) }); if (!res.ok) throw new Error(`Kling submit failed: ${res.status}`); return (await res.json()).data.task_id;}async function pollKlingTask(taskId, intervalMs = 10000, maxWaitMs = 600000) { let elapsed = 0; while (elapsed < maxWaitMs) { const res = await fetch( `https://api.cometapi.com/kling/v1/videos/text2video/${taskId}`, { headers: { 'Authorization': `Bearer ${API_KEY}` } } ); if (!res.ok) throw new Error(`Kling poll failed: ${res.status}`); const result = await res.json(); const status = result.data.task_status; if (status === 'succeed') return result.data.task_result.videos[0].url; if (status === 'failed') { throw new Error(`Kling task ${taskId} failed: ${JSON.stringify(result.data.task_result ?? 'no detail')}`); } await new Promise(r => setTimeout(r, intervalMs)); elapsed += intervalMs; } throw new Error(`Kling task ${taskId} timed out`);}// --- Runway (image-to-video) ---async function submitRunwayTask(imageUrl, motionPrompt, duration = 5) { const res = await fetch('https://api.cometapi.com/runwayml/v1/image_to_video', { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'X-Runway-Version': '2024-11-06', 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'gen3a_turbo', promptImage: imageUrl, promptText: motionPrompt, duration, ratio: '1280:720', watermark: false }) }); if (!res.ok) throw new Error(`Runway submit failed: ${res.status}`); return (await res.json()).id;}async function pollRunwayTask(taskId, intervalMs = 5000, maxWaitMs = 600000) { let elapsed = 0; while (elapsed < maxWaitMs) { const res = await fetch( `https://api.cometapi.com/runwayml/v1/tasks/${taskId}`, { headers: { 'Authorization': `Bearer ${API_KEY}`, 'X-Runway-Version': '2024-11-06' } } ); if (!res.ok) throw new Error(`Runway poll failed: ${res.status}`); const result = await res.json(); const status = result.status; if (status === 'task_not_exist') { // CometAPI-specific: task still initializing await new Promise(r => setTimeout(r, intervalMs)); elapsed += intervalMs; continue; } if (status === 'succeeded') return result.output[0]; if (['failed', 'cancelled'].includes(status)) { throw new Error(`Runway task ${taskId} failed: ${result.error ?? 'no detail'}`); } await new Promise(r => setTimeout(r, intervalMs)); elapsed += intervalMs; } throw new Error(`Runway task ${taskId} timed out`);}// Usage exampleconst taskId = await submitVeoTask('A paper kite drifting above a wheat field');const videoUrl = await pollVeoTask(taskId);console.log('Video ready:', videoUrl);
آگے کیا ہے
اب آپ کے پاس چار ویڈیو ماڈلز کے لیے چلنے والا کوڈ ہے، ایک پولنگ لوپ جو ناکامیوں کو ہینڈل کرتا ہے، اور ایک ڈاؤن لوڈ قدم جو آپ کو جنریٹڈ کنٹینٹ ضائع ہونے سے بچاتا ہے۔
اگلا مسئلہ جو اکثر ڈویلپرز کو درپیش ہوتا ہے: انہوں نے ایک ماڈل ہارڈ کوڈ کیا ہوتا ہے، اور سستے یا تیز تر آپشن پر سوئچ کرنے کے لیے متعدد فائلوں میں تبدیلی کرنا پڑتی ہے۔ اگلا مضمون یہ بتاتا ہے کہ اپنے کوڈ کو دوبارہ لکھے بغیر مختلف ماڈلز کے درمیان ریکویسٹس کو کیسے روٹ کریں۔
آگے: اپنا کوڈ دوبارہ لکھے بغیر AI ماڈلز کے درمیان کیسے سوئچ کریں
FAQ
Q: مجھے API ریسپانس میں ویڈیو کے بجائے ٹاسک ID کیوں ملتی ہے؟
ویڈیو جنریشن ایسِنک ہے — Veo، Sora، Kling، اور Runway جیسے ماڈلز کو رینڈر کرنے میں 2–5 منٹ لگتے ہیں۔ API فوراً ٹاسک ID اس لیے لوٹاتی ہے تاکہ آپ کی ریکویسٹ ٹائم آؤٹ نہ ہو۔ آپ ایک علیحدہ اسٹیٹس اینڈ پوائنٹ کو پول کرتے ہیں جب تک ٹاسک ٹرمینل حالت (succeeded، succeed، failed) تک نہ پہنچ جائے۔
Q: بنایا گیا ویڈیو URL کتنی دیر تک قابلِ استعمال رہتا ہے؟
جنریشن APIs کے ویڈیو URLs عارضی ہوتے ہیں۔ URL ملتے ہی فوراً فائل ڈاؤن لوڈ کریں اور اپنے اسٹوریج (S3، Cloudflare R2، وغیرہ) میں محفوظ کریں۔ صرف URL محفوظ نہ رکھیں اور امید کریں کہ گھنٹوں بعد بھی چلے گا۔
Q: Veo 3 Fast اور Kling Video میں کیا فرق ہے؟
Veo 3 Fast سستا ($0.05/sec)، تیز، اور کال کرنا آسان ہے۔ Kling Video زیادہ کنٹرول دیتا ہے: negative_prompt، cfg_scale، کیمرہ موومنٹ سیٹنگز، اور pro کوالٹی موڈ۔ اگر آپ کو آؤٹ پٹ کو باریک بینی سے سیٹ کرنا ہو تو Kling استعمال کریں۔ اگر رفتار اور کم لاگت درکار ہو تو Veo 3 Fast بہتر ہے۔
Q: کیا میں ٹیکسٹ پرامپٹ کے بجائے امیج سے ویڈیو بنا سکتا/سکتی ہوں؟
ہاں۔ Veo، input_reference فائل پاس کر کے امیج ٹو ویڈیو سپورٹ کرتا ہے۔ Kling /kling/v1/videos/image2video اینڈ پوائنٹ کے ذریعے سپورٹ کرتا ہے جس میں image پیرامیٹر (URL یا base64) ہوتا ہے۔ Runway صرف امیج ٹو ویڈیو ہے — یہ CometAPI کے ذریعے ٹیکسٹ صرف پرامپٹس قبول نہیں کرتا۔
Q: Runway پہلی پول پر task_not_exist کیوں دیتا ہے؟
یہ CometAPI کا دستاویزی رویہ ہے — بیک اینڈ پر ٹاسک ابھی انیشیالائز ہو رہا ہوتا ہے۔ چند سیکنڈ انتظار کریں اور دوبارہ کوشش کریں۔ یہ خرابی نہیں ہے۔ اوپر دیا گیا پولنگ کوڈ یہ خودکار طور پر ہینڈل کرتا ہے۔
Q: Kling "succeed" کے بجائے "succeeded" کیوں استعمال کرتا ہے؟
یہ Kling کے API کا اصل ریسپانس فارمیٹ ہے۔ یہ ٹائپو نہیں ہے۔ Veo اور Runway "succeeded" استعمال کرتے ہیں — Kling "succeed" استعمال کرتا ہے۔ اگر آپ ایک متحد پولنگ ریپر بنا رہے ہیں تو دونوں اسٹرنگز کو ہینڈل کرنا ہوگا۔
Q: کیا ہم وقت (synchronous) پولنگ لوپ ویب سرور میں محفوظ ہے؟
نہیں۔ اس گائیڈ میں دیا گیا پولنگ لوپ تھریڈ کو منٹوں تک بلاک کر دیتا ہے۔ ایک حقیقی ویب سروس میں، پولنگ کو بیک گراؤنڈ ورکر (Python کے لیے Celery، Node.js کے لیے Bull) میں چلائیں۔ ریکویسٹ ہینڈلر میں ٹاسک جمع کرائیں، کلائنٹ کو ٹاسک ID لوٹائیں، اور جب ویڈیو تیار ہو تو ورکر کلائنٹ کو مطلع کرے۔
