### Connect and Stream with Odyssey Client in Vanilla JavaScript Source: https://documentation.api.odyssey.ml/sdk/javascript/examples This example shows how to initialize the Odyssey client, connect to the service, handle connection events (connected, disconnected, status change, errors), start a video stream with a prompt, interact with the stream, and disconnect. It requires the '@odysseyml/odyssey' package and DOM elements for video and status display. ```javascript import { Odyssey } from '@odysseyml/odyssey'; const videoElement = document.getElementById('video'); const statusElement = document.getElementById('status'); const client = new Odyssey({ apiKey: 'ody_your_api_key_here' }); async function connect() { try { await client.connect({ onConnected: (mediaStream) => { videoElement.srcObject = mediaStream; videoElement.play(); }, onDisconnected: () => { videoElement.srcObject = null; }, onStatusChange: (status, message) => { statusElement.textContent = message || status; }, onError: (error, fatal) => { console.error('Error:', error.message); if (fatal) { statusElement.textContent = 'Connection failed: ' + error.message; } }, }); } catch (error) { console.error('Failed to connect:', error.message); statusElement.textContent = 'Connection failed: ' + error.message; } } async function startStream() { const streamId = await client.startStream({ prompt: 'A cat', portrait: true }); console.log('Stream started:', streamId); } async function interact(prompt) { const ack = await client.interact({ prompt }); console.log('Acknowledged:', ack); } function disconnect() { client.disconnect(); } // Usage connect(); document.getElementById('start-btn').onclick = startStream; document.getElementById('interact-btn').onclick = () => interact('Pet the cat'); document.getElementById('disconnect-btn').onclick = disconnect; ``` -------------------------------- ### Record and Retrieve Video Streams with Python Source: https://documentation.api.odyssey.ml/sdk/python/examples Illustrates how to start a video stream, record it, and then retrieve the recording details and URL. It also shows how to list all available stream recordings. ```python import asyncio from odyssey import Odyssey async def main(): client = Odyssey(api_key="ody_your_api_key_here") stream_id = None try: await client.connect(on_video_frame=lambda f: None) # Start stream and save the ID stream_id = await client.start_stream("A sunset over the ocean") print(f"Stream ID: {stream_id}") await client.interact("Add some seagulls flying") await asyncio.sleep(5) await client.end_stream() finally: await client.disconnect() # Retrieve the recording (after disconnect is fine) if stream_id: recording = await client.get_recording(stream_id) print(f"Video URL: {recording.video_url}") print(f"Duration: {recording.duration_seconds}s") # List all recordings result = await client.list_stream_recordings(limit=5) print(f"Total recordings: {result.total}") for rec in result.recordings: print(f" - {rec.stream_id}: {rec.duration_seconds}s") asyncio.run(main()) ``` -------------------------------- ### Recording Workflow Source: https://documentation.api.odyssey.ml/sdk/python/examples Shows how to start a stream, interact with it, end the stream, and then retrieve the recording details, including video URL and duration. ```APIDOC ## Recording Workflow ### Description This workflow demonstrates how to initiate a video stream, perform interactions, terminate the stream, and subsequently access the generated recording, including its video URL and duration. ### Method Asynchronous Python functions using the `odyssey` library. ### Endpoint N/A (Client-side library usage) ### Parameters N/A ### Request Example ```python import asyncio from odyssey import Odyssey async def main(): client = Odyssey(api_key="ody_your_api_key_here") stream_id = None try: await client.connect(on_video_frame=lambda f: None) # Start stream and save the ID stream_id = await client.start_stream("A sunset over the ocean") print(f"Stream ID: {stream_id}") await client.interact("Add some seagulls flying") await asyncio.sleep(5) await client.end_stream() finally: await client.disconnect() # Retrieve the recording (after disconnect is fine) if stream_id: recording = await client.get_recording(stream_id) print(f"Video URL: {recording.video_url}") print(f"Duration: {recording.duration_seconds}s") # List all recordings result = await client.list_stream_recordings(limit=5) print(f"Total recordings: {result.total}") for rec in result.recordings: print(f" - {rec.stream_id}: {rec.duration_seconds}s") asyncio.run(main()) ``` ### Response Prints Stream ID, Video URL, Duration, and a list of recordings. #### Success Response (200) N/A #### Response Example ``` Stream ID: Video URL: Duration: s Total recordings: - : s - : s ... ``` ``` -------------------------------- ### Image-to-Video Source: https://documentation.api.odyssey.ml/sdk/python/examples Enables the creation of videos starting from an image, with support for various image formats and automatic resizing. ```APIDOC ## Image-to-Video ### Description This feature allows you to generate videos starting from a provided image. The API supports multiple image formats (JPEG, PNG, WebP, GIF, BMP, HEIC, HEIF, AVIF) and automatically resizes images to optimal dimensions (1280x704 or 704x1280). Requires SDK version 1.0.0+ and the image file size must not exceed 25MB. ### Method Asynchronous Python functions using the `odyssey` library. ### Endpoint N/A (Client-side library usage) ### Parameters #### Request Body - **prompt** (string) - Required - The initial prompt for the video. - **image** (string or PIL.Image or bytes or numpy.ndarray) - Required - Path to the image file, a PIL Image object, bytes, or a NumPy array. - **portrait** (boolean) - Optional - Specifies if the video should be in portrait mode (default is landscape). ### Request Example ```python import asyncio from odyssey import Odyssey, VideoFrame frames = [] def on_frame(frame: VideoFrame) -> None: frames.append(frame.data.copy()) async def main(): client = Odyssey(api_key="ody_your_api_key_here") try: # Connect to Odyssey await client.connect( on_video_frame=on_frame, ) # Start stream with an image (file path) stream_id = await client.start_stream( prompt="A cat", portrait=False, image="/path/to/your/image.jpg" ) print(f"Stream started: {stream_id}") # Interact as usual await client.interact("Pet the cat") await asyncio.sleep(5) await client.end_stream() finally: await client.disconnect() print(f"Collected {len(frames)} frames") asyncio.run(main()) ``` ### Response Starts a stream using the provided image and collects video frames. Prints the stream ID and the number of collected frames. #### Success Response (200) N/A #### Response Example ``` Stream started: Collected frames ``` ### Request Example (Using PIL Image) ```python from PIL import Image # Using PIL Image pil_image = Image.open("/path/to/image.jpg") stream_id = await client.start_stream(prompt="A cat", image=pil_image) ``` ``` -------------------------------- ### Connect and Stream Video with Image and Text Prompt (JavaScript) Source: https://documentation.api.odyssey.ml/api-quick-start This example demonstrates connecting to the Odyssey API and initiating a video stream with both an image file and a text prompt. It handles UI updates for connection status and stream states, and includes logic for sending text prompts during an active stream or starting a new stream with an image. The Odyssey library is imported via ESM. ```javascript import { Odyssey } from 'https://esm.sh/@odysseyml/odyssey'; const client = new Odyssey({ apiKey: 'ody_your_api_key_here' }); const status = document.getElementById('status'); const prompt = document.getElementById('prompt'); const imageInput = document.getElementById('image'); const sendBtn = document.getElementById('send'); const endBtn = document.getElementById('end'); let isStreaming = false; window.addEventListener('beforeunload', () => client.disconnect()); document.getElementById('connect').onclick = () => { status.textContent = 'Connecting...'; client.connect({ onConnected: (mediaStream) => { document.getElementById('video').srcObject = mediaStream; prompt.disabled = false; sendBtn.disabled = false; status.textContent = 'Connected'; }, onStreamStarted: () => { isStreaming = true; endBtn.disabled = false; status.textContent = 'Streaming'; }, onStreamEnded: () => { isStreaming = false; endBtn.disabled = true; status.textContent = 'Connected'; }, onError: (error) => console.error('Error:', error.message), }); }; sendBtn.onclick = () => { const text = prompt.value.trim(); prompt.value = ''; if (isStreaming) { client.interact({ prompt: text }); } else { const image = imageInput.files[0]; client.startStream({ prompt: text, image }); } }; endBtn.onclick = () => client.endStream(); ``` -------------------------------- ### HTML Boilerplate for Odyssey Client Demo Source: https://documentation.api.odyssey.ml/sdk/javascript/examples This HTML boilerplate sets up the necessary elements (video player, status display, buttons) and includes a script to initialize and use the Odyssey client. It demonstrates connecting, starting a stream, interacting, and disconnecting, handling basic connection and error states. ```html Odyssey Demo

