DIFFICULTIES TO GET GENERATED VIDEOS URL BACK IN ORDER TO DISPLAY THEM ON MY WEB APP
'Annie_expressive4_public',
'teaching' => 'Annie_expressive4_public',
'project_management'=> 'Annie_expressive4_public',
'pharmacy' => 'Annie_expressive4_public',
'agro' => 'Annie_expressive4_public',
];
$VOICE_ID = '0b41c487c6da4f5ba5782bbe462958e8';
// === UTILS ===
function logMessage($msg) {
$logFile = __DIR__ . '/logs/avatar_gen.log';
if (!is_dir(dirname($logFile))) mkdir(dirname($logFile), 0755, true);
$timestamp = date('Y-m-d H:i:s');
error_log("[$timestamp] [AvatarGen] $msg\n", 3, $logFile);
echo "[$timestamp] $msg\n";
}
function heyGenRequest($method, $url, $payload = null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json',
'X-Api-Key: ' . HEYGEN_API_KEY
]);
if ($method === 'POST' && $payload) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
}
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new Exception("cURL error: $error");
}
// π Debug temporaire
if ($http_code !== 200) {
logMessage("DEBUG HTTP $http_code - URL: $url");
logMessage("DEBUG Response: " . substr($response, 0, 200));
}
return [$http_code, json_decode($response, true)];
}
// === ΓTAPE 1 : Lancer la gΓ©nΓ©ration ===
function generateVideo($text, $user_group) {
global $AVATAR_MAP, $VOICE_ID;
$avatar_id = $AVATAR_MAP[$user_group] ?? $AVATAR_MAP['default'];
$payload = [
"video_inputs" => [[
"character" => [
"type" => "avatar",
"avatar_id" => $avatar_id,
"scale" => 1
],
"voice" => [
"type" => "text",
"input_text" => $text,
"voice_id" => $VOICE_ID
],
"background" => ["type" => "color", "value" => "#f8fafc"]
]],
"dimension" => ["width" => 1920, "height" => 1080],
"test" => false,
"caption" => false
];
for ($attempt = 1; $attempt <= MAX_RETRIES; $attempt++) {
try {
[$code, $data] = heyGenRequest('POST', HEYGEN_API_URL, $payload);
if ($code === 200 && !empty($data['data']['video_id'])) {
return $data['data']['video_id'];
} else {
$msg = "HeyGen error (attempt $attempt): HTTP $code - " . ($data['message'] ?? json_encode($data));
logMessage($msg);
if ($attempt < MAX_RETRIES) sleep(RETRY_DELAY_SEC);
}
} catch (Exception $e) {
logMessage("Exception (attempt $attempt): " . $e->getMessage());
if ($attempt < MAX_RETRIES) sleep(RETRY_DELAY_SEC);
}
}
throw new Exception("Γchec aprΓ¨s " . MAX_RETRIES . " tentatives.");
}
// === ΓTAPE 2 : Attendre la fin de la gΓ©nΓ©ration ===
function waitForVideoCompletion($video_id) {
$elapsed = 0;
$check_interval = 5;
$max_checks = MAX_WAIT_SEC / $check_interval;
logMessage("β³ Attente de la complΓ©tion de la vidΓ©o (max " . MAX_WAIT_SEC . " sec)...");
logMessage("π Video ID: $video_id");
// DΓ©lai initial plus long (HeyGen met du temps Γ indexer)
sleep(25);
for ($check = 1; $check <= $max_checks; $check++) {
try {
// β
CORRECTION DΓFINITIVE : POST avec video_id dans le body JSON (API v1)
$payload = ['video_id' => $video_id];
[$code, $data] = heyGenRequest('POST', HEYGEN_STATUS_URL, $payload);
if ($code === 200 && !empty($data['data'])) {
$status = $data['data']['status'] ?? 'unknown';
logMessage("CallCheck #$check (elapsed: {$elapsed}s) - Statut: $status");
if ($status === 'completed') {
$video_url = $data['data']['video_url'] ?? null;
if ($video_url) {
logMessage("β
URL CDN trouvΓ©e : $video_url");
return $video_url;
}
// Recherche alternative dans assets
$assets = $data['data']['assets'] ?? [];
foreach ($assets as $asset) {
if (isset($asset['type']) && $asset['type'] === 'video' && isset($asset['url'])) {
$video_url = $asset['url'];
logMessage("β
URL trouvΓ©e dans assets : $video_url");
return $video_url;
}
}
throw new Exception("VidΓ©o complΓ©tΓ©e mais URL non trouvΓ©e");
} elseif ($status === 'failed') {
$reason = $data['data']['reason'] ?? 'Unknown';
throw new Exception("Γchec HeyGen : $reason");
}
} else {
$error_msg = $data['message'] ?? json_encode($data);
logMessage("β οΈ CheckCall #$check - HTTP $code - $error_msg");
}
sleep($check_interval);
$elapsed += $check_interval;
} catch (Exception $e) {
logMessage("β οΈ CheckCall #$check erreur: " . $e->getMessage());
sleep($check_interval);
$elapsed += $check_interval;
}
}
throw new Exception("Timeout après " . MAX_WAIT_SEC . " secondes");
}
// === ΓTAPE 3 : Mettre Γ jour la base ===
function updateMediaUrl($conn, $content_date, $user_group, $video_url) {
logMessage("πΎ Mise Γ jour de la base de donnΓ©es...");
$stmt = $conn->prepare("
UPDATE daily_content
SET media_url = :url, media_type = 'video'
WHERE content_date = :date AND user_group = :group
");
$stmt->execute([
':url' => $video_url,
':date' => $content_date,
':group' => $user_group
]);
$rows = $stmt->rowCount();
logMessage("β
Base mise Γ jour : $rows ligne(s) modifiΓ©e(s) - $user_group / $content_date β $video_url");
// VΓ©rification
$verify = $conn->prepare("
SELECT media_url, media_type
FROM daily_content
WHERE content_date = :date AND user_group = :group
");
$verify->execute([':date' => $content_date, ':group' => $user_group]);
$result = $verify->fetch(PDO::FETCH_ASSOC);
if ($result && !empty($result['media_url'])) {
logMessage("π VΓ©rification BDD : OK β " . substr($result['media_url'], 0, 60) . "...");
} else {
logMessage("β οΈ VΓ©rification BDD : ΓCHOUΓE");
}
}
// === SCRIPT PRINCIPAL ===
try {
logMessage("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ");
logMessage("β DΓMARRAGE GΓNΓRATION VIDΓO HEYGEN v2 β");
logMessage("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ");
$stmt = $conn->prepare("
SELECT id, content_date, user_group, reading_text
FROM daily_content
WHERE content_date = :today
AND (media_url IS NULL OR media_url = '' OR media_type != 'video')
AND reading_text IS NOT NULL AND TRIM(reading_text) != ''
");
$stmt->execute([':today' => date('Y-m-d')]);
$contents = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($contents)) {
logMessage("βΉοΈ Aucun contenu Γ traiter aujourd'hui.");
exit(0);
}
logMessage("π " . count($contents) . " contenu(s) trouvΓ©(s) Γ traiter");
foreach ($contents as $row) {
$text = trim($row['reading_text']);
$user_group = $row['user_group'];
$content_date = $row['content_date'];
$content_id = $row['id'];
if (empty($text)) continue;
logMessage("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ");
logMessage("π¬ Traitement : $user_group / $content_date (ID: $content_id)");
logMessage("π Texte (premiers 50 caractΓ¨res): " . substr($text, 0, 50) . "...");
try {
$video_id = generateVideo($text, $user_group);
logMessage("β³ Job HeyGen lancΓ© : $video_id");
logMessage("π Suivre sur : https://app.heygen.com/videos/$video_id");
$video_url = waitForVideoCompletion($video_id);
if (empty($video_url)) {
throw new Exception("URL de vidΓ©o vide");
}
updateMediaUrl($conn, $content_date, $user_group, $video_url);
logMessage("β
VIDΓO GΓNΓRΓE ET STOCKΓE !");
logMessage("π¬ URL publique : $video_url");
} catch (Exception $e) {
logMessage("β ΓCHEC pour $user_group : " . $e->getMessage());
}
}
logMessage("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ");
logMessage("β GΓNΓRATION TERMINΓE β");
logMessage("ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ");
logMessage("π‘ Rechargez enregistrement.php pour voir la vidΓ©o !");
} catch (Exception $e) {
logMessage("π₯ ERREUR CRITIQUE : " . $e->getMessage());
exit(1);
}
?>
last month by ADOUAN ANTOINE