From 6e9126b54756982770fd2a30a98cd6db8eedbb85 Mon Sep 17 00:00:00 2001 From: Tim Pietrusky Date: Tue, 10 Mar 2026 16:42:20 +0100 Subject: [PATCH] feat(ai-sdk): add video generation examples for all 15 supported models - Add 15 new example scripts (4 t2v, 11 i2v) covering all video models - Update generate-video.js to use npm imports and latest API patterns - Each i2v example uses a unique demo image from image.runpod.ai/demo/ - Motion control example (kling-v2.6-std) uses person image + video reference - Sora i2v example includes explicit duration: 4 (required by API) - Bump @runpod/ai-sdk-provider to ^1.4.0 and ai to ^6.0.116 --- .../generate-video-alibaba-wan-2-1-i2v-720.js | 35 +++ .../generate-video-alibaba-wan-2-2-i2v-720.js | 35 +++ ...rate-video-alibaba-wan-2-2-t2v-720-lora.js | 35 +++ .../generate-video-alibaba-wan-2-5.js | 35 +++ .../generate-video-alibaba-wan-2-6-i2v.js | 35 +++ .../generate-video-alibaba-wan-2-6-t2v.js | 29 +++ ...e-video-bytedance-seedance-v1-5-pro-i2v.js | 35 +++ ...nerate-video-kwaivgi-kling-v2-1-i2v-pro.js | 35 +++ ...o-kwaivgi-kling-v2-6-std-motion-control.js | 44 ++++ ...nerate-video-kwaivgi-kling-video-o1-r2v.js | 35 +++ .../generate-video-openai-sora-2-i2v.js | 36 +++ .../generate-video-openai-sora-2-pro-i2v.js | 35 +++ .../generate-video-pruna-p-video.js | 29 +++ .../generate-video-vidu-q3-i2v.js | 35 +++ .../generate-video-vidu-q3-t2v.js | 29 +++ ai-sdk/getting-started/generate-video.js | 17 +- ai-sdk/getting-started/package-lock.json | 232 ++++++++++++++++++ ai-sdk/getting-started/package.json | 4 +- 18 files changed, 756 insertions(+), 14 deletions(-) create mode 100644 ai-sdk/getting-started/generate-video-alibaba-wan-2-1-i2v-720.js create mode 100644 ai-sdk/getting-started/generate-video-alibaba-wan-2-2-i2v-720.js create mode 100644 ai-sdk/getting-started/generate-video-alibaba-wan-2-2-t2v-720-lora.js create mode 100644 ai-sdk/getting-started/generate-video-alibaba-wan-2-5.js create mode 100644 ai-sdk/getting-started/generate-video-alibaba-wan-2-6-i2v.js create mode 100644 ai-sdk/getting-started/generate-video-alibaba-wan-2-6-t2v.js create mode 100644 ai-sdk/getting-started/generate-video-bytedance-seedance-v1-5-pro-i2v.js create mode 100644 ai-sdk/getting-started/generate-video-kwaivgi-kling-v2-1-i2v-pro.js create mode 100644 ai-sdk/getting-started/generate-video-kwaivgi-kling-v2-6-std-motion-control.js create mode 100644 ai-sdk/getting-started/generate-video-kwaivgi-kling-video-o1-r2v.js create mode 100644 ai-sdk/getting-started/generate-video-openai-sora-2-i2v.js create mode 100644 ai-sdk/getting-started/generate-video-openai-sora-2-pro-i2v.js create mode 100644 ai-sdk/getting-started/generate-video-pruna-p-video.js create mode 100644 ai-sdk/getting-started/generate-video-vidu-q3-i2v.js create mode 100644 ai-sdk/getting-started/generate-video-vidu-q3-t2v.js create mode 100644 ai-sdk/getting-started/package-lock.json diff --git a/ai-sdk/getting-started/generate-video-alibaba-wan-2-1-i2v-720.js b/ai-sdk/getting-started/generate-video-alibaba-wan-2-1-i2v-720.js new file mode 100644 index 0000000..1dbc689 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-alibaba-wan-2-1-i2v-720.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-alibaba-wan-2-1-i2v-720\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/desert-oasis-camels-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("alibaba/wan-2.1-i2v-720"), + prompt: { + text: "Animate the camels walking slowly toward the oasis, heat haze shimmering over the sand dunes, palm trees swaying gently in warm breeze", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-alibaba-wan-2-1-i2v-720-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-alibaba-wan-2-2-i2v-720.js b/ai-sdk/getting-started/generate-video-alibaba-wan-2-2-i2v-720.js new file mode 100644 index 0000000..1fdb633 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-alibaba-wan-2-2-i2v-720.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-alibaba-wan-2-2-i2v-720\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/city-rain-neon-reflections-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("alibaba/wan-2.2-i2v-720"), + prompt: { + text: "Animate the rainy city street with raindrops falling, neon reflections shimmering on wet pavement, taxis driving past, and steam rising from manholes", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-alibaba-wan-2-2-i2v-720-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-alibaba-wan-2-2-t2v-720-lora.js b/ai-sdk/getting-started/generate-video-alibaba-wan-2-2-t2v-720-lora.js new file mode 100644 index 0000000..f6558ca --- /dev/null +++ b/ai-sdk/getting-started/generate-video-alibaba-wan-2-2-t2v-720-lora.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-alibaba-wan-2-2-t2v-720-lora\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/japanese-garden-koi-pond-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("alibaba/wan-2.2-t2v-720-lora"), + prompt: { + text: "Animate the koi pond with fish swimming, cherry blossoms falling gently, and soft ripples on the water surface", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-alibaba-wan-2-2-t2v-720-lora-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-alibaba-wan-2-5.js b/ai-sdk/getting-started/generate-video-alibaba-wan-2-5.js new file mode 100644 index 0000000..c185204 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-alibaba-wan-2-5.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-alibaba-wan-2-5\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/steam-train-mountain-pass-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("alibaba/wan-2.5"), + prompt: { + text: "Animate the steam train crossing the bridge with smoke billowing from the locomotive, autumn leaves drifting in the wind", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-alibaba-wan-2-5-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-alibaba-wan-2-6-i2v.js b/ai-sdk/getting-started/generate-video-alibaba-wan-2-6-i2v.js new file mode 100644 index 0000000..009ce98 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-alibaba-wan-2-6-i2v.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-alibaba-wan-2-6-i2v\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/underwater-coral-reef-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("alibaba/wan-2.6-i2v"), + prompt: { + text: "Animate the tropical fish swimming through the coral reef, sunlight rays dancing through the water, gentle ocean current swaying the sea anemones", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-alibaba-wan-2-6-i2v-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-alibaba-wan-2-6-t2v.js b/ai-sdk/getting-started/generate-video-alibaba-wan-2-6-t2v.js new file mode 100644 index 0000000..42a4833 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-alibaba-wan-2-6-t2v.js @@ -0,0 +1,29 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-alibaba-wan-2-6-t2v\n"); + +async function main() { + const { video } = await generateVideo({ + model: runpod.video("alibaba/wan-2.6-t2v"), + prompt: + "An astronaut floating in space with Earth visible in the background, photorealistic, 4K", + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-alibaba-wan-2-6-t2v-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-bytedance-seedance-v1-5-pro-i2v.js b/ai-sdk/getting-started/generate-video-bytedance-seedance-v1-5-pro-i2v.js new file mode 100644 index 0000000..12ab8f8 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-bytedance-seedance-v1-5-pro-i2v.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-bytedance-seedance-v1-5-pro-i2v\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/sailboat-ocean-sunset-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("bytedance/seedance-v1.5-pro-i2v"), + prompt: { + text: "Animate the sailboat gliding across calm ocean waves, seagulls soaring overhead, golden sunset light reflecting on the water", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-bytedance-seedance-v1-5-pro-i2v-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-kwaivgi-kling-v2-1-i2v-pro.js b/ai-sdk/getting-started/generate-video-kwaivgi-kling-v2-1-i2v-pro.js new file mode 100644 index 0000000..a250400 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-kwaivgi-kling-v2-1-i2v-pro.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-kwaivgi-kling-v2-1-i2v-pro\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/northern-lights-cabin-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("kwaivgi/kling-v2.1-i2v-pro"), + prompt: { + text: "Animate the aurora borealis dancing and shimmering across the night sky, warm light flickering in the cabin windows, snow gently falling", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-kwaivgi-kling-v2-1-i2v-pro-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-kwaivgi-kling-v2-6-std-motion-control.js b/ai-sdk/getting-started/generate-video-kwaivgi-kling-v2-6-std-motion-control.js new file mode 100644 index 0000000..84f0946 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-kwaivgi-kling-v2-6-std-motion-control.js @@ -0,0 +1,44 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-kwaivgi-kling-v2-6-std-motion-control\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/person-standing-garden-1280x720.png"; + + const videoUrl = + process.argv[3] || + "https://image.runpod.ai/demo/person-motion-reference.mp4"; + + const { video } = await generateVideo({ + model: runpod.video("kwaivgi/kling-v2.6-std-motion-control"), + prompt: { + text: "Animate the person with natural swaying motion, hair blowing gently in the wind, subtle body movement", + image: imageUrl, + }, + aspectRatio: "16:9", + providerOptions: { + runpod: { + video: videoUrl, + }, + }, + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-kwaivgi-kling-v2-6-std-motion-control-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-kwaivgi-kling-video-o1-r2v.js b/ai-sdk/getting-started/generate-video-kwaivgi-kling-video-o1-r2v.js new file mode 100644 index 0000000..c97188d --- /dev/null +++ b/ai-sdk/getting-started/generate-video-kwaivgi-kling-video-o1-r2v.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-kwaivgi-kling-video-o1-r2v\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/hot-air-balloons-sunrise-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("kwaivgi/kling-video-o1-r2v"), + prompt: { + text: "Animate the hot air balloons rising slowly through the misty valley, morning fog drifting across the landscape", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-kwaivgi-kling-video-o1-r2v-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-openai-sora-2-i2v.js b/ai-sdk/getting-started/generate-video-openai-sora-2-i2v.js new file mode 100644 index 0000000..8ce7bb8 --- /dev/null +++ b/ai-sdk/getting-started/generate-video-openai-sora-2-i2v.js @@ -0,0 +1,36 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-openai-sora-2-i2v\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/mountain-lake-reflection-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("openai/sora-2-i2v"), + prompt: { + text: "Animate the mountain lake with gentle ripples breaking the mirror-like reflection, clouds drifting slowly over snow-capped peaks, wildflowers swaying in the breeze", + image: imageUrl, + }, + aspectRatio: "16:9", + duration: 4, + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-openai-sora-2-i2v-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-openai-sora-2-pro-i2v.js b/ai-sdk/getting-started/generate-video-openai-sora-2-pro-i2v.js new file mode 100644 index 0000000..39b89fc --- /dev/null +++ b/ai-sdk/getting-started/generate-video-openai-sora-2-pro-i2v.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-openai-sora-2-pro-i2v\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/waterfall-tropical-forest-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("openai/sora-2-pro-i2v"), + prompt: { + text: "Animate the waterfall cascading into the turquoise pool, mist rising from the falls, sunbeams shifting through the tropical canopy", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-openai-sora-2-pro-i2v-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-pruna-p-video.js b/ai-sdk/getting-started/generate-video-pruna-p-video.js new file mode 100644 index 0000000..3aeae9e --- /dev/null +++ b/ai-sdk/getting-started/generate-video-pruna-p-video.js @@ -0,0 +1,29 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-pruna-p-video\n"); + +async function main() { + const { video } = await generateVideo({ + model: runpod.video("pruna/p-video"), + prompt: + "A golden retriever running through a sunlit meadow with wildflowers, slow motion, cinematic", + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-pruna-p-video-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-vidu-q3-i2v.js b/ai-sdk/getting-started/generate-video-vidu-q3-i2v.js new file mode 100644 index 0000000..77d9e3c --- /dev/null +++ b/ai-sdk/getting-started/generate-video-vidu-q3-i2v.js @@ -0,0 +1,35 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-vidu-q3-i2v\n"); + +async function main() { + const imageUrl = + process.argv[2] || + "https://image.runpod.ai/demo/lighthouse-stormy-sea-1280x720.png"; + + const { video } = await generateVideo({ + model: runpod.video("vidu/q3-i2v"), + prompt: { + text: "Animate the stormy sea with crashing waves, flickering lighthouse beam, and lightning flashing across dark clouds", + image: imageUrl, + }, + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-vidu-q3-i2v-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video-vidu-q3-t2v.js b/ai-sdk/getting-started/generate-video-vidu-q3-t2v.js new file mode 100644 index 0000000..69dcefa --- /dev/null +++ b/ai-sdk/getting-started/generate-video-vidu-q3-t2v.js @@ -0,0 +1,29 @@ +import dotenv from "dotenv"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; +import { writeFileSync } from "fs"; + +dotenv.config({ quiet: true }); + +console.log("generate-video-vidu-q3-t2v\n"); + +async function main() { + const { video } = await generateVideo({ + model: runpod.video("vidu/q3-t2v"), + prompt: + "A futuristic city skyline at night with neon lights reflecting on wet streets, cyberpunk atmosphere", + aspectRatio: "16:9", + }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const filename = `generated-video-vidu-q3-t2v-${timestamp}.mp4`; + + writeFileSync(filename, video.uint8Array); + console.log(`saved video: ${filename}`); + console.log(`size: ${(video.uint8Array.length / 1024 / 1024).toFixed(2)} MB`); +} + +main().catch((err) => { + console.error("failed:", err?.message || err); + process.exit(1); +}); diff --git a/ai-sdk/getting-started/generate-video.js b/ai-sdk/getting-started/generate-video.js index b06a124..576ea1d 100644 --- a/ai-sdk/getting-started/generate-video.js +++ b/ai-sdk/getting-started/generate-video.js @@ -1,25 +1,18 @@ import dotenv from "dotenv"; -import { runpod } from "../../../ai-sdk-provider/dist/index.mjs"; -import { experimental_generateVideo as generateVideo } from "../../../thirdparty/ai/packages/ai/dist/index.mjs"; +import { runpod } from "@runpod/ai-sdk-provider"; +import { experimental_generateVideo as generateVideo } from "ai"; import { writeFileSync } from "fs"; dotenv.config({ quiet: true }); -console.log("video generation (Runpod AI SDK Provider)\n"); +console.log("generate-video\n"); async function main() { const { video } = await generateVideo({ - model: runpod.videoModel("alibaba/wan-2-2-t2v-720"), + model: runpod.video("alibaba/wan-2.6-t2v"), prompt: "A serene sunrise timelapse over snowy mountains, cinematic, high detail", - resolution: "1280x720", - durationSeconds: 5, - fps: 24, - providerOptions: { - runpod: { - // optional provider-specific params; adjust as needed - }, - }, + aspectRatio: "16:9", }); const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); diff --git a/ai-sdk/getting-started/package-lock.json b/ai-sdk/getting-started/package-lock.json new file mode 100644 index 0000000..0c964aa --- /dev/null +++ b/ai-sdk/getting-started/package-lock.json @@ -0,0 +1,232 @@ +{ + "name": "runpod-aisdk-getting-started", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "runpod-aisdk-getting-started", + "version": "1.0.0", + "dependencies": { + "@ai-sdk/openai": "^2.0.13", + "@runpod/ai-sdk-provider": "file:../../../ai-sdk-provider", + "ai": "^6.0.116", + "dotenv": "^17.2.1", + "zod": "^3.25.76" + } + }, + "../../../ai-sdk-provider": { + "name": "@runpod/ai-sdk-provider", + "version": "1.2.0", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/openai-compatible": "^2.0.30", + "@ai-sdk/provider": "^3.0.8", + "@ai-sdk/provider-utils": "^4.0.15" + }, + "devDependencies": { + "@changesets/cli": "^2.29.8", + "@edge-runtime/vm": "^5.0.0", + "@types/node": "^20.0.0", + "@typescript-eslint/eslint-plugin": "^8.56.1", + "@typescript-eslint/parser": "^8.56.1", + "eslint": "^9.33.0", + "prettier": "^3.8.1", + "tsup": "^8.5.1", + "typescript": "^5.9.3", + "vitest": "^2.0.0", + "zod": "^3.25.76" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4" + } + }, + "node_modules/@ai-sdk/gateway": { + "version": "3.0.66", + "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-3.0.66.tgz", + "integrity": "sha512-SIQ0YY0iMuv+07HLsZ+bB990zUJ6S4ujORAh+Jv1V2KGNn73qQKnGO0JBk+w+Res8YqOFSycwDoWcFlQrVxS4A==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.8", + "@ai-sdk/provider-utils": "4.0.19", + "@vercel/oidc": "3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/gateway/node_modules/@ai-sdk/provider": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-3.0.8.tgz", + "integrity": "sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ai-sdk/gateway/node_modules/@ai-sdk/provider-utils": { + "version": "4.0.19", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-4.0.19.tgz", + "integrity": "sha512-3eG55CrSWCu2SXlqq2QCsFjo3+E7+Gmg7i/oRVoSZzIodTuDSfLb3MRje67xE9RFea73Zao7Lm4mADIfUETKGg==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.8", + "@standard-schema/spec": "^1.1.0", + "eventsource-parser": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/openai": { + "version": "2.0.89", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.1", + "@ai-sdk/provider-utils": "3.0.20" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/provider": { + "version": "2.0.1", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ai-sdk/provider-utils": { + "version": "3.0.20", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.1", + "@standard-schema/spec": "^1.0.0", + "eventsource-parser": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@runpod/ai-sdk-provider": { + "resolved": "../../../ai-sdk-provider", + "link": true + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/@vercel/oidc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.1.0.tgz", + "integrity": "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==", + "license": "Apache-2.0", + "engines": { + "node": ">= 20" + } + }, + "node_modules/ai": { + "version": "6.0.116", + "resolved": "https://registry.npmjs.org/ai/-/ai-6.0.116.tgz", + "integrity": "sha512-7yM+cTmyRLeNIXwt4Vj+mrrJgVQ9RMIW5WO0ydoLoYkewIvsMcvUmqS4j2RJTUXaF1HphwmSKUMQ/HypNRGOmA==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/gateway": "3.0.66", + "@ai-sdk/provider": "3.0.8", + "@ai-sdk/provider-utils": "4.0.19", + "@opentelemetry/api": "1.9.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/ai/node_modules/@ai-sdk/provider": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-3.0.8.tgz", + "integrity": "sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/ai/node_modules/@ai-sdk/provider-utils": { + "version": "4.0.19", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-4.0.19.tgz", + "integrity": "sha512-3eG55CrSWCu2SXlqq2QCsFjo3+E7+Gmg7i/oRVoSZzIodTuDSfLb3MRje67xE9RFea73Zao7Lm4mADIfUETKGg==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "3.0.8", + "@standard-schema/spec": "^1.1.0", + "eventsource-parser": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/zod": { + "version": "3.25.76", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/ai-sdk/getting-started/package.json b/ai-sdk/getting-started/package.json index f05f701..91f1a83 100644 --- a/ai-sdk/getting-started/package.json +++ b/ai-sdk/getting-started/package.json @@ -7,8 +7,8 @@ "scripts": {}, "dependencies": { "@ai-sdk/openai": "^2.0.13", - "@runpod/ai-sdk-provider": "^1.0.1", - "ai": "^6.0.3", + "@runpod/ai-sdk-provider": "^1.4.0", + "ai": "^6.0.116", "dotenv": "^17.2.1", "zod": "^3.25.76" }