117 lines
5.2 KiB
PHP
117 lines
5.2 KiB
PHP
<?php
|
|
header('Content-Type: application/json');
|
|
require_once __DIR__ . '/../db/config.php';
|
|
|
|
try {
|
|
$db = db();
|
|
|
|
// 1. Check if there is an active local "played" song and if it's still playing
|
|
$stmt = $db->query("SELECT *, UNIX_TIMESTAMP(created_at) as started_at FROM song_requests WHERE status = 'played' ORDER BY created_at DESC LIMIT 1");
|
|
$lastPlayed = $stmt->fetch();
|
|
|
|
$isLocalActive = false;
|
|
if ($lastPlayed) {
|
|
$duration = (int)($lastPlayed['duration'] ?? 240);
|
|
$endTime = $lastPlayed['started_at'] + $duration;
|
|
if (time() < $endTime) {
|
|
$isLocalActive = true;
|
|
}
|
|
}
|
|
|
|
// 2. If no local song is active, check if RadioKing is playing something we should wait for
|
|
$shouldWait = $isLocalActive;
|
|
|
|
if (!$isLocalActive) {
|
|
// Optional: Check RadioKing current track end_at
|
|
try {
|
|
$radioKingUrl = 'https://www.radioking.com/widgets/api/v1/radio/828046/track/current';
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $radioKingUrl);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
|
|
$resp = curl_exec($ch);
|
|
curl_close($ch);
|
|
|
|
if ($resp) {
|
|
$data = json_decode($resp, true);
|
|
if (isset($data['end_at'])) {
|
|
$endAt = strtotime($data['end_at']);
|
|
// If the RadioKing song ends in more than 5 seconds, we wait
|
|
if ($endAt > (time() + 5)) {
|
|
$shouldWait = true;
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
// Ignore RadioKing errors and proceed
|
|
}
|
|
}
|
|
|
|
if (!$shouldWait) {
|
|
// 3. Take the oldest pending request and "execute" it using a transaction to avoid race conditions
|
|
$db->beginTransaction();
|
|
try {
|
|
$stmt = $db->query("SELECT * FROM song_requests WHERE status = 'pending' ORDER BY is_priority DESC, created_at ASC LIMIT 1 FOR UPDATE");
|
|
$next = $stmt->fetch();
|
|
|
|
if ($next) {
|
|
// Mark as played immediately within the transaction
|
|
$stmt = $db->prepare("UPDATE song_requests SET status = 'played', created_at = NOW() WHERE id = ?");
|
|
$stmt->execute([$next['id']]);
|
|
$db->commit();
|
|
|
|
// Now that we "own" this request, we can do the slow AI/log operations
|
|
$youtubeUrl = $next['youtube_url'];
|
|
$duration = $next['duration'] ?? 240;
|
|
|
|
if (!$youtubeUrl) {
|
|
try {
|
|
require_once __DIR__ . '/../ai/LocalAIApi.php';
|
|
$artist = $next['artist'];
|
|
$song = $next['song'];
|
|
$aiResp = LocalAIApi::createResponse([
|
|
'input' => [
|
|
['role' => 'system', 'content' => 'Eres un asistente de radio. Tu tarea es encontrar el ID de YouTube oficial y la duración aproximada en segundos para una canción. Responde ÚNICAMENTE con un JSON: {"id": "...", "duration": ...}. Si no estás seguro, usa id null y duration 240.'],
|
|
['role' => 'user', 'content' => "Encuentra el ID de YouTube y duración para: $artist - $song"]
|
|
]
|
|
]);
|
|
if (!empty($aiResp['success'])) {
|
|
$jsonText = LocalAIApi::extractText($aiResp);
|
|
$data = json_decode($jsonText, true);
|
|
if ($data && isset($data['id']) && $data['id'] !== null) {
|
|
$youtubeUrl = "https://www.youtube.com/watch?v={$data['id']}";
|
|
$duration = (int)($data['duration'] ?? 240);
|
|
}
|
|
}
|
|
} catch (Exception $e) {}
|
|
|
|
// Update with AI info
|
|
if ($youtubeUrl) {
|
|
$stmt = $db->prepare("UPDATE song_requests SET youtube_url = ?, duration = ? WHERE id = ?");
|
|
$stmt->execute([$youtubeUrl, $duration, $next['id']]);
|
|
}
|
|
}
|
|
|
|
// Log automation
|
|
$db->prepare("INSERT INTO automation_logs (message) VALUES (?)")->execute(["Auto-DJ ejecutó: {$next['artist']} - {$next['song']}"]);
|
|
|
|
// Announce in chat
|
|
$chatMsg = "🤖 [AUTO-DJ] Es el turno de: **{$next['artist']} - {$next['song']}** (Pedido por: **{$next['requester']}**) 🎧🔥";
|
|
$db->prepare("INSERT INTO messages (username, message, type) VALUES ('Sistema', ?, 'dj_power')")->execute([$chatMsg]);
|
|
|
|
echo json_encode(['success' => true, 'action' => 'executed', 'song' => $next['song']]);
|
|
exit;
|
|
} else {
|
|
$db->rollBack();
|
|
}
|
|
} catch (Exception $e) {
|
|
$db->rollBack();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
echo json_encode(['success' => true, 'action' => 'none']);
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|