captura video con audio del sistema (como música o sonidos del navegador) pero sin usar el micrófono

 Aquí tienes una versión que captura video con audio del sistema (como música o sonidos del navegador) pero sin usar el micrófono:

Aquí tienes una versión que captura video con audio del sistema (como música o sonidos del navegador) pero sin usar el micrófono:

html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grabación de Video con Audio del Sistema</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 20px;
            background-color: #f5f5f5;
        }
        #videoElement {
            width: 100%;
            max-width: 640px;
            background-color: #333;
            margin: 20px 0;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }
        .controls {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
            flex-wrap: wrap;
            justify-content: center;
        }
        button {
            padding: 10px 20px;
            background-color: #4285F4;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: #3367D6;
        }
        button:disabled {
            background-color: #9E9E9E;
            cursor: not-allowed;
        }
        #errorMsg {
            color: #D32F2F;
            margin-top: 20px;
            text-align: center;
        }
        #recordingIndicator {
            display: none;
            width: 12px;
            height: 12px;
            background-color: red;
            border-radius: 50%;
            margin-left: 5px;
            animation: pulse 1.5s infinite;
        }
        @keyframes pulse {
            0% { opacity: 1; }
            50% { opacity: 0.3; }
            100% { opacity: 1; }
        }
        #timer {
            margin-left: 10px;
            font-weight: bold;
        }
        .audio-info {
            background-color: #e8f0fe;
            padding: 10px;
            border-radius: 5px;
            margin-bottom: 15px;
            text-align: center;
        }
    </style>
