403Webshell
Server IP : 127.0.0.1  /  Your IP : 216.73.216.48
Web Server : Apache/2.4.58 (Win64) OpenSSL/3.1.3 PHP/8.2.12
System : Windows NT DESKTOP-3H4FHQJ 10.0 build 19045 (Windows 10) AMD64
User : win 10 ( 0)
PHP Version : 8.2.12
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : OFF |  Perl : OFF |  Python : OFF |  Sudo : OFF |  Pkexec : OFF
Directory :  D:/xampp/htdocs-coblaa/pureFaith/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : D:/xampp/htdocs-coblaa/pureFaith/liveMe.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Live Stream Preview</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
        body {
            font-family: 'Inter', sans-serif;
            background-color: #0F172A; /* Slate 900 */
        }
        .stream-container {
            width: 100%;
            max-width: 900px;
            /* Tailwind classes will manage aspect ratio dynamically */
        }
        .aspect-16-9 {
            aspect-ratio: 16 / 9;
        }
        .aspect-4-3 {
            aspect-ratio: 4 / 3;
        }
        .aspect-1-1 {
            aspect-ratio: 1 / 1;
        }
        #video-feed {
            object-fit: cover; /* Use cover to ensure no black bars within the video feed itself */
            width: 100%;
            height: 100%;
            background-color: #1E293B; /* Slate 800 */
        }
    </style>