Disconnected

``` -------------------------------- ### Generate Video from Image with Python Source: https://documentation.api.odyssey.ml/sdk/python/examples Explains how to use the Odyssey API to create a video starting from a provided image. It covers requirements, supported formats, and how to pass image data (file path, PIL Image, bytes, or NumPy array). ```python import asyncio from odyssey import Odyssey, VideoFrame frames = [] def on_frame(frame: VideoFrame) -> None: frames.append(frame.data.copy()) async def main(): client = Odyssey(api_key="ody_your_api_key_here") try: # Connect to Odyssey await client.connect( on_video_frame=on_frame, ) # Start stream with an image (file path) stream_id = await client.start_stream( prompt="A cat", portrait=False, image="/path/to/your/image.jpg" ) print(f"Stream started: {stream_id}") # Interact as usual await client.interact("Pet the cat") await asyncio.sleep(5) await client.end_stream() finally: await client.disconnect() print(f"Collected {len(frames)} frames") asyncio.run(main()) ``` ```python from PIL import Image # Using PIL Image pil_image = Image.open("/path/to/image.jpg") stream_id = await client.start_stream(prompt="A cat", image=pil_image) ``` -------------------------------- ### Example Simulation Script for Simulate API Source: https://documentation.api.odyssey.ml/sdk/javascript/simulations Provides a concrete example of a simulation script using the `ScriptEntry` interface. This script demonstrates starting a video, interacting with prompts at specific times, and ending the stream. It serves as a template for creating custom simulation sequences. ```typescript const script = [ // Start a portrait video of a cat at t=0 { timestamp_ms: 0, start: { prompt: 'A cat sitting by a window' } }, // Interact at t=3000ms (3 seconds) { timestamp_ms: 3000, interact: { prompt: 'The cat looks outside' } }, // Another interaction at t=6000ms (6 seconds) { timestamp_ms: 6000, interact: { prompt: 'The cat stretches' } }, // End the stream at t=9000ms (9 seconds) { timestamp_ms: 9000, end: {} } ]; ``` -------------------------------- ### Complete Example: Run and Monitor Simulation Source: https://documentation.api.odyssey.ml/sdk/javascript/simulations A comprehensive example demonstrating how to initialize the Odyssey client, create a simulation, poll for its status, and download recordings upon completion. Includes error handling for failed simulations. ```typescript import { Odyssey } from '@odysseyml/odyssey'; async function runSimulation() { const client = new Odyssey({ apiKey: 'ody_your_api_key_here' }); // Create simulation const job = await client.simulate({ script: [ { timestamp_ms: 0, start: { prompt: 'A cat sitting on a windowsill' } }, { timestamp_ms: 3000, interact: { prompt: 'The cat watches a bird outside' } }, { timestamp_ms: 6000, interact: { prompt: 'The cat stretches lazily' } }, { timestamp_ms: 9000, interact: { prompt: 'The cat curls up to sleep' } }, { timestamp_ms: 12000, end: {} } ], portrait: true }); console.log('Started simulation:', job.job_id); // Poll for completion let status; do { await new Promise(resolve => setTimeout(resolve, 5000)); status = await client.getSimulateStatus(job.job_id); console.log('Status:', status.status); } while (status.status === 'pending' || status.status === 'running'); if (status.status === 'completed') { // Download recordings for (const stream of status.streams) { const recording = await client.getRecording(stream.stream_id); console.log('Recording ready:', recording.video_url); } } else { console.error('Simulation failed:', status.error_message); } } runSimulation(); ``` -------------------------------- ### Complete Simulation Example Source: https://documentation.api.odyssey.ml/sdk/python/simulations This comprehensive Python example illustrates the end-to-end process of running a simulation, from creation to polling for completion and downloading recordings. It includes basic interaction prompts. ```python import asyncio from odyssey import Odyssey async def run_simulation(): client = Odyssey(api_key="ody_your_api_key_here") # Create simulation job = await client.simulate( script=[ {"timestamp_ms": 0, "start": {"prompt": "A cat sitting on a windowsill"}}, {"timestamp_ms": 3000, "interact": {"prompt": "The cat watches a bird outside"}}, {"timestamp_ms": 6000, "interact": {"prompt": "The cat stretches lazily"}}, {"timestamp_ms": 9000, "interact": {"prompt": "The cat curls up to sleep"}}, {"timestamp_ms": 12000, "end": {}} ], portrait=True ) print(f"Started simulation: {job.job_id}") # Poll for completion status = None while True: await asyncio.sleep(5) status = await client.get_simulate_status(job.job_id) print(f"Status: {status.status}") if status.status not in ("pending", "running"): break if status.status == "completed": # Download recordings for stream in status.streams: recording = await client.get_recording(stream.stream_id) print(f"Recording ready: {recording.video_url}") else: print(f"Simulation failed: {status.error_message}") asyncio.run(run_simulation()) ``` -------------------------------- ### Next.js Text-to-Video with Callback Style Odyssey ML API Source: https://documentation.api.odyssey.ml/api-quick-start This example demonstrates text-to-video generation using the Odyssey ML API with a callback-based approach in Next.js. It shows how to handle connection events, stream status, and errors using provided callback functions. This style is an alternative to the async/await pattern for managing API interactions. ```tsx 'use client'; import { Odyssey } from '@odysseyml/odyssey'; import { useRef, useEffect, useState } from 'react'; const client = new Odyssey({ apiKey: 'ody_your_api_key_here' }); export default function OdysseyDemo() { const videoRef = useRef(null); const [prompt, setPrompt] = useState(''); const [isConnected, setIsConnected] = useState(false); const [isStreaming, setIsStreaming] = useState(false); useEffect(() => () => client.disconnect(), []); const handleConnect = () => { client.connect({ onConnected: (mediaStream) => { if (videoRef.current) videoRef.current.srcObject = mediaStream; setIsConnected(true); }, onStreamStarted: () => setIsStreaming(true), onStreamEnded: () => setIsStreaming(false), onError: (error) => console.error('Error:', error.message), }); }; const handleSend = () => { const text = prompt; setPrompt(''); isStreaming ? client.interact({ prompt: text }) : client.startStream({ prompt: text }); }; return (