feat: Add AiVideoGeneratorService for automated lively video script generation
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Core\Database;
|
||||
use App\Core\Env;
|
||||
|
||||
class AiVideoGeneratorService
|
||||
{
|
||||
/**
|
||||
* Step 1: Generate the Educational Script using Gemini
|
||||
* Takes the complex Markdown and simplifies it into a lively script with examples.
|
||||
*/
|
||||
public static function generateLivelyScript(int $lessonId): ?array
|
||||
{
|
||||
$lesson = Database::selectOne(
|
||||
"SELECT l.*, c.subject_id FROM lessons l JOIN courses c ON l.course_id = c.id WHERE l.id = ?",
|
||||
[$lessonId]
|
||||
);
|
||||
|
||||
if (!$lesson || empty($lesson['markdown_content'])) {
|
||||
throw new \Exception("Lesson not found or has no markdown content.");
|
||||
}
|
||||
|
||||
// Determine Language based on subject or content (assuming Subject ID 2 might be English)
|
||||
$isEnglish = ($lesson['subject_id'] == 2) || (stripos($lesson['title'], 'english') !== false);
|
||||
|
||||
$prompt = self::buildPrompt($lesson['title'], $lesson['markdown_content'], $isEnglish);
|
||||
|
||||
// Call Gemini to get the script
|
||||
return self::callGemini($prompt);
|
||||
}
|
||||
|
||||
private static function buildPrompt(string $title, string $content, bool $isEnglish): string
|
||||
{
|
||||
if ($isEnglish) {
|
||||
return "You are a world-class, enthusiastic English teacher.
|
||||
Transform the following lesson content into a lively, highly engaging video script.
|
||||
Use simple vocabulary, lots of practical examples, and a friendly tone.
|
||||
Output as JSON: {\"narration_text\": \"...\", \"visual_cues\": \"...\"}
|
||||
|
||||
Lesson Title: {$title}
|
||||
Content: {$content}";
|
||||
} else {
|
||||
return "أنت معلم خبير، مبدع ومحبوب جداً لدى الطلاب.
|
||||
قم بتحويل محتوى الدرس التالي إلى (سكربت/سيناريو) مفعم بالحيوية والنشاط لتسجيله كفيديو تعليمي.
|
||||
يجب أن يكون الشرح بسيطاً جداً، يستخدم أمثلة من الحياة الواقعية، وبلغة عربية فصحى مبسطة (أو لهجة قريبة للقلب).
|
||||
|
||||
أريد الإجابة بصيغة JSON فقط كالتالي:
|
||||
{
|
||||
\"narration_text\": \"النص الذي سيقرأه المعلم الذكي أو التعليق الصوتي\",
|
||||
\"visual_cues\": \"وصف للمشاهد البصرية أو الرسوم التي يجب أن تظهر على الشاشة\"
|
||||
}
|
||||
|
||||
عنوان الدرس: {$title}
|
||||
المحتوى: {$content}";
|
||||
}
|
||||
}
|
||||
|
||||
private static function callGemini(string $prompt): ?array
|
||||
{
|
||||
$apiKey = Env::get('GEMINI_API_KEY');
|
||||
if (!$apiKey) return null;
|
||||
|
||||
$model = Env::get('GEMINI_MODEL') ?: 'gemini-flash-lite-latest';
|
||||
$url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent?key={$apiKey}";
|
||||
|
||||
$payload = [
|
||||
'contents' => [['parts' => [['text' => $prompt]]]],
|
||||
'generationConfig' => ['responseMimeType' => 'application/json', 'temperature' => 0.7]
|
||||
];
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => json_encode($payload),
|
||||
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 60
|
||||
]);
|
||||
$res = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if (!$res) return null;
|
||||
|
||||
$json = json_decode($res, true);
|
||||
$text = $json['candidates'][0]['content']['parts'][0]['text'] ?? '';
|
||||
|
||||
$text = preg_replace('/^```json\s*/i', '', $text);
|
||||
$text = preg_replace('/```\s*$/i', '', $text);
|
||||
|
||||
return json_decode(trim($text), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 2: Call external AI Video/Avatar API (e.g., HeyGen, Synthesia)
|
||||
* (Placeholder for future API integration)
|
||||
*/
|
||||
public static function triggerVideoGenerationApi(int $lessonId, string $scriptText): string
|
||||
{
|
||||
// TODO: Integrate with specific Video API (HeyGen, D-ID, Synthesia)
|
||||
// 1. Send $scriptText to API
|
||||
// 2. Receive Webhook or Poll for MP4 URL
|
||||
// 3. Download MP4
|
||||
// 4. Pass MP4 to our VideoService::transcodeToHls()
|
||||
|
||||
return "pending_api_integration";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user