</head>
<body class="min-h-screen flex flex-col items-center p-4">

    <header class="text-center mb-8 w-full max-w-2xl">
        <h1 class="text-3xl font-bold text-white mb-2">Webcam Stream Preview</h1>
        <p class="text-indigo-400 text-sm">Access your camera feed instantly.</p>
    </header>

    <!-- Main Stream Container - Aspect Ratio Class is now controlled by JS -->
    <div id="stream-container" class="stream-container aspect-16-9 rounded-xl shadow-2xl overflow-hidden relative border-4 border-indigo-500 mb-8">
        <video id="video-feed" autoplay playsinline class="rounded-lg"></video>
        
        <!-- Overlay for Status Messages -->
        <div id="status-overlay" class="absolute inset-0 bg-gray-900 bg-opacity-90 flex items-center justify-center p-6 transition-opacity duration-300">
            <div class="text-center space-y-4">
                <svg id="status-icon" class="w-12 h-12 mx-auto text-indigo-400 animate-spin" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" class="opacity-25"></circle>
                    <path fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" class="opacity-75"></path>
                </svg>
                <p id="status-text" class="text-lg font-semibold text-white"></p>
                <div id="error-details" class="text-sm text-red-400 hidden p-2 bg-gray-700 rounded-lg"></div>
            </div>
        </div>
    </div>

    <!-- Controls -->
    <div class="w-full max-w-xl space-y-4">
        <!-- Stream Control Buttons (Start/Stop/Switch) -->
        <div class="flex flex-col md:flex-row space-y-3 md:space-y-0 md:space-x-4">
            <button id="start-btn" class="w-full md:w-1/3 bg-indigo-600 text-white p-3 rounded-lg font-semibold hover:bg-indigo-700 transition-colors duration-200 shadow-md">
                Start Live Stream
            </button>
            <button id="switch-camera-btn" class="w-full md:w-1/3 bg-gray-600 text-white p-3 rounded-lg font-semibold hover:bg-gray-700 transition-colors duration-200 shadow-md hidden" disabled>
                Switch Camera
            </button>
            <button id="stop-btn" class="w-full md:w-1/3 bg-red-600 text-white p-3 rounded-lg font-semibold hover:bg-red-700 transition-colors duration-200 shadow-md hidden" disabled>
                Stop Stream
            </button>
        </div>

        <!-- Recording Controls -->
        <div class="p-3 bg-gray-800 rounded-xl shadow-lg">
            <p class="text-sm font-semibold text-gray-300 mb-3 text-center">Recording Controls:</p>
            <div class="flex justify-center space-x-3">
                <button id="record-btn" class="p-2 w-1/2 rounded-lg bg-green-600 text-white text-sm font-medium hover:bg-green-700 transition-colors shadow-md disabled:opacity-50" disabled>
                    <span id="record-icon">
                        <svg class="w-5 h-5 inline-block mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" clip-rule="evenodd"></path></svg>
                    </span>
                    <span id="record-text">Start Recording</span>
                </button>
                <button id="stop-record-btn" class="p-2 w-1/2 rounded-lg bg-red-800 text-white text-sm font-medium hover:bg-red-900 transition-colors shadow-md hidden disabled:opacity-50" disabled>
                    <svg class="w-5 h-5 inline-block mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9 9a1 1 0 011-1h1a1 1 0 110 2h-1a1 1 0 01-1-1z" clip-rule="evenodd"></path></svg>
                    Stop & Download
                </button>
            </div>
        </div>

        <!-- Aspect Ratio Controls -->
        <div class="p-3 bg-gray-800 rounded-xl shadow-lg">
            <p class="text-sm font-semibold text-gray-300 mb-3 text-center">Aspect Ratio:</p>
            <div id="ratio-controls" class="flex justify-center space-x-3">
                <button data-ratio="16/9" data-class="aspect-16-9" class="ratio-btn p-2 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 transition-colors shadow-md">16:9</button>
                <button data-ratio="4/3" data-class="aspect-4-3" class="ratio-btn p-2 rounded-lg bg-gray-700 text-white text-sm font-medium hover:bg-indigo-500 transition-colors shadow-md">4:3</button>
                <button data-ratio="1/1" data-class="aspect-1-1" class="ratio-btn p-2 rounded-lg bg-gray-700 text-white text-sm font-medium hover:bg-indigo-500 transition-colors shadow-md">1:1</button>
            </div>
        </div>
    </div>
    
    <!-- Mandatory Security Note -->
    <div class="mt-8 p-4 bg-yellow-900 bg-opacity-30 border border-yellow-500 rounded-lg w-full max-w-xl text-yellow-300">
        <p class="font-bold mb-2">Important Note on Access Errors:</p>
        <p class="text-sm">For the webcam to work, this page <strong class="text-yellow-100">must be running on a secure connection (HTTPS)</strong> or on a local server (`localhost`). If you see an error, ensure your environment meets this security requirement.</p>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const videoFeed = document.getElementById('video-feed');
            const streamContainer = document.getElementById('stream-container');
            const startBtn = document.getElementById('start-btn');
            const stopBtn = document.getElementById('stop-btn');
            const switchCameraBtn = document.getElementById('switch-camera-btn');
            const ratioButtons = document.querySelectorAll('.ratio-btn');
            const statusOverlay = document.getElementById('status-overlay');
            const statusText = document.getElementById('status-text');
            const statusIcon = document.getElementById('status-icon');
            const errorDetails = document.getElementById('error-details');

            // Recording elements
            const recordBtn = document.getElementById('record-btn');
            const stopRecordBtn = document.getElementById('stop-record-btn');
            const recordIcon = document.getElementById('record-icon');
            const recordText = document.getElementById('record-text');

            let currentStream = null;
            let currentFacingMode = 'user'; 
            let currentAspectRatio = 16 / 9;
            let currentAspectRatioClass = 'aspect-16-9';

            // Recording state
            let mediaRecorder = null;
            let recordedChunks = [];
            // Use 'video/webm;codecs=vp8,opus' for wider browser support and audio
            const mimeType = 'video/webm;codecs=vp8,opus'; 

            // --- Utility Functions ---

            function updateStatus(message, isError = false, details = '') {
                statusOverlay.classList.remove('hidden');
                statusText.textContent = message;
                statusIcon.classList.toggle('hidden', isError);
                statusIcon.classList.toggle('animate-spin', !isError);
                statusText.classList.toggle('text-white', !isError);
                statusText.classList.toggle('text-red-400', isError);

                if (isError && details) {
                    errorDetails.textContent = details;
                    errorDetails.classList.remove('hidden');
                } else {
                    errorDetails.classList.add('hidden');
                }

                if (videoFeed.srcObject) {
                    videoFeed.srcObject = null;
                }
            }

            function hideStatus() {
                statusOverlay.classList.add('opacity-0');
                setTimeout(() => {
                    statusOverlay.classList.add('hidden');
                    statusOverlay.classList.remove('opacity-0');
                }, 300); 
            }
            
            function updateSwitchButtonText() {
                if (currentFacingMode === 'user') {
                    switchCameraBtn.textContent = 'Switch to Back Camera';
                } else {
                    switchCameraBtn.textContent = 'Switch to Front Camera';
                }
            }
            
            function updateRatioButtonStyles() {
                ratioButtons.forEach(btn => {
                    const btnRatio = btn.getAttribute('data-ratio');
                    const isActive = (eval(btnRatio) === currentAspectRatio);

                    if (isActive) {
                        btn.classList.add('bg-indigo-600', 'hover:bg-indigo-700');
                        btn.classList.remove('bg-gray-700', 'hover:bg-indigo-500');
                    } else {
                        btn.classList.add('bg-gray-700', 'hover:bg-indigo-500');
                        btn.classList.remove('bg-indigo-600', 'hover:bg-indigo-700');
                    }
                });
            }

            // --- Recording Logic ---

            function startRecording() {
                if (!currentStream) {
                    updateStatus('Error: Stream not active.', true, 'Start the camera stream first before recording.');
                    return;
                }
                
                // Reset chunks array
                recordedChunks = [];

                try {
                    if (!window.MediaRecorder || !MediaRecorder.isTypeSupported(mimeType)) {
                         updateStatus('Error: Recording is not supported.', true, `Your browser does not support the required video/webm MIME type.`);
                         return;
                    }
                    
                    // Initialize recorder
                    mediaRecorder = new MediaRecorder(currentStream, { mimeType: mimeType });

                    // Event to collect data chunks
                    mediaRecorder.ondataavailable = (event) => {
                        if (event.data.size > 0) {
                            recordedChunks.push(event.data);
                        }
                    };

                    // Event triggered when recording stops
                    mediaRecorder.onstop = () => {
                        // Create Blob from chunks and trigger download
                        const blob = new Blob(recordedChunks, { type: mimeType });
                        const url = URL.createObjectURL(blob);
                        
                        const a = document.createElement('a');
                        a.style.display = 'none';
                        a.href = url;
                        // Use a consistent, unique filename
                        a.download = `webcam-recording-${new Date().toISOString().replace(/[:.]/g, '-')}.webm`;
                        document.body.appendChild(a);
                        a.click();
                        document.body.removeChild(a);
                        
                        URL.revokeObjectURL(url);
                        
                        // Reset recording UI state
                        recordBtn.classList.remove('hidden');
                        recordBtn.disabled = false;
                        stopRecordBtn.classList.add('hidden');
                        stopRecordBtn.disabled = true;
                        
                        recordText.textContent = 'Start Recording';
                        recordIcon.innerHTML = `<svg class="w-5 h-5 inline-block mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" clip-rule="evenodd"></path></svg>`;

                        updateStatus('Recording downloaded successfully!', false, 'Click "Start Recording" again to record a new session.');
                        hideStatus(); 
                    };

                    mediaRecorder.start(100); // Start recording, collecting data every 100ms

                    // Update UI state
                    recordBtn.classList.add('hidden');
                    recordBtn.disabled = true;
                    stopRecordBtn.classList.remove('hidden');
                    stopRecordBtn.disabled = false;
                    
                    // Display recording indicator (pulse)
                    recordText.textContent = 'Recording...';
                    recordIcon.innerHTML = `<svg class="w-5 h-5 inline-block mr-1 text-red-500 animate-pulse" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM10 10a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path></svg>`;
                    
                    // Hide status overlay to see the stream
                    hideStatus();

                } catch (e) {
                    updateStatus('Recording failed.', true, `Error during MediaRecorder initialization: ${e.message}`);
                    console.error('MediaRecorder init error:', e);
                }
            }

            function stopRecording() {
                if (mediaRecorder && mediaRecorder.state === 'recording') {
                    mediaRecorder.stop();
                    stopRecordBtn.disabled = true; // Disable while processing download
                    updateStatus('Processing recording for download...');
                }
            }


            // --- Stream Control Logic ---

            async function startStream() {
                if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
                    updateStatus('Error: Media devices are not supported by your browser.', true, 'Try updating your browser or using Chrome/Firefox/Edge.');
                    return;
                }

                updateStatus(`Requesting ${currentFacingMode === 'user' ? 'Front' : 'Back'} Camera at ${currentAspectRatio.toFixed(2)} ratio...`);
                startBtn.disabled = true;
                switchCameraBtn.disabled = true; 
                recordBtn.disabled = true;

                if (currentStream) {
                    currentStream.getTracks().forEach(track => track.stop());
                    currentStream = null;
                }
                
                streamContainer.className = 'stream-container ' + currentAspectRatioClass + ' rounded-xl shadow-2xl overflow-hidden relative border-4 border-indigo-500 mb-8';

                try {
                    const stream = await navigator.mediaDevices.getUserMedia({ 
                        video: { 
                            facingMode: currentFacingMode, 
                            aspectRatio: currentAspectRatio,
                            width: { ideal: 1280 }, 
                            height: { ideal: 720 } 
                        }, 
                        // Request audio access as well for recording features
                        audio: true 
                    });

                    currentStream = stream;
                    videoFeed.srcObject = stream;
                    
                    await videoFeed.play(); 
                    
                    hideStatus();
                    startBtn.classList.add('hidden');
                    
                    // Show/Enable stream controls
                    stopBtn.classList.remove('hidden');
                    stopBtn.disabled = false;
                    switchCameraBtn.classList.remove('hidden');
                    switchCameraBtn.disabled = false;
                    updateSwitchButtonText(); 
                    
                    // Show/Enable record button
                    recordBtn.classList.remove('hidden');
                    recordBtn.disabled = false;
                    updateRatioButtonStyles();

                } catch (err) {
                    let errorMessage = 'An unknown error occurred while trying to access the camera.';
                    let errorHint = 'Ensure your device has a camera and try refreshing the page.';
                    
                    if (err.name === 'NotAllowedError' || err.name === 'PermissionDeniedError') {
                        errorMessage = 'Access Denied.';
                        errorHint = 'You must grant camera/microphone permission in your browser settings to continue.';
                    } else if (err.name === 'NotFoundError' || err.name === 'OverconstrainedError') {
                        errorMessage = 'No Camera Found or Ratio Not Supported.';
                        errorHint = `No suitable camera device found for facing mode: ${currentFacingMode} with ratio ${currentAspectRatio}. Try switching cameras or aspect ratios.`;
                    } else if (err.name === 'SecurityError') {
                        errorMessage = 'Security Error: HTTPS Required.';
                        errorHint = 'This feature only works on secure connections (HTTPS) or localhost.';
                    }
                    
                    updateStatus(errorMessage, true, errorHint);
                    console.error('getUserMedia Error:', err);

                    // Revert buttons to initial state on failure
                    startBtn.disabled = false;
                    startBtn.classList.remove('hidden');
                    stopBtn.classList.add('hidden');
                    switchCameraBtn.classList.add('hidden');
                    recordBtn.classList.add('hidden');
                    stopRecordBtn.classList.add('hidden');
                }
            }

            function stopStream() {
                // If recording is active, stop it first. This triggers the download.
                if (mediaRecorder && mediaRecorder.state === 'recording') {
                    mediaRecorder.stop();
                }

                if (currentStream) {
                    currentStream.getTracks().forEach(track => track.stop());
                    currentStream = null;
                    videoFeed.srcObject = null;
                    
                    // Update buttons and status
                    stopBtn.disabled = true;
                    stopBtn.classList.add('hidden');
                    switchCameraBtn.classList.add('hidden');
                    startBtn.classList.remove('hidden');
                    startBtn.disabled = false;
                    
                    // Hide and reset recording buttons
                    recordBtn.classList.add('hidden');
                    stopRecordBtn.classList.add('hidden');
                    recordBtn.disabled = true;
                    stopRecordBtn.disabled = true;

                    currentFacingMode = 'user'; 
                    updateSwitchButtonText();
                    
                    updateStatus('Stream stopped. Click "Start Live Stream" to restart.');
                }
            }
            
            function switchCamera() {
                currentFacingMode = (currentFacingMode === 'user' ? 'environment' : 'user');
                
                switchCameraBtn.disabled = true;
                stopBtn.disabled = true;
                recordBtn.disabled = true;
                stopRecordBtn.disabled = true;

                startStream();
            }

            function handleRatioSwitch(event) {
                const ratioStr = event.currentTarget.getAttribute('data-ratio');
                const ratioClass = event.currentTarget.getAttribute('data-class');
                
                currentAspectRatio = eval(ratioStr);
                currentAspectRatioClass = ratioClass;

                if (currentStream) {
                    // Stop recorder if active before restarting stream
                    if (mediaRecorder && mediaRecorder.state === 'recording') {
                        mediaRecorder.stop(); 
                    }
                    startStream();
                } else {
                    streamContainer.className = 'stream-container ' + currentAspectRatioClass + ' rounded-xl shadow-2xl overflow-hidden relative border-4 border-indigo-500 mb-8';
                    updateRatioButtonStyles();
                }
            }

            // --- Event Listeners ---
            startBtn.addEventListener('click', startStream);
            stopBtn.addEventListener('click', stopStream);
            switchCameraBtn.addEventListener('click', switchCamera);
            recordBtn.addEventListener('click', startRecording);
            stopRecordBtn.addEventListener('click', stopRecording);
            
            ratioButtons.forEach(button => {
                button.addEventListener('click', handleRatioSwitch);
            });

            // Initial setup
            updateStatus('Click "Start Live Stream" to begin.', false);
            statusIcon.classList.add('hidden');
            updateSwitchButtonText();
            updateRatioButtonStyles();
        });
    </script>
</body>
</html>

Youez - 2016 - github.com/yon3zu
LinuXploit