T.ME/BIBIL_0DAY
CasperSecurity


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/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/private_html/create_vocal_removal.php
<?php
session_start();

// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
    header('Location: auth/login_new.php');
    exit;
}

// Check if form was submitted
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: index.php#create');
    exit;
}

require_once 'config/database.php';
require_once 'api_functions.php';
require_once 'includes/translations.php';

$pdo = getDBConnection();
$api = new APIBoxFunctions('63edba40620216c5aa2c04240ac41dbd');

// Get form data
$title = $_POST['title'] ?? 'Untitled Audio Separation';
$audioUrl = $_POST['audioUrl'] ?? '';
$audioFile = $_FILES['audioFile'] ?? null;
$selectedTrackId = $_POST['selectedTrackId'] ?? null;
$separationMode = $_POST['separationMode'] ?? 'separate_vocal'; // separate_vocal or split_stem
$separationType = $_POST['separationType'] ?? 'vocals'; // vocals, instrumental, both (for 2-stem mode)
$quality = $_POST['quality'] ?? 'high';
$format = $_POST['format'] ?? 'mp3';

// Handle track selection from library
if (!empty($selectedTrackId)) {
    // Verify user owns the track and get audio URL
    $stmt = $pdo->prepare("SELECT audio_url, title FROM music_tracks WHERE id = ? AND user_id = ? AND status = 'complete' AND audio_url IS NOT NULL AND audio_url != ''");
    $stmt->execute([$selectedTrackId, $_SESSION['user_id']]);
    $selectedTrack = $stmt->fetch();
    
    if ($selectedTrack && !empty($selectedTrack['audio_url'])) {
        // Use the stored audio_url directly - it's already the correct URL
        $audioUrl = $selectedTrack['audio_url'];
        
        // If it's a relative URL (signed URL), convert to full URL
        if (strpos($audioUrl, 'http') !== 0) {
            $audioUrl = 'https://soundstudiopro.com' . $audioUrl;
        }
        
        // Use the original track title as default if no title provided
        if (empty($title) || $title === 'Untitled Audio Separation') {
            $title = ($selectedTrack['title'] ?? 'Untitled') . ' - Stems';
        }
    } else {
        $_SESSION['error'] = 'Selected track not found or not available.';
        header('Location: index.php#create');
        exit;
    }
}

// Validate input
if (empty($audioUrl) && empty($audioFile['name'])) {
    $_SESSION['error'] = 'Please select a track from your library, upload a file, or provide an audio URL.';
    header('Location: index.php#create');
    exit;
}

// Calculate credit cost based on separation mode
$creditCost = ($separationMode === 'split_stem') ? 3 : 2; // Full stem separation costs 3 credits, 2-stem costs 2

// Check user credits
$stmt = $pdo->prepare("SELECT credits FROM users WHERE id = ?");
$stmt->execute([$_SESSION['user_id']]);
$user = $stmt->fetch();

if (!$user || $user['credits'] < $creditCost) {
    $modeText = ($separationMode === 'split_stem') ? 'separate stems' : 'separate audio';
    error_log("Insufficient credits for user {$_SESSION['user_id']}: has {$user['credits']}, needs $creditCost");
    $_SESSION['error'] = "Insufficient credits. You need $creditCost credits to $modeText. Please purchase credits to continue.";
    header('Location: index.php');
    exit;
}

// Handle file upload if provided
$finalAudioUrl = $audioUrl;
if (!empty($audioFile['name'])) {
    // SECURITY: Enhanced file upload validation
    require_once 'includes/security.php';
    $validation = validateFileUpload($audioFile, ['mp3', 'wav', 'm4a', 'ogg'], 50 * 1024 * 1024); // 50MB max for audio
    
    if (!$validation['valid']) {
        error_log("SECURITY: Invalid audio file upload attempt from user {$_SESSION['user_id']}: " . ($validation['error'] ?? 'unknown error'));
        $_SESSION['error'] = 'Invalid audio file. ' . ($validation['error'] ?? 'Please upload a valid audio file (MP3, WAV, M4A, or OGG).');
        header('Location: index.php#create');
        exit;
    }
    
    $uploadDir = 'uploads/';
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0755, true);
    }
    
    // Use sanitized filename from validation
    $fileName = time() . '_' . $_SESSION['user_id'] . '_' . $validation['filename'];
    $uploadPath = $uploadDir . $fileName;
    
    if (move_uploaded_file($audioFile['tmp_name'], $uploadPath)) {
        $finalAudioUrl = 'https://soundstudiopro.com/' . $uploadPath;
    } else {
        error_log("SECURITY: Failed to move uploaded audio file for user {$_SESSION['user_id']}");
        $_SESSION['error'] = 'Failed to upload audio file.';
        header('Location: index.php#create');
        exit;
    }
}