</head>
<body>
    <h1>Grabación de Video con Audio del Sistema</h1>
    
    <div class="audio-info">
        <p>Esta aplicación captura video de tu cámara y audio del sistema (como música o sonidos del navegador), pero no usa el micrófono.</p>
    </div>
    
    <video id="videoElement" autoplay playsinline></video>
    
    <div class="controls">
        <button id="startButton">Iniciar Cámara</button>
        <button id="stopButton" disabled>Detener Cámara</button>
        <button id="recordButton" disabled>
            Grabar
            <span id="recordingIndicator"></span>
            <span id="timer"></span>
        </button>
        <button id="downloadButton" disabled>Descargar</button>
    </div>
    
    <div id="errorMsg"></div>

    <script>
        // Elementos del DOM
        const videoElement = document.getElementById('videoElement');
        const startButton = document.getElementById('startButton');
        const stopButton = document.getElementById('stopButton');
        const recordButton = document.getElementById('recordButton');
        const downloadButton = document.getElementById('downloadButton');
        const recordingIndicator = document.getElementById('recordingIndicator');
        const timerElement = document.getElementById('timer');
        const errorMsg = document.getElementById('errorMsg');

        // Variables de estado
        let videoStream = null;
        let audioStream = null;
        let combinedStream = null;
        let mediaRecorder = null;
        let recordedChunks = [];
        let recordingStartTime = null;
        let timerInterval = null;

        // Iniciar cámara y captura de audio del sistema
        async function startCapture() {
            try {
                // 1. Obtener solo video de la cámara (sin audio del micrófono)
                videoStream = await navigator.mediaDevices.getUserMedia({
                    video: true,
                    audio: false
                });

                // 2. Intentar capturar audio del sistema (no micrófono)
                // Nota: Esto requiere que el usuario haya interactuado con la página primero
                try {
                    audioStream = await navigator.mediaDevices.getDisplayMedia({
                        video: false,
                        audio: true
                    });
                    
                    // 3. Combinar los streams
                    combinedStream = new MediaStream([
                        ...videoStream.getVideoTracks(),
                        ...audioStream.getAudioTracks()
                    ]);

                    // Mostrar video en el elemento
                    videoElement.srcObject = videoStream;

                    // Habilitar/deshabilitar botones
                    startButton.disabled = true;
                    stopButton.disabled = false;
                    recordButton.disabled = false;
                    downloadButton.disabled = true;
                    errorMsg.textContent = '';
                } catch (audioError) {
                    console.error("Error al capturar audio del sistema:", audioError);
                    // Continuar solo con video si no se puede obtener audio
                    combinedStream = videoStream;
                    videoElement.srcObject = videoStream;
                    startButton.disabled = true;
                    stopButton.disabled = false;
                    recordButton.disabled = false;
                    downloadButton.disabled = true;
                    errorMsg.textContent = "Se inició sin audio del sistema (solo video)";
                }
            } catch (err) {
                console.error("Error al acceder a la cámara:", err);
                errorMsg.textContent = `Error: ${err.message}`;
            }
        }

        // Detener captura
        function stopCapture() {
            // Detener grabación si está activa
            if (mediaRecorder && mediaRecorder.state === 'recording') {
                stopRecording();
            }

            // Detener todas las pistas
            if (videoStream) {
                videoStream.getTracks().forEach(track => track.stop());
            }
            if (audioStream) {
                audioStream.getTracks().forEach(track => track.stop());
            }
            
            videoElement.srcObject = null;

            // Resetear estado
            videoStream = null;
            audioStream = null;
            combinedStream = null;

            // Actualizar UI
            startButton.disabled = false;
            stopButton.disabled = true;
            recordButton.disabled = true;
            downloadButton.disabled = true;
            recordButton.textContent = "Grabar";
            recordingIndicator.style.display = "none";
            timerElement.textContent = "";
            errorMsg.textContent = "";
        }

        // Iniciar grabación
        function startRecording() {
            if (!combinedStream) return;
            
            recordedChunks = [];
            
            // Configurar MediaRecorder
            const options = { mimeType: 'video/webm;codecs=vp9' };
            mediaRecorder = new MediaRecorder(combinedStream, options);

            // Recoger datos de grabación
            mediaRecorder.ondataavailable = function(event) {
                if (event.data.size > 0) {
                    recordedChunks.push(event.data);
                }
            };

            // Iniciar grabación
            mediaRecorder.start(100); // Recoger datos cada 100ms

            // Actualizar UI
            recordButton.textContent = "Detener";
            recordingIndicator.style.display = "inline-block";
            downloadButton.disabled = true;
            
            // Iniciar temporizador
            recordingStartTime = new Date();
            updateTimer();
            timerInterval = setInterval(updateTimer, 1000);
        }

        // Detener grabación
        function stopRecording() {
            if (mediaRecorder && mediaRecorder.state !== 'inactive') {
                mediaRecorder.stop();
                
                // Detener temporizador
                clearInterval(timerInterval);
                
                // Actualizar UI
                recordButton.textContent = "Grabar";
                recordingIndicator.style.display = "none";
                downloadButton.disabled = false;
            }
        }

        // Actualizar temporizador
        function updateTimer() {
            const elapsed = Math.floor((new Date() - recordingStartTime) / 1000);
            const minutes = Math.floor(elapsed / 60).toString().padStart(2, '0');
            const seconds = (elapsed % 60).toString().padStart(2, '0');
            timerElement.textContent = `${minutes}:${seconds}`;
        }

        // Descargar video grabado
        function downloadVideo() {
            const blob = new Blob(recordedChunks, { type: 'video/webm' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.style.display = 'none';
            a.href = url;
            a.download = `grabacion-${new Date().toISOString().slice(0, 19).replace(/[:T]/g, '-')}.webm`;
            document.body.appendChild(a);
            a.click();
            setTimeout(() => {
                document.body.removeChild(a);
                URL.revokeObjectURL(url);
            }, 100);
        }

        // Event listeners
        startButton.addEventListener('click', startCapture);
        stopButton.addEventListener('click', stopCapture);
        recordButton.addEventListener('click', function() {
            if (recordButton.textContent === "Grabar") {
                startRecording();
            } else {
                stopRecording();
            }
        });
        downloadButton.addEventListener('click', downloadVideo);

        // Limpiar al salir
        window.addEventListener('beforeunload', stopCapture);
    </script>
</body>
</html>

Características clave:

  1. Captura de video sin micrófono:

    • Usa getUserMedia solo para video (audio: false)

    • No solicita permisos de micrófono

  2. Captura de audio del sistema:

    • Usa getDisplayMedia para capturar audio del sistema (música, sonidos del navegador)

    • El navegador mostrará un selector para compartir pestañas/ventanas con audio

  3. Combinación de streams:

    • Combina el stream de video de la cámara con el audio del sistema

    • Si no se puede obtener audio, graba solo video

  4. Interfaz clara:

    • Explica que no se usa el micrófono

    • Mantiene controles simples para iniciar/detener y grabar

  5. Limitaciones importantes:

    • El audio del sistema solo se puede capturar después de una interacción del usuario

    • Algunos navegadores pueden restringir esta funcionalidad

    • El usuario debe seleccionar manualmente qué ventana/pestaña compartir para el audio

Comentarios

Entradas más populares de este blog

b-Web Speech API

EL audio lo envia el navegador-Transcripción de Voz con Whisper