![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/soundstudiopro.com/private_html/ |
<?php
session_start();
header('Content-Type: application/json');
// Include translation system
require_once 'includes/translations.php';
// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['error' => 'Login required']);
exit;
}
require_once 'config/database.php';
$pdo = getDBConnection();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
// Handle both old and new format
$prompt = $input['prompt'] ?? '';
$title = $input['title'] ?? 'Untitled Track';
$type = $input['type'] ?? 'music';
$model_version = $input['model_version'] ?? 'v1';
$duration = $input['duration'] ?? 30;
// New advanced parameters
$customMode = $input['customMode'] ?? false;
$instrumental = $input['instrumental'] ?? false;
$model_name = $input['model_name'] ?? 'V5';
$variations = $input['variations'] ?? 1;
$tags = $input['tags'] ?? '';
$tempo = $input['tempo'] ?? null;
$key = $input['key'] ?? null;
$scale = $input['scale'] ?? null;
$energy = $input['energy'] ?? 7;
$excitement = $input['excitement'] ?? 6;
$mood = $input['mood'] ?? null;
$genre = $input['genre'] ?? null;
// If no prompt but we have type, create a basic prompt
if (empty($prompt)) {
$prompt = "Create a {$type} track with {$duration} seconds duration using {$model_version}";
}
// If no title, create one from the prompt
if ($title === 'Untitled Track') {
$title = substr($prompt, 0, 50) . (strlen($prompt) > 50 ? '...' : '');
}
if (empty($prompt)) {
http_response_code(400);
echo json_encode(['error' => 'Prompt is required']);
exit;
}
// Check user credits - require credits to generate music
$stmt = $pdo->prepare("SELECT credits FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$user = $stmt->fetch();
// If user has no credits, block the request
if (!$user || $user['credits'] < 1) {
error_log("Insufficient credits for user {$_SESSION['user_id']} to generate music");
echo json_encode([
'success' => false,
'error' => 'Insufficient credits. Please purchase credits to continue generating music.'
]);
exit;
}
// Create track record with enhanced metadata (we'll update task_id after API call)
$temp_task_id = 'temp_' . time() . '_' . $_SESSION['user_id'] . '_' . uniqid();
$metadata = json_encode([
'customMode' => $customMode,
'instrumental' => $instrumental,
'model_name' => $model_name,
'variations' => $variations,
'tags' => $tags,
'tempo' => $tempo,
'key' => $key,
'scale' => $scale,
'energy' => $energy,
'excitement' => $excitement,
'mood' => $mood,
'genre' => $genre,
'duration' => $duration
]);
$stmt = $pdo->prepare("
INSERT INTO music_tracks (user_id, task_id, title, prompt, music_type, status, metadata, is_public, created_at)
VALUES (?, ?, ?, ?, 'music', 'processing', ?, 0, NOW())
");
$stmt->execute([$_SESSION['user_id'], $temp_task_id, $title, $prompt, $metadata]);
$track_id = $pdo->lastInsertId();
// Deduct credit and record transaction
$newCredits = $user['credits'] - 1;
$stmt = $pdo->prepare("UPDATE users SET credits = ? WHERE id = ?");
$stmt->execute([$newCredits, $_SESSION['user_id']]);
// Record credit transaction
$stmt = $pdo->prepare("
INSERT INTO credit_transactions (user_id, amount, type, description, created_at)
VALUES (?, -1, 'usage', 'Music track creation: $title', NOW())
");
$stmt->execute([$_SESSION['user_id']]);
// Update session credits
$_SESSION['credits'] = $newCredits;
// Log credit deduction
error_log("Credit deducted for user {$_SESSION['user_id']}: 1 credit, new balance: $newCredits");
// Call the actual music generation API
$api_url = 'https://api.api.box/api/v1/generate';
$api_data = [
'prompt' => $prompt,
'model' => $model_name,
'style' => $genre ?: 'Pop',
'title' => $title,
'customMode' => $customMode ? 'true' : 'false',
'instrumental' => $instrumental ? 'true' : 'false',
'duration' => $duration,
'callBackUrl' => 'https://soundstudiopro.com/callback.php'
];
// Add advanced parameters if provided
if ($tempo) $api_data['tempo'] = $tempo;
if ($key) $api_data['key'] = $key;
if ($scale) $api_data['scale'] = $scale;
if ($energy) $api_data['energy'] = $energy;
if ($excitement) $api_data['excitement'] = $excitement;
if ($mood) $api_data['mood'] = $mood;
if ($tags) $api_data['tags'] = $tags;
if ($variations > 1) $api_data['variations'] = $variations;
// Log the API request for debugging
error_log("API Request to $api_url: " . json_encode($api_data));
// Music generation access key
$api_key = '63edba40620216c5aa2c04240ac41dbd';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($api_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $api_key,
'Content-Type: application/json',
'User-Agent: SoundStudioPro-Music/2.0'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curl_error = curl_error($ch);
curl_close($ch);
// Log the API response for debugging
error_log("API Response HTTP Code: $http_code");
error_log("API Response: " . $response);
if ($curl_error) {
error_log("cURL Error: " . $curl_error);
}
if ($curl_error) {
// Log curl error
error_log("CURL Error: " . $curl_error);
// Keep track in processing state and let user know about temporary issue
// This allows the system to work even if the API is temporarily down
echo json_encode([
'success' => true,
'data' => [
'track_id' => $track_id,
'task_id' => $temp_task_id,
'status' => 'processing',
'message' => t('success.music_generation.queued'),
'metadata' => [
'customMode' => $customMode,
'instrumental' => $instrumental,
'model_name' => $model_name,
'variations' => $variations,
'tags' => $tags,
'tempo' => $tempo,
'key' => $key,
'scale' => $scale,
'energy' => $energy,
'excitement' => $excitement,
'mood' => $mood,
'genre' => $genre
]
]
]);
exit;
}
// Parse API response
$api_result = json_decode($response, true);
if ($http_code !== 200 || !$api_result) {
// Log API error
error_log("API Error: HTTP $http_code, Response: " . $response);
// Keep track in processing state instead of failing immediately
// This allows for retry mechanisms and better user experience
echo json_encode([
'success' => true,
'data' => [
'track_id' => $track_id,
'task_id' => $temp_task_id,
'status' => 'processing',
'message' => t('success.music_generation.queued'),
'metadata' => [
'customMode' => $customMode,
'instrumental' => $instrumental,
'model_name' => $model_name,
'variations' => $variations,
'tags' => $tags,
'tempo' => $tempo,
'key' => $key,
'scale' => $scale,
'energy' => $energy,
'excitement' => $excitement,
'mood' => $mood,
'genre' => $genre
]
]
]);
exit;
}
// Check if this is a callback-based response (task created)
if (isset($api_result['taskId']) || isset($api_result['id']) || isset($api_result['data']['taskId']) ||
(isset($api_result['status']) && $api_result['status'] === 'processing') ||
(isset($api_result['code']) && $api_result['code'] == 200)) {
// Enhanced task ID extraction for different API response formats
$real_task_id = null;
// Try multiple possible locations for task ID
if (isset($api_result['taskId'])) {
$real_task_id = $api_result['taskId'];
} elseif (isset($api_result['id'])) {
$real_task_id = $api_result['id'];
} elseif (isset($api_result['data']['taskId'])) {
$real_task_id = $api_result['data']['taskId'];
} elseif (isset($api_result['data']['task_id'])) {
$real_task_id = $api_result['data']['task_id'];
} elseif (isset($api_result['task_id'])) {
$real_task_id = $api_result['task_id'];
}
// Log the API response for debugging
error_log("API Response Analysis - taskId found: " . ($real_task_id ? 'YES' : 'NO'));
error_log("API Response Structure: " . json_encode(array_keys($api_result)));
if (isset($api_result['data'])) {
error_log("API Data Structure: " . json_encode(array_keys($api_result['data'])));
}
if ($real_task_id) {
// Update track with real task ID from API.Box
$stmt = $pdo->prepare("UPDATE music_tracks SET task_id = ? WHERE id = ?");
$stmt->execute([$real_task_id, $track_id]);
echo json_encode([
'success' => true,
'data' => [
'track_id' => $track_id,
'task_id' => $real_task_id,
'status' => 'processing',
'message' => t('success.music_generation.started'),
'metadata' => [
'customMode' => $customMode,
'instrumental' => $instrumental,
'model_name' => $model_name,
'variations' => $variations,
'tags' => $tags,
'tempo' => $tempo,
'key' => $key,
'scale' => $scale,
'energy' => $energy,
'excitement' => $excitement,
'mood' => $mood,
'genre' => $genre
]
]
]);
} else {
// No task ID in response, but keep in processing state
// This allows for manual retry and better error handling
error_log("No task ID found in API response - using temporary ID: $temp_task_id");
error_log("Full API response for debugging: " . json_encode($api_result));
echo json_encode([
'success' => true,
'data' => [
'track_id' => $track_id,
'task_id' => $temp_task_id,
'status' => 'processing',
'message' => t('success.music_generation.queued'),
'metadata' => [
'customMode' => $customMode,
'instrumental' => $instrumental,
'model_name' => $model_name,
'variations' => $variations,
'tags' => $tags,
'tempo' => $tempo,
'key' => $key,
'scale' => $scale,
'energy' => $energy,
'excitement' => $excitement,
'mood' => $mood,
'genre' => $genre
]
]
]);
exit;
}
} else {
// Direct response with audio data
$audio_url = $api_result['audio_url'] ?? $api_result['data']['audio_url'] ?? null;
if ($audio_url) {
// Update track with audio data
$stmt = $pdo->prepare("
UPDATE music_tracks
SET status = 'complete', audio_url = ?, duration = ?
WHERE id = ?
");
$stmt->execute([$audio_url, $duration, $track_id]);
echo json_encode([
'success' => true,
'data' => [
'track_id' => $track_id,
'status' => 'complete',
'audio_url' => $audio_url,
'duration' => $duration,
'title' => $title,
'message' => t('success.music_generation.complete'),
'metadata' => [
'customMode' => $customMode,
'instrumental' => $instrumental,
'model_name' => $model_name,
'variations' => $variations,
'tags' => $tags,
'tempo' => $tempo,
'key' => $key,
'scale' => $scale,
'energy' => $energy,
'excitement' => $excitement,
'mood' => $mood,
'genre' => $genre
]
]
]);
} else {
// No audio URL in response, but keep in processing state
error_log("No audio URL in API response: " . $response);
echo json_encode([
'success' => true,
'data' => [
'track_id' => $track_id,
'task_id' => $temp_task_id,
'status' => 'processing',
'message' => t('success.music_generation.queued'),
'metadata' => [
'customMode' => $customMode,
'instrumental' => $instrumental,
'model_name' => $model_name,
'variations' => $variations,
'tags' => $tags,
'tempo' => $tempo,
'key' => $key,
'scale' => $scale,
'energy' => $energy,
'excitement' => $excitement,
'mood' => $mood,
'genre' => $genre
]
]
]);
exit;
}
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'GET') {
$track_id = $_GET['track_id'] ?? null;
if (!$track_id) {
http_response_code(400);
echo json_encode(['error' => 'Track ID required']);
exit;
}
// Get track status
$stmt = $pdo->prepare("
SELECT id, title, prompt, status, audio_url, duration, created_at
FROM music_tracks
WHERE id = ? AND user_id = ?
");
$stmt->execute([$track_id, $_SESSION['user_id']]);
$track = $stmt->fetch();
if (!$track) {
http_response_code(404);
echo json_encode(['error' => 'Track not found']);
exit;
}
echo json_encode([
'success' => true,
'data' => $track
]);
} else {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
}
?>