// Create track record
$musicType = ($separationMode === 'split_stem') ? 'stem-separation' : 'vocal-removal';
$temp_task_id = $musicType . '_' . time() . '_' . $_SESSION['user_id'] . '_' . uniqid();
$metadata = [
    'separationMode' => $separationMode,
    'separationType' => $separationType,
    'quality' => $quality,
    'format' => $format,
    'originalAudioUrl' => $finalAudioUrl,
    'sourceTrackId' => $selectedTrackId // Track if this came from library
];

$description = ($separationMode === 'split_stem') 
    ? 'Full stem separation (all instruments)' 
    : 'Audio separation (vocals/instrumental)';

$track_id = $api->createTrackRecord($_SESSION['user_id'], $temp_task_id, $title, $description, $musicType, $metadata);

// Call the audio separation API FIRST (before deducting credits)
$api_data = [
    'audioUrl' => $finalAudioUrl,
    'type' => $separationMode, // 'separate_vocal' or 'split_stem'
    'quality' => $quality,
    'format' => $format,
    'callBackUrl' => 'https://soundstudiopro.com/callback.php'
];

// Only add separationType for 2-stem mode
if ($separationMode === 'separate_vocal') {
    $api_data['separationType'] = $separationType;
}

// Log the API call
error_log("Stem Separation API Call - User: {$_SESSION['user_id']}, Mode: $separationMode, Audio URL: $finalAudioUrl");
error_log("API Data: " . json_encode($api_data));

$result = $api->separateVocals($api_data);

// Log the API response
error_log("Stem Separation API Response: " . json_encode($result));

// Check if API call was successful
if (isset($result['error'])) {
    error_log("Audio separation API error: " . json_encode($result));
    
    // Update track status to failed
    $stmt = $pdo->prepare("UPDATE music_tracks SET status = 'failed' WHERE id = ?");
    $stmt->execute([$track_id]);
    
    $_SESSION['error'] = 'Failed to start stem separation: ' . ($result['error'] ?? 'Unknown error. Please try again.');
    header('Location: index.php#create');
    exit;
}

// Extract task ID from response
$real_task_id = $result['taskId'] ?? $result['id'] ?? $result['data']['taskId'] ?? $result['data']['id'] ?? null;

if (empty($real_task_id)) {
    error_log("No task ID returned from API. Full response: " . json_encode($result));
    
    // Update track status to failed
    $stmt = $pdo->prepare("UPDATE music_tracks SET status = 'failed' WHERE id = ?");
    $stmt->execute([$track_id]);
    
    $_SESSION['error'] = 'API did not return a task ID. Please try again or contact support.';
    header('Location: index.php#create');
    exit;
}

// Update track with real task ID
$stmt = $pdo->prepare("UPDATE music_tracks SET task_id = ? WHERE id = ?");
$stmt->execute([$real_task_id, $track_id]);

error_log("Stem separation task created successfully. Task ID: $real_task_id, Track ID: $track_id");

// NOW deduct credits (only after API call succeeds)
$newCredits = $user['credits'] - $creditCost;
$stmt = $pdo->prepare("UPDATE users SET credits = ? WHERE id = ?");
$stmt->execute([$newCredits, $_SESSION['user_id']]);

// Record credit transaction
$transactionDesc = ($separationMode === 'split_stem') 
    ? "Full stem separation: $title" 
    : "Audio separation: $title";
$stmt = $pdo->prepare("
    INSERT INTO credit_transactions (user_id, amount, type, description, created_at) 
    VALUES (?, ?, 'usage', ?, NOW())
");
$stmt->execute([$_SESSION['user_id'], -$creditCost, $transactionDesc]);

$_SESSION['credits'] = $newCredits;

$successMsg = ($separationMode === 'split_stem') 
    ? 'Full stem separation started. This may take a few minutes...'
    : t('success.vocal_removal.started');
$_SESSION['success'] = $successMsg;

// Redirect back to the create page with success message
header('Location: index.php#create');
exit;
?> 

CasperSecurity Mini