50 lines
3.5 KiB
PHP
50 lines
3.5 KiB
PHP
<?php
|
|
|
|
require_once __DIR__ . '/../app/bootstrap.php';
|
|
|
|
use App\Core\Database;
|
|
use App\Services\CurriculumService;
|
|
use App\Services\VideoService;
|
|
use App\Services\AiVideoAnalyzerService;
|
|
|
|
$taskId = $argv[1] ?? '';
|
|
$dir = __DIR__ . '/../storage/curriculum/processing';
|
|
$stateFile = $dir . '/' . basename($taskId) . '.json';
|
|
|
|
function updateVideoTask(string $file, array $changes): void {
|
|
$state = file_exists($file) ? (json_decode(file_get_contents($file), true) ?: []) : [];
|
|
file_put_contents($file, json_encode(array_merge($state, $changes), JSON_UNESCAPED_UNICODE));
|
|
}
|
|
|
|
if ($taskId === '' || !file_exists($stateFile)) exit(1);
|
|
$task = json_decode(file_get_contents($stateFile), true) ?: [];
|
|
|
|
try {
|
|
updateVideoTask($stateFile, ['status' => 'processing', 'progress' => 15, 'message' => 'جاري تحويل الفيديو إلى HLS...']);
|
|
$file = (string)($task['file'] ?? '');
|
|
$manifestLesson = CurriculumService::findLessonByFile($file);
|
|
$title = $manifestLesson['title'] ?? basename($file, '.md');
|
|
$existing = Database::selectOne('SELECT id, course_id FROM lessons WHERE curriculum_key = ? OR title = ? OR markdown_content LIKE ? LIMIT 1', [$file, $title, '%' . $file . '%']);
|
|
$courseId = $existing ? (int)$existing['course_id'] : CurriculumService::getOrCreateSystemCourse();
|
|
$uploaded = VideoService::handleDirectUpload([
|
|
'error' => UPLOAD_ERR_OK, 'tmp_name' => $task['video_path'],
|
|
'name' => $task['original_name'] ?? 'lesson.mp4', 'size' => filesize($task['video_path'])
|
|
], $courseId, $title);
|
|
updateVideoTask($stateFile, ['progress' => 80, 'message' => 'تم رفع حزمة HLS إلى Cloudflare R2، جاري تثبيت الدرس...']);
|
|
$videoUrl = $uploaded['hls_url'] ?? $uploaded['r2_url'] ?? null;
|
|
if ($existing) {
|
|
$lessonId = (int)$existing['id'];
|
|
Database::query("UPDATE lessons SET curriculum_key = ?, storage_type = 'api_upload', video_uuid = ?, bunny_video_id = '', local_path = ?, hls_url = ?, thumbnail_url = ?, duration_seconds = ?, encoding_status = 'ready', ai_video_url = ? WHERE id = ?", [$file, $uploaded['video_uuid'], $uploaded['local_path'], $uploaded['hls_url'], $uploaded['thumbnail_url'], $uploaded['duration'] ?? 0, $videoUrl, $lessonId]);
|
|
} else {
|
|
$lessonId = Database::insert("INSERT INTO lessons (course_id, title, curriculum_key, sequence_order, storage_type, video_uuid, bunny_video_id, local_path, hls_url, thumbnail_url, duration_seconds, is_free_preview, encoding_status, ai_video_url) VALUES (?, ?, ?, 1, 'api_upload', ?, '', ?, ?, ?, ?, 0, 'ready', ?)", [$courseId, $title, $file, $uploaded['video_uuid'], $uploaded['local_path'], $uploaded['hls_url'], $uploaded['thumbnail_url'], $uploaded['duration'] ?? 0, $videoUrl]);
|
|
}
|
|
try { AiVideoAnalyzerService::processLessonAutonomously((int)$lessonId); } catch (Throwable $e) { error_log('Video AI analysis deferred: ' . $e->getMessage()); }
|
|
$assets = CurriculumService::getLessonAiAssets($file);
|
|
$assets['ai_video_url'] = $videoUrl;
|
|
CurriculumService::saveLessonAiAssets($file, $assets);
|
|
updateVideoTask($stateFile, ['status' => 'completed', 'progress' => 100, 'message' => 'تم رفع الفيديو وربطه بالدرس بنجاح.', 'lesson_id' => (int)$lessonId, 'video_url' => $videoUrl]);
|
|
} catch (Throwable $e) {
|
|
if (!empty($task['video_path']) && is_file($task['video_path'])) @unlink($task['video_path']);
|
|
updateVideoTask($stateFile, ['status' => 'error', 'progress' => 100, 'message' => $e->getMessage()]);
|
|
}
|