![]() 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();
require_once 'config/database.php';
// Check if user is admin
if (!isset($_SESSION['is_admin']) || !$_SESSION['is_admin']) {
header('Location: /auth/login.php');
exit;
}
$pdo = getDBConnection();
// Handle form submissions
$message = '';
$action = $_POST['action'] ?? $_GET['action'] ?? '';
// Function to download and store audio files locally
function downloadAndStoreAudio($audioUrl, $taskId, $type = 'main', $variationIndex = null) {
if (empty($audioUrl) || !filter_var($audioUrl, FILTER_VALIDATE_URL)) {
return null;
}
// Create audio storage directory
$audioDir = 'audio_files/';
if (!is_dir($audioDir)) {
mkdir($audioDir, 0755, true);
}
// Generate filename
$extension = pathinfo(parse_url($audioUrl, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'mp3';
if ($type === 'variation' && $variationIndex !== null) {
$filename = "{$taskId}_variation_{$variationIndex}.{$extension}";
} else {
$filename = "{$taskId}.{$extension}";
}
$localPath = $audioDir . $filename;
$webPath = '/audio_files/' . $filename;
// Skip if file already exists
if (file_exists($localPath)) {
return $webPath;
}
// Download the file
$context = stream_context_create([
'http' => [
'timeout' => 300, // 5 minutes timeout
'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
]
]);
$audioContent = file_get_contents($audioUrl, false, $context);
if ($audioContent === false) {
error_log("Failed to download audio from: $audioUrl");
return null;
}
// Save the file
if (file_put_contents($localPath, $audioContent, LOCK_EX)) {
// Set proper permissions
chmod($localPath, 0644);
// Log the download
$downloadLog = [
'timestamp' => date('Y-m-d H:i:s'),
'action' => 'audio_downloaded_sync',
'task_id' => $taskId,
'original_url' => $audioUrl,
'local_path' => $localPath,
'web_path' => $webPath,
'file_size' => strlen($audioContent),
'type' => $type,
'variation_index' => $variationIndex
];
$downloadLogFile = 'logs/audio_downloads.log';
file_put_contents($downloadLogFile, json_encode($downloadLog) . "\n", FILE_APPEND | LOCK_EX);
return $webPath;
}
return null;
}
// Function to extract comprehensive metadata from existing data
function extractComprehensiveMetadata($data) {
return [
// Raw callback data for debugging
'raw_callback' => $data,
// Basic music information
'genre' => $data['genre'] ?? $data['tags'][0] ?? 'Electronic',
'style' => $data['style'] ?? '',
'tags' => $data['tags'] ?? [],
'bpm' => $data['bpm'] ?? $data['tempo'] ?? 120,
'key' => $data['key'] ?? 'C major',
'time_signature' => $data['time_signature'] ?? '4/4',
'mood' => $data['mood'] ?? 'neutral',
'energy' => $data['energy'] ?? 'medium',
'instruments' => $data['instruments'] ?? ['synthesizer'],
// Audio Quality Metrics
'audio_quality' => [
'bitrate' => $data['bitrate'] ?? $data['audio_bitrate'] ?? null,
'sample_rate' => $data['sample_rate'] ?? $data['audio_sample_rate'] ?? null,
'format' => $data['format'] ?? $data['audio_format'] ?? 'mp3',
'channels' => $data['channels'] ?? $data['audio_channels'] ?? 2,
'file_size' => $data['file_size'] ?? null,
'duration' => $data['duration'] ?? null,
'audio_quality_score' => $data['audio_quality_score'] ?? null
],
// Generation Parameters
'generation_parameters' => [
'model_version' => $data['model_version'] ?? $data['model'] ?? 'v3',
'model_name' => $data['model_name'] ?? null,
'temperature' => $data['temperature'] ?? null,
'top_p' => $data['top_p'] ?? null,
'max_tokens' => $data['max_tokens'] ?? null,
'seed' => $data['seed'] ?? null,
'parameters' => $data['parameters'] ?? $data['generation_params'] ?? []
],
// Processing Information
'processing_info' => [
'processing_time' => $data['processing_time'] ?? $data['generation_time'] ?? null,
'queue_time' => $data['queue_time'] ?? null,
'total_time' => $data['total_time'] ?? null,
'start_time' => $data['start_time'] ?? null,
'end_time' => $data['end_time'] ?? null,
'server_id' => $data['server_id'] ?? null,
'worker_id' => $data['worker_id'] ?? null
],
// Cost Information
'cost_info' => [
'api_cost' => $data['api_cost'] ?? $data['cost'] ?? null,
'credits_used' => $data['credits_used'] ?? null,
'currency' => $data['currency'] ?? 'USD',
'pricing_tier' => $data['pricing_tier'] ?? null,
'cost_per_second' => $data['cost_per_second'] ?? null
],
// Waveform Data
'waveform_data' => [
'waveform' => $data['waveform'] ?? $data['waveform_data'] ?? null,
'waveform_url' => $data['waveform_url'] ?? null,
'waveform_points' => $data['waveform_points'] ?? null,
'waveform_resolution' => $data['waveform_resolution'] ?? null
],
// Spectrum Analysis
'spectrum_analysis' => [
'spectrum' => $data['spectrum'] ?? $data['spectrum_data'] ?? null,
'spectrum_url' => $data['spectrum_url'] ?? null,
'frequency_data' => $data['frequency_data'] ?? null,
'spectral_centroid' => $data['spectral_centroid'] ?? null,
'spectral_rolloff' => $data['spectral_rolloff'] ?? null,
'spectral_bandwidth' => $data['spectral_bandwidth'] ?? null
],
// Audio Segments
'audio_segments' => [
'segments' => $data['segments'] ?? $data['audio_segments'] ?? [],
'verse_timestamps' => $data['verse_timestamps'] ?? null,
'chorus_timestamps' => $data['chorus_timestamps'] ?? null,
'bridge_timestamps' => $data['bridge_timestamps'] ?? null,
'intro_timestamps' => $data['intro_timestamps'] ?? null,
'outro_timestamps' => $data['outro_timestamps'] ?? null,
'section_labels' => $data['section_labels'] ?? null
],
// Error Details (for failed generations)
'error_details' => [
'error_code' => $data['error_code'] ?? $data['code'] ?? null,
'error_message' => $data['error_message'] ?? $data['msg'] ?? null,
'error_type' => $data['error_type'] ?? null,
'error_category' => $data['error_category'] ?? null,
'error_suggestions' => $data['error_suggestions'] ?? null,
'retry_available' => $data['retry_available'] ?? null,
'error_timestamp' => $data['error_timestamp'] ?? null
],
// Additional Analysis
'audio_analysis' => [
'loudness' => $data['loudness'] ?? null,
'dynamic_range' => $data['dynamic_range'] ?? null,
'peak_amplitude' => $data['peak_amplitude'] ?? null,
'rms_amplitude' => $data['rms_amplitude'] ?? null,
'zero_crossing_rate' => $data['zero_crossing_rate'] ?? null,
'harmonic_content' => $data['harmonic_content'] ?? null,
'percussive_content' => $data['percussive_content'] ?? null
],
// System Information
'system_info' => [
'created_with' => 'AI Music Generation',
'version' => '3.0',
'sync_processed' => date('Y-m-d H:i:s'),
'api_version' => $data['api_version'] ?? null,
'api_endpoint' => $data['api_endpoint'] ?? null
]
];
}
if ($action === 'sync_all_metadata') {
try {
// Get all tracks with existing metadata
$stmt = $pdo->query("
SELECT id, title, metadata, task_id, audio_url, video_url, status
FROM music_tracks
WHERE status = 'complete'
AND metadata IS NOT NULL
AND metadata != ''
");
$tracks = $stmt->fetchAll();
$updated_count = 0;
$processed_count = 0;
$files_downloaded = 0;
foreach ($tracks as $track) {
$processed_count++;
$metadata = json_decode($track['metadata'], true);
if (!$metadata) {
continue;
}
// Extract comprehensive metadata
$enhanced_metadata = extractComprehensiveMetadata($metadata);
// Download audio files locally
$localAudioUrl = null;
$localVideoUrl = null;
if ($track['audio_url'] && strpos($track['audio_url'], 'http') === 0) {
$localAudioUrl = downloadAndStoreAudio($track['audio_url'], $track['task_id'], 'main');
if ($localAudioUrl) {
$files_downloaded++;
}
}
if ($track['video_url'] && strpos($track['video_url'], 'http') === 0) {
$localVideoUrl = downloadAndStoreAudio($track['video_url'], $track['task_id'], 'video');
if ($localVideoUrl) {
$files_downloaded++;
}
}
// Update individual metadata fields
$updates = [];
$params = [];
// Update main metadata
$updates[] = 'metadata = ?';
$params[] = json_encode($enhanced_metadata);
// Update individual fields
if (isset($enhanced_metadata['audio_quality'])) {
$updates[] = 'audio_quality = ?';
$params[] = json_encode($enhanced_metadata['audio_quality']);
}
if (isset($enhanced_metadata['generation_parameters'])) {
$updates[] = 'generation_parameters = ?';
$params[] = json_encode($enhanced_metadata['generation_parameters']);
}
if (isset($enhanced_metadata['processing_info'])) {
$updates[] = 'processing_info = ?';
$params[] = json_encode($enhanced_metadata['processing_info']);
}
if (isset($enhanced_metadata['cost_info'])) {
$updates[] = 'cost_info = ?';
$params[] = json_encode($enhanced_metadata['cost_info']);
}
if (isset($enhanced_metadata['waveform_data'])) {
$updates[] = 'waveform_data = ?';
$params[] = json_encode($enhanced_metadata['waveform_data']);
}
if (isset($enhanced_metadata['spectrum_analysis'])) {
$updates[] = 'spectrum_analysis = ?';
$params[] = json_encode($enhanced_metadata['spectrum_analysis']);
}
if (isset($enhanced_metadata['audio_segments'])) {
$updates[] = 'audio_segments = ?';
$params[] = json_encode($enhanced_metadata['audio_segments']);
}
if (isset($enhanced_metadata['error_details'])) {
$updates[] = 'error_details = ?';
$params[] = json_encode($enhanced_metadata['error_details']);
}
if (isset($enhanced_metadata['audio_analysis'])) {
$updates[] = 'audio_analysis = ?';
$params[] = json_encode($enhanced_metadata['audio_analysis']);
}
if (isset($enhanced_metadata['system_info'])) {
$updates[] = 'system_info = ?';
$params[] = json_encode($enhanced_metadata['system_info']);
}
// Update audio URLs if local files were downloaded
if ($localAudioUrl) {
$updates[] = 'audio_url = ?';
$params[] = $localAudioUrl;
}
if ($localVideoUrl) {
$updates[] = 'video_url = ?';
$params[] = $localVideoUrl;
}
$params[] = $track['id'];
$sql = "UPDATE music_tracks SET " . implode(', ', $updates) . ", updated_at = NOW() WHERE id = ?";
$update_stmt = $pdo->prepare($sql);
$update_stmt->execute($params);
$updated_count++;
}
$message = "✅ Sync completed! Processed: $processed_count, Updated: $updated_count, Files Downloaded: $files_downloaded";
} catch (Exception $e) {
$message = "❌ Error during sync: " . $e->getMessage();
}
}
// Get statistics
$stats = [];
try {
// Total tracks
$stmt = $pdo->query("SELECT COUNT(*) as total FROM music_tracks WHERE status = 'complete'");
$stats['total_tracks'] = $stmt->fetch()['total'];
// Tracks with metadata
$stmt = $pdo->query("SELECT COUNT(*) as total FROM music_tracks WHERE status = 'complete' AND metadata IS NOT NULL AND metadata != ''");
$stats['tracks_with_metadata'] = $stmt->fetch()['total'];
// Tracks with local files
$stmt = $pdo->query("SELECT COUNT(*) as total FROM music_tracks WHERE status = 'complete' AND audio_url LIKE '/audio_files/%'");
$stats['tracks_with_local_files'] = $stmt->fetch()['total'];
// Tracks with enhanced metadata
$stmt = $pdo->query("SELECT COUNT(*) as total FROM music_tracks WHERE status = 'complete' AND audio_quality IS NOT NULL");
$stats['tracks_with_enhanced_metadata'] = $stmt->fetch()['total'];
} catch (Exception $e) {
$stats['error'] = $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Comprehensive Metadata Sync</title>
<style>
body {
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
}
.container {
max-width: 1000px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 10px;
backdrop-filter: blur(10px);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 20px 0;
}
.stat-card {
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 8px;
text-align: center;
}
.stat-number {
font-size: 2em;
font-weight: bold;
color: #48bb78;
}
.stat-label {
font-size: 0.9em;
opacity: 0.8;
}
.sync-button {
background: linear-gradient(135deg, #48bb78, #38a169);
color: white;
border: none;
padding: 15px 30px;
border-radius: 8px;
cursor: pointer;
font-size: 1.1em;
margin: 10px;
}
.sync-button:hover {
transform: translateY(-2px);
}
.message {
padding: 15px;
border-radius: 8px;
margin: 20px 0;
}
.success { background: rgba(72, 187, 120, 0.3); }
.error { background: rgba(245, 101, 101, 0.3); }
.info { background: rgba(102, 126, 234, 0.3); }
</style>
</head>
<body>
<div class="container">
<h1>🔄 Comprehensive Metadata Sync</h1>
<?php if ($message): ?>
<div class="message <?= strpos($message, '✅') !== false ? 'success' : 'error' ?>">
<?= htmlspecialchars($message) ?>
</div>
<?php endif; ?>
<h2>📊 Current Statistics</h2>
<div class="stats-grid">
<div class="stat-card">
<div class="stat-number"><?= number_format($stats['total_tracks'] ?? 0) ?></div>
<div class="stat-label">Total Tracks</div>
</div>
<div class="stat-card">
<div class="stat-number"><?= number_format($stats['tracks_with_metadata'] ?? 0) ?></div>
<div class="stat-label">With Metadata</div>
</div>
<div class="stat-card">
<div class="stat-number"><?= number_format($stats['tracks_with_local_files'] ?? 0) ?></div>
<div class="stat-label">Local Files</div>
</div>
<div class="stat-card">
<div class="stat-number"><?= number_format($stats['tracks_with_enhanced_metadata'] ?? 0) ?></div>
<div class="stat-label">Enhanced Metadata</div>
</div>
</div>
<h2>🚀 Sync Actions</h2>
<form method="post">
<input type="hidden" name="action" value="sync_all_metadata">
<button type="submit" class="sync-button">
🔄 Sync All Metadata & Download Files
</button>
</form>
<div class="info message">
<h3>What this sync does:</h3>
<ul>
<li>✅ Extracts comprehensive metadata from existing callback data</li>
<li>✅ Downloads all audio files locally to /audio_files/</li>
<li>✅ Updates database with individual metadata columns</li>
<li>✅ Preserves original data while adding new structure</li>
<li>✅ Logs all download activities</li>
</ul>
</div>
<h2>📋 Missing Data on Cards</h2>
<div class="info message">
<h3>Data that could be displayed on track cards:</h3>
<ul>
<li>🎵 <strong>Audio Quality</strong>: Bitrate, Sample Rate, Format</li>
<li>⏱️ <strong>Processing Time</strong>: How long generation took</li>
<li>💰 <strong>Cost Info</strong>: API cost, credits used</li>
<li>🎚️ <strong>Generation Parameters</strong>: Model version, temperature</li>
<li>📊 <strong>Audio Analysis</strong>: Loudness, dynamic range</li>
<li>🎼 <strong>Audio Segments</strong>: Verse/chorus timestamps</li>
<li>🌊 <strong>Waveform Data</strong>: Visual waveform display</li>
<li>📈 <strong>Spectrum Analysis</strong>: Frequency data</li>
</ul>
</div>
</div>
</body>
</html>