false, 'error' => 'API Key diperlukan.']); exit(); } if (!isset($data['image']) || !isset($data['prompt'])) { echo json_encode(['success' => false, 'error' => 'Gambar dan prompt diperlukan.']); exit(); } $base64Image = $data['image']; $prompt = $data['prompt']; $duration = $data['duration'] ?? 8; // Default 8 detik $aspectRatio = $data['aspectRatio'] ?? '16:9'; // Default 16:9 $negativePrompt = $data['negativePrompt'] ?? ''; // Hapus prefix data URL jika ada (e.g., "data:image/jpeg;base64,") $base64Image = preg_replace('/^data:image\/(png|jpeg|gif|webp);base64,/', '', $base64Image); // Tentukan MIME type berdasarkan prefix yang mungkin ada atau asumsi $mimeType = 'image/jpeg'; // Asumsi default, sesuaikan jika Anda tahu format aslinya // URL endpoint Gemini API // Untuk generasi video dengan Veo, endpoint dan model bisa sangat spesifik // dan mungkin tidak selalu melalui `gemini-2.0-flash:generateContent`. // Anda HARUS merujuk dokumentasi Veo API terbaru di ai.google.dev/gemini-api/docs/video // Model 'veo-generate-001' atau sejenisnya mungkin memerlukan akses khusus. // Untuk demo, kita akan mencoba menggunakan endpoint generik dengan model yang mungkin mendukung multimodal. $apiUrl = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent?key=" . $apiKey; // Atau jika model Veo spesifik sudah tersedia dan Anda memiliki akses: // $apiUrl = "https://generativelanguage.googleapis.com/v1beta/models/veo-generate-001:generateContent?key=" . $apiKey; $payload = [ 'contents' => [ [ 'role' => 'user', 'parts' => [ ['text' => $prompt], [ 'inlineData' => [ 'mimeType' => $mimeType, 'data' => $base64Image ] ] ] ] ], 'generationConfig' => [ 'temperature' => 0.7, 'topP' => 0.95, 'topK' => 40, // Untuk Veo, parameter seperti durasi, rasio aspek, dll. // mungkin perlu ditambahkan di sini atau di bagian 'tool_config' yang spesifik. // Ini adalah area yang paling mungkin berubah dan memerlukan referensi dokumentasi Veo. // Contoh placeholder (sintaks mungkin salah): // 'videoGenerationParameters' => [ // 'durationSeconds' => (int)$duration, // 'aspectRatio' => $aspectRatio, // 'negativePrompt' => $negativePrompt // ] ] ]; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json' ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $error = curl_error($ch); curl_close($ch); if ($response === false) { echo json_encode(['success' => false, 'error' => 'Gagal memanggil Gemini API: ' . $error]); exit(); } $result = json_decode($response, true); if ($httpCode !== 200) { echo json_encode([ 'success' => false, 'error' => 'API Error: ' . ($result['error']['message'] ?? 'Tidak diketahui'), 'details' => $result ]); exit(); } // Menangani respons API // Respons dari model multimodal (seperti Gemini 1.5 Pro) mungkin mengembalikan teks atau // jika Veo terintegrasi penuh, mungkin mengembalikan data video atau URL. // Ini adalah bagian yang paling mungkin memerlukan penyesuaian saat Veo lebih stabil. if (isset($result['candidates'][0]['content']['parts'])) { $parts = $result['candidates'][0]['content']['parts']; $videoUrl = null; $message = "Respons diterima, mencari video..."; foreach ($parts as $part) { if (isset($part['mimeType']) && strpos($part['mimeType'], 'video/') === 0) { // Jika API mengembalikan video sebagai inlineData (base64) if (isset($part['inlineData']['data'])) { // Untuk demo, kita bisa mengembalikan base64 data video // Namun, ini tidak efisien untuk video besar. // Dalam aplikasi nyata, Anda akan menyimpan ini ke file dan mengembalikan URL. $videoData = $part['inlineData']['data']; // Contoh: Simpan ke file sementara dan berikan URL $tempFileName = 'generated_video_' . uniqid() . '.mp4'; file_put_contents($tempFileName, base64_decode($videoData)); $videoUrl = $tempFileName; // Ini adalah URL lokal di server Anda $message = "Video berhasil dihasilkan dan disimpan di server."; break; } } elseif (isset($part['text'])) { // Jika API mengembalikan teks (misalnya, deskripsi atau konfirmasi) $message = $part['text']; } } if ($videoUrl) { echo json_encode(['success' => true, 'videoUrl' => $videoUrl, 'message' => $message]); } else { echo json_encode(['success' => true, 'message' => $message . " (Video mungkin tidak dihasilkan atau tidak dalam format yang diharapkan.)"]); } } else { echo json_encode(['success' => false, 'error' => 'Format respons API tidak terduga.', 'details' => $result]); } ?>