import React, { useState } from 'react'; import { generateVideo } from '../services/geminiService'; import { AspectRatio } from '../types'; import Loader from './Loader'; import { LandscapeIcon, PortraitIcon, SparklesIcon } from './icons'; interface VideoGeneratorProps { onApiKeyError: () => void; } const VideoGenerator: React.FC = ({ onApiKeyError }) => { const initialPrompt = "A tiny orange-and-white fluffy kitten, about 2 months old, with big teary blue eyes, stands trembling between speeding cars on a busy asphalt highway. The kitten’s fur is slightly dirty and windblown. A torn cardboard box lies nearby. Background shows blurred cars passing fast, grey sky above. Realistic cinematic lighting, shallow depth of field, emotional atmosphere, high detail."; const [prompt, setPrompt] = useState(initialPrompt); const [aspectRatio, setAspectRatio] = useState('16:9'); const [isLoading, setIsLoading] = useState(false); const [loadingMessage, setLoadingMessage] = useState(''); const [videoUrl, setVideoUrl] = useState(null); const [error, setError] = useState(null); const handleGenerate = async () => { setIsLoading(true); setError(null); setVideoUrl(null); try { const url = await generateVideo(prompt, aspectRatio, setLoadingMessage); setVideoUrl(url); } catch (e: unknown) { const err = e as Error; if (err.message.includes("Requested entity was not found")) { setError("API Key error. Please re-select your API key."); onApiKeyError(); } else { try { // The API often returns errors as a JSON string in the message const errorJson = JSON.parse(err.message); if (errorJson?.error?.status === 'RESOURCE_EXHAUSTED') { setError('QUOTA_EXCEEDED'); } else { setError(errorJson?.error?.message || err.message); } } catch (parseError) { // The error message is not a JSON string. setError(err.message); } } } finally { setIsLoading(false); setLoadingMessage(''); } }; const AspectRatioButton = ({ value, label, icon }: { value: AspectRatio, label: string, icon: React.ReactElement }) => ( ); return (
{/* Control Panel */}

Video Prompt

Describe the video you want to create. Be as detailed as possible for the best results.