37689-vm/api/generate.php
2026-01-25 17:56:38 +00:00

184 lines
7.3 KiB
PHP

<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../includes/pexels.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['success' => false, 'error' => 'Invalid request method']);
exit;
}
$type = $_POST['type'] ?? 'photo';
$prompt = $_POST['prompt'] ?? '';
$style = $_POST['style'] ?? '';
$aspect_ratio = $_POST['aspect_ratio'] ?? '1:1';
$rapidapi_key = $_POST['rapidapi_key'] ?? '';
$video_provider = $_POST['video_provider'] ?? 'pexels'; // 'pexels' or 'ai'
if (empty($prompt)) {
echo json_encode(['success' => false, 'error' => 'Запрос не может быть пустым']);
exit;
}
// Map aspect ratios to dimensions
$dimensions = [
'1:1' => [1024, 1024],
'16:9' => [1280, 720],
'9:16' => [720, 1280],
'4:3' => [1024, 768],
'3:2' => [1080, 720]
];
$width = $dimensions[$aspect_ratio][0] ?? 1024;
$height = $dimensions[$aspect_ratio][1] ?? 1024;
// Enhance prompt with style
$enhanced_prompt = $prompt;
if (!empty($style)) {
$style_map = [
'anime' => 'in anime style, high quality, vibrant colors',
'realism' => 'photorealistic, highly detailed, 8k, masterpiece',
'cyberpunk' => 'cyberpunk style, neon lights, futuristic, highly detailed',
'vaporwave' => 'vaporwave aesthetic, pink and blue colors, retro-futuristic',
'pixel-art' => 'pixel art style, 8-bit, retro game aesthetic',
'fantasy' => 'fantasy art, magical atmosphere, epic, highly detailed',
'3d-render' => '3d render, octane render, cinematic lighting, unreal engine 5',
'steampunk' => 'steampunk style, gears, brass, Victorian aesthetic',
'oil-painting' => 'oil painting, brush strokes, artistic, classic masterpiece',
'sketch' => 'pencil sketch, hand drawn, artistic, charcoal',
'pop-art' => 'pop art style, Andy Warhol aesthetic, vibrant, bold colors',
'minimalism' => 'minimalist style, clean lines, simple, elegant',
'cinematic' => 'cinematic shot, dramatic lighting, movie still, high contrast'
];
if (isset($style_map[$style])) {
$enhanced_prompt .= ", " . $style_map[$style];
}
}
try {
$result_url = '';
$is_ai = false;
$provider_name = '';
$message = '';
if ($type === 'photo') {
$is_ai = true;
$provider_name = 'Pollinations AI (Flux)';
// Real AI Generation (Truly free)
$seed = rand(1000, 99999);
$encoded_prompt = urlencode($enhanced_prompt);
$api_url = "https://image.pollinations.ai/prompt/{$encoded_prompt}?width={$width}&height={$height}&seed={$seed}&model=flux&nologo=true";
$filename = 'assets/images/pexels/gen_' . md5($enhanced_prompt . $seed) . '.jpg';
$target = __DIR__ . '/../' . $filename;
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$image_data = curl_exec($ch);
$content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code === 200 && strpos($content_type, 'image') !== false && $image_data) {
file_put_contents($target, $image_data);
$result_url = $filename;
} else {
// Fallback to direct URL if saving failed
$result_url = $api_url;
}
} else {
// Video Logic
if ($video_provider === 'ai') {
if (!empty($rapidapi_key)) {
$is_ai = true;
$provider_name = 'RapidAPI AI';
// Attempt real AI Video generation
// Note: Different APIs have different formats, this is a generic attempt
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://text-to-video2.p.rapidapi.com/generate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(["prompt" => $enhanced_prompt]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-RapidAPI-Host: text-to-video2.p.rapidapi.com",
"X-RapidAPI-Key: " . $rapidapi_key
],
]);
$response = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if (!$err) {
$res_data = json_decode($response, true);
if (isset($res_data['video_url'])) {
$result_url = $res_data['video_url'];
} else if (isset($res_data['url'])) {
$result_url = $res_data['url'];
}
}
}
if (empty($result_url)) {
// Fallback to Pexels search if no key or API failed
$is_ai = false;
$provider_name = 'Pexels Stock (Fallback)';
if (empty($rapidapi_key)) {
$message = 'Ключ RapidAPI не найден. Используется качественный стоковый поиск вместо ИИ-генерации.';
} else {
$message = 'Ошибка API генерации. Используется стоковый поиск.';
}
$url = 'https://api.pexels.com/videos/search?query=' . urlencode($prompt) . '&per_page=1&page=1';
$data = pexels_get($url);
if ($data && !empty($data['videos'])) {
foreach ($data['videos'][0]['video_files'] as $file) {
if ($file['quality'] === 'hd' || $file['quality'] === 'sd') {
$result_url = $file['link'];
break;
}
}
}
}
} else {
// Standard Pexels Stock
$is_ai = false;
$provider_name = 'Pexels Stock';
$url = 'https://api.pexels.com/videos/search?query=' . urlencode($prompt) . '&per_page=1&page=1';
$data = pexels_get($url);
if ($data && !empty($data['videos'])) {
foreach ($data['videos'][0]['video_files'] as $file) {
if ($file['quality'] === 'hd' || $file['quality'] === 'sd') {
$result_url = $file['link'];
break;
}
}
}
}
if (empty($result_url)) {
$result_url = 'https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4';
}
}
// Save to history
$stmt = db()->prepare("INSERT INTO media_history (type, prompt, result_url) VALUES (?, ?, ?)");
$stmt->execute([$type, $prompt . ($style ? " ($style)" : ""), $result_url]);
echo json_encode([
'success' => true,
'type' => $type,
'url' => $result_url,
'prompt' => $prompt,
'is_ai' => $is_ai,
'provider' => $provider_name,
'message' => $message
]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}