![]() 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/components/ |
<?php
// Enhanced Track Card Component
// Displays comprehensive metadata from the new callback system
function renderEnhancedTrackCard($track) {
// Parse metadata
$metadata = json_decode($track['metadata'], true);
$audioQuality = json_decode($track['audio_quality'], true);
$generationParams = json_decode($track['generation_parameters'], true);
$processingInfo = json_decode($track['processing_info'], true);
$costInfo = json_decode($track['cost_info'], true);
$waveformData = json_decode($track['waveform_data'], true);
$spectrumAnalysis = json_decode($track['spectrum_analysis'], true);
$audioSegments = json_decode($track['audio_segments'], true);
$audioAnalysis = json_decode($track['audio_analysis'], true);
// Extract values with fallbacks
$bpm = $metadata['bpm'] ?? $track['bpm'] ?? 120;
$key = $metadata['key'] ?? $track['key'] ?? 'C maj';
$mood = $metadata['mood'] ?? $track['mood'] ?? 'Neutral';
$energy = $metadata['energy'] ?? $track['energy'] ?? 'Medium';
$genre = $metadata['genre'] ?? $track['genre'] ?? 'Electronic';
// Audio quality info
$bitrate = $audioQuality['bitrate'] ?? null;
$sampleRate = $audioQuality['sample_rate'] ?? null;
$format = $audioQuality['format'] ?? 'mp3';
$fileSize = $audioQuality['file_size'] ?? null;
$qualityScore = $audioQuality['audio_quality_score'] ?? null;
// Processing info
$processingTime = $processingInfo['processing_time'] ?? null;
$queueTime = $processingInfo['queue_time'] ?? null;
$totalTime = $processingInfo['total_time'] ?? null;
// Cost info
$apiCost = $costInfo['api_cost'] ?? null;
$creditsUsed = $costInfo['credits_used'] ?? null;
$currency = $costInfo['currency'] ?? 'USD';
// Generation parameters
$modelVersion = $generationParams['model_version'] ?? null;
$modelName = $generationParams['model_name'] ?? null;
$temperature = $generationParams['temperature'] ?? null;
$seed = $generationParams['seed'] ?? null;
// Audio analysis
$loudness = $audioAnalysis['loudness'] ?? null;
$dynamicRange = $audioAnalysis['dynamic_range'] ?? null;
$peakAmplitude = $audioAnalysis['peak_amplitude'] ?? null;
// Audio segments
$segments = $audioSegments['segments'] ?? [];
$verseTimestamps = $audioSegments['verse_timestamps'] ?? [];
$chorusTimestamps = $audioSegments['chorus_timestamps'] ?? [];
// Waveform data
$waveform = $waveformData['waveform'] ?? null;
$waveformUrl = $waveformData['waveform_url'] ?? null;
// Spectrum analysis
$spectralCentroid = $spectrumAnalysis['spectral_centroid'] ?? null;
$spectralRolloff = $spectrumAnalysis['spectral_rolloff'] ?? null;
// Price calculation
$artist_plan = $track['plan'] ?? 'free';
$is_free_user = (strtolower($artist_plan) === 'free');
$display_price = $is_free_user ? 1.99 : ($track['price'] ?? 2.99);
$price_label = $display_price == 0 ? 'FREE' : '$' . number_format($display_price, 2);
// Format file size
$formattedFileSize = $fileSize ? formatBytes($fileSize) : null;
// Format processing time
$formattedProcessingTime = $processingTime ? formatTime($processingTime) : null;
// Format cost
$formattedCost = $apiCost ? '$' . number_format($apiCost, 4) : null;
// Generate waveform bars from data or random
$waveformBars = [];
if ($waveform && is_array($waveform)) {
$waveformBars = array_slice($waveform, 0, 25); // Limit to 25 bars
} else {
// Generate random waveform bars
for ($i = 0; $i < 25; $i++) {
$waveformBars[] = rand(20, 100);
}
}
// Generate segment timeline
$segmentTimeline = '';
if (!empty($segments)) {
$segmentTimeline = '<div class="segment-timeline">';
foreach ($segments as $segment) {
$start = formatTime($segment['start']);
$end = formatTime($segment['end']);
$type = ucfirst($segment['type']);
$confidence = isset($segment['confidence']) ? round($segment['confidence'] * 100) : 0;
$segmentTimeline .= "<span class='segment' title='$type ($start-$end, $confidence% confidence)'>$type</span>";
}
$segmentTimeline .= '</div>';
}
ob_start();
?>
<div class="track-card enhanced-card" data-track-id="<?= $track['id'] ?>">
<!-- Enhanced Header -->
<div class="enhanced-header">
<div class="artist-info">
<div class="artist-avatar">
<?php if (!empty($track['profile_image'])): ?>
<img src="<?= htmlspecialchars($track['profile_image']) ?>" alt="<?= htmlspecialchars($track['artist_name']) ?>">
<?php else: ?>
<div class="default-avatar"><?= substr(htmlspecialchars($track['artist_name']), 0, 1) ?></div>
<?php endif; ?>
</div>
<div class="track-info">
<div class="track-title"><?= htmlspecialchars($track['title'] ?: 'Untitled Track') ?></div>
<div class="artist-name">by <?= htmlspecialchars($track['artist_name']) ?></div>
<div class="track-meta">
<span class="genre-badge"><?= htmlspecialchars($genre) ?></span>
<?php if ($modelVersion): ?>
<span class="model-badge"><?= htmlspecialchars($modelVersion) ?></span>
<?php endif; ?>
</div>
</div>
</div>
<!-- Enhanced Actions -->
<div class="enhanced-actions">
<button class="action-btn play-btn" onclick="playTrack(<?= $track['id'] ?>, '<?= htmlspecialchars($track['audio_url'], ENT_QUOTES) ?>', '<?= htmlspecialchars($track['title'], ENT_QUOTES) ?>', '<?= htmlspecialchars($track['artist_name'], ENT_QUOTES) ?>')">
<i class="fas fa-play"></i>
</button>
<button class="action-btn cart-btn" onclick="addToCart(<?= $track['id'] ?>, '<?= htmlspecialchars($track['title'], ENT_QUOTES) ?>', <?= $display_price ?>, this)">
<i class="fas fa-shopping-cart"></i>
</button>
<div class="price-display"><?= $price_label ?></div>
</div>
</div>
<!-- Enhanced DJ Tech Grid -->
<div class="enhanced-dj-tech">
<div class="tech-item">
<span class="tech-label">BPM</span>
<span class="tech-value"><?= $bpm ?></span>
</div>
<div class="tech-item">
<span class="tech-label">KEY</span>
<span class="tech-value"><?= $key ?></span>
</div>
<div class="tech-item">
<span class="tech-label">MOOD</span>
<span class="tech-value"><?= $mood ?></span>
</div>
<div class="tech-item">
<span class="tech-label">ENERGY</span>
<span class="tech-value"><?= $energy ?></span>
</div>
</div>
<!-- Audio Quality Metrics -->
<?php if ($bitrate || $sampleRate || $qualityScore): ?>
<div class="audio-quality-metrics">
<h4>🎵 Audio Quality</h4>
<div class="metrics-grid">
<?php if ($bitrate): ?>
<div class="metric">
<span class="metric-label">Bitrate</span>
<span class="metric-value"><?= $bitrate ?> kbps</span>
</div>
<?php endif; ?>
<?php if ($sampleRate): ?>
<div class="metric">
<span class="metric-label">Sample Rate</span>
<span class="metric-value"><?= number_format($sampleRate) ?> Hz</span>
</div>
<?php endif; ?>
<?php if ($qualityScore): ?>
<div class="metric">
<span class="metric-label">Quality Score</span>
<span class="metric-value"><?= $qualityScore ?>/100</span>
</div>
<?php endif; ?>
<?php if ($formattedFileSize): ?>
<div class="metric">
<span class="metric-label">File Size</span>
<span class="metric-value"><?= $formattedFileSize ?></span>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<!-- Processing Information -->
<?php if ($processingTime || $apiCost): ?>
<div class="processing-info">
<h4>⚙️ Processing Details</h4>
<div class="info-grid">
<?php if ($formattedProcessingTime): ?>
<div class="info-item">
<span class="info-label">Processing Time</span>
<span class="info-value"><?= $formattedProcessingTime ?></span>
</div>
<?php endif; ?>
<?php if ($formattedCost): ?>
<div class="info-item">
<span class="info-label">API Cost</span>
<span class="info-value"><?= $formattedCost ?></span>
</div>
<?php endif; ?>
<?php if ($creditsUsed): ?>
<div class="info-item">
<span class="info-label">Credits Used</span>
<span class="info-value"><?= $creditsUsed ?></span>
</div>
<?php endif; ?>
<?php if ($modelName): ?>
<div class="info-item">
<span class="info-label">Model</span>
<span class="info-value"><?= htmlspecialchars($modelName) ?></span>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<!-- Audio Analysis -->
<?php if ($loudness || $dynamicRange || $peakAmplitude): ?>
<div class="audio-analysis">
<h4>📊 Audio Analysis</h4>
<div class="analysis-grid">
<?php if ($loudness): ?>
<div class="analysis-item">
<span class="analysis-label">Loudness</span>
<span class="analysis-value"><?= $loudness ?> dB</span>
</div>
<?php endif; ?>
<?php if ($dynamicRange): ?>
<div class="analysis-item">
<span class="analysis-label">Dynamic Range</span>
<span class="analysis-value"><?= $dynamicRange ?> dB</span>
</div>
<?php endif; ?>
<?php if ($peakAmplitude): ?>
<div class="analysis-item">
<span class="analysis-label">Peak Amplitude</span>
<span class="analysis-value"><?= round($peakAmplitude * 100) ?>%</span>
</div>
<?php endif; ?>
<?php if ($spectralCentroid): ?>
<div class="analysis-item">
<span class="analysis-label">Spectral Centroid</span>
<span class="analysis-value"><?= round($spectralCentroid) ?> Hz</span>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<!-- Audio Segments -->
<?php if (!empty($segments)): ?>
<div class="audio-segments">
<h4>🎼 Song Structure</h4>
<?= $segmentTimeline ?>
</div>
<?php endif; ?>
<!-- Enhanced Waveform -->
<div class="enhanced-waveform" onclick="playTrackFromWaveform(<?= $track['id'] ?>, '<?= htmlspecialchars($track['audio_url'], ENT_QUOTES) ?>', '<?= htmlspecialchars($track['title'], ENT_QUOTES) ?>', '<?= htmlspecialchars($track['artist_name'], ENT_QUOTES) ?>')">
<?php foreach ($waveformBars as $barHeight): ?>
<div class="wave-bar" style="height: <?= $barHeight ?>%;"></div>
<?php endforeach; ?>
</div>
<!-- Bottom Stats & Actions -->
<div class="bottom-section">
<div class="track-stats">
<span><i class="fas fa-play"></i> <?= number_format($track['play_count']) ?></span>
<span><i class="fas fa-heart"></i> <?= number_format($track['like_count']) ?></span>
<span><?= floor($track['duration'] / 60) ?>:<?= str_pad($track['duration'] % 60, 2, '0', STR_PAD_LEFT) ?></span>
</div>
<div class="rating-section">
<div class="star-rating" data-track-id="<?= $track['id'] ?>">
<?php for ($i = 1; $i <= 5; $i++):
$is_filled = $i <= ($track['average_rating'] / 2);
?>
<span class="star <?= $is_filled ? 'filled' : '' ?>" onclick="rateTrack(<?= $track['id'] ?>, <?= $i * 2 ?>, this)">★</span>
<?php endfor; ?>
</div>
<span class="rating-text"><?= number_format($track['average_rating'], 1) ?></span>
</div>
<div class="social-actions">
<button class="social-btn like-btn <?= $track['user_liked'] ? 'liked' : '' ?>" onclick="toggleLike(<?= $track['id'] ?>, this)">
<i class="fas fa-heart"></i>
</button>
<button class="social-btn share-btn" onclick="shareTrack(<?= $track['id'] ?>)">
<i class="fas fa-share"></i>
</button>
<button class="social-btn comment-btn" onclick="showComments(<?= $track['id'] ?>)">
<i class="fas fa-comment"></i>
</button>
<button class="social-btn download-btn" onclick="downloadTrack(<?= $track['id'] ?>)">
<i class="fas fa-download"></i>
</button>
</div>
</div>
</div>
<?php
return ob_get_clean();
}
// Helper functions
function formatBytes($bytes, $precision = 2) {
$units = array('B', 'KB', 'MB', 'GB', 'TB');
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
$bytes /= 1024;
}
return round($bytes, $precision) . ' ' . $units[$i];
}
function formatTime($seconds) {
if ($seconds < 60) {
return round($seconds, 1) . 's';
} elseif ($seconds < 3600) {
$minutes = floor($seconds / 60);
$secs = $seconds % 60;
return $minutes . 'm ' . round($secs) . 's';
} else {
$hours = floor($seconds / 3600);
$minutes = floor(($seconds % 3600) / 60);
return $hours . 'h ' . $minutes . 'm';
}
}
?>
<style>
.enhanced-card {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 20px;
margin: 15px 0;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
transition: all 0.3s ease;
}
.enhanced-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
.enhanced-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 15px;
}
.artist-info {
display: flex;
align-items: center;
gap: 15px;
}
.artist-avatar img, .default-avatar {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
}
.default-avatar {
background: linear-gradient(135deg, #667eea, #764ba2);
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 1.2em;
}
.track-info {
flex: 1;
}
.track-title {
font-size: 1.2em;
font-weight: bold;
margin-bottom: 5px;
}
.artist-name {
font-size: 0.9em;
opacity: 0.8;
margin-bottom: 8px;
}
.track-meta {
display: flex;
gap: 8px;
}
.genre-badge, .model-badge {
background: rgba(255, 255, 255, 0.2);
padding: 4px 8px;
border-radius: 12px;
font-size: 0.8em;
font-weight: 500;
}
.enhanced-actions {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.action-btn {
background: linear-gradient(135deg, #48bb78, #38a169);
border: none;
color: white;
padding: 12px;
border-radius: 50%;
cursor: pointer;
transition: all 0.3s ease;
width: 45px;
height: 45px;
display: flex;
align-items: center;
justify-content: center;
}
.action-btn:hover {
transform: scale(1.1);
}
.price-display {
font-weight: bold;
font-size: 1.1em;
color: #48bb78;
}
.enhanced-dj-tech {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
margin: 15px 0;
}
.tech-item {
background: rgba(255, 255, 255, 0.1);
padding: 10px;
border-radius: 8px;
text-align: center;
}
.tech-label {
display: block;
font-size: 0.8em;
opacity: 0.7;
margin-bottom: 5px;
}
.tech-value {
display: block;
font-weight: bold;
font-size: 1.1em;
}
.audio-quality-metrics, .processing-info, .audio-analysis, .audio-segments {
background: rgba(255, 255, 255, 0.05);
padding: 15px;
border-radius: 10px;
margin: 15px 0;
}
.audio-quality-metrics h4, .processing-info h4, .audio-analysis h4, .audio-segments h4 {
margin: 0 0 10px 0;
font-size: 1em;
opacity: 0.9;
}
.metrics-grid, .info-grid, .analysis-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 10px;
}
.metric, .info-item, .analysis-item {
text-align: center;
}
.metric-label, .info-label, .analysis-label {
display: block;
font-size: 0.8em;
opacity: 0.7;
margin-bottom: 3px;
}
.metric-value, .info-value, .analysis-value {
display: block;
font-weight: bold;
font-size: 0.9em;
}
.segment-timeline {
display: flex;
gap: 5px;
flex-wrap: wrap;
}
.segment {
background: rgba(255, 255, 255, 0.2);
padding: 4px 8px;
border-radius: 12px;
font-size: 0.8em;
cursor: pointer;
transition: all 0.3s ease;
}
.segment:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.05);
}
.enhanced-waveform {
display: flex;
align-items: end;
gap: 2px;
height: 60px;
margin: 15px 0;
cursor: pointer;
padding: 10px;
background: rgba(255, 255, 255, 0.05);
border-radius: 8px;
}
.wave-bar {
background: linear-gradient(to top, #667eea, #764ba2);
border-radius: 2px;
min-width: 3px;
transition: all 0.3s ease;
}
.enhanced-waveform:hover .wave-bar {
background: linear-gradient(to top, #48bb78, #38a169);
}
.bottom-section {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.track-stats {
display: flex;
gap: 15px;
font-size: 0.9em;
opacity: 0.8;
}
.rating-section {
display: flex;
align-items: center;
gap: 8px;
}
.star-rating {
display: flex;
gap: 2px;
}
.star {
color: #ccc;
cursor: pointer;
transition: color 0.3s ease;
}
.star.filled {
color: #ffd700;
}
.star:hover {
color: #ffd700;
}
.rating-text {
font-weight: bold;
font-size: 0.9em;
}
.social-actions {
display: flex;
gap: 8px;
}
.social-btn {
background: rgba(255, 255, 255, 0.1);
border: none;
color: white;
padding: 8px;
border-radius: 50%;
cursor: pointer;
transition: all 0.3s ease;
width: 35px;
height: 35px;
display: flex;
align-items: center;
justify-content: center;
}
.social-btn:hover {
background: rgba(255, 255, 255, 0.2);
transform: scale(1.1);
}
.social-btn.liked {
background: #e53e3e;
color: white;
}
@media (max-width: 768px) {
.enhanced-header {
flex-direction: column;
gap: 15px;
}
.enhanced-dj-tech {
grid-template-columns: repeat(2, 1fr);
}
.metrics-grid, .info-grid, .analysis-grid {
grid-template-columns: repeat(2, 1fr);
}
.bottom-section {
flex-direction: column;
gap: 15px;
align-items: stretch;
}
.track-stats {
justify-content: center;
}
.social-actions {
justify-content: center;
}
}
</style>