Drawaria Video Editor

Advanced video editor for Drawaria.online Audio, effects and loaded images

// ==UserScript==
// @name Drawaria Video Editor
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Advanced video editor for Drawaria.online Audio, effects and loaded images
// @author YouTubeDrawaria
// @match https://drawaria.online/*
// @grant none
// @license MIT
// @icon https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// ==/UserScript==

(function() {
    'use strict';

    // Función para crear e inyectar el editor de video
    function createVideoEditor() {
        // Crear contenedor principal del editor
        const editorContainer = document.createElement('div');
        editorContainer.id = 'drawaria-video-editor';
        editorContainer.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: 999999;
            background: #1a1a1a;
            display: none;
        `;

        // Inyectar el CSS
        const style = document.createElement('style');
        style.textContent = `
            /* Estilos generales del editor de video */
            #drawaria-video-editor {
                font-family: 'Arial', sans-serif;
                color: white;
                overflow: hidden;
            }

            #drawaria-video-editor * {
                box-sizing: border-box;
            }

            #drawaria-video-editor #main-container {
                display: flex;
                height: 100vh;
                width: 100vw;
                background: #222;
                color: white;
            }

            /* Panel izquierdo para controles */
            #drawaria-video-editor #left-panel {
                flex: 1;
                display: flex;
                flex-direction: column;
                background: #111;
                padding: 10px;
                overflow-y: auto;
                transition: transform 0.3s ease;
                border-right: 3px solid #444;
            }

            #drawaria-video-editor #controls {
                width: 100%;
                box-sizing: border-box;
            }

            #drawaria-video-editor .control-group {
                display: flex;
                flex-direction: column;
                align-items: center;
                gap: 10px;
                margin-bottom: 20px;
                background: #1c1c1c;
                padding: 10px;
                border-radius: 8px;
            }

            #drawaria-video-editor .control-row {
                display: flex;
                flex-wrap: wrap;
                gap: 10px;
                align-items: center;
                justify-content: center;
                width: 100%;
            }

            #drawaria-video-editor .url-container {
                display: flex;
                gap: 10px;
                align-items: center;
                width: 100%;
                max-width: 500px;
            }

            /* Panel derecho para el canvas */
            #drawaria-video-editor #right-panel {
                flex: 2;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                background: #222;
                position: relative;
                transition: transform 0.3s ease;
            }

            /* Estilos para el canvas */
            #drawaria-video-editor #canvas {
                display: block;
                max-width: 100%;
                max-height: 80vh;
                border: 1px solid #444;
                cursor: crosshair;
                background-color: black;
                border-radius: 4px;
                box-shadow: 0 0 15px rgba(0, 100, 255, 0.3);
            }

            /* Estilos de botones */
            #drawaria-video-editor .button {
                padding: 10px 20px;
                font-weight: bold;
                border: none;
                cursor: pointer;
                border-radius: 8px;
                transition: all 0.2s ease;
                font-size: 14px;
                min-width: 120px;
            }

            #drawaria-video-editor .button:hover {
                transform: translateY(-2px);
                box-shadow: 0 4px 8px rgba(0,0,0,0.3);
            }

            #drawaria-video-editor .start-btn { background: #0f0; color: #000; }
            #drawaria-video-editor .stop-btn { background: #ff0; color: #000; }
            #drawaria-video-editor .emergency-btn { background: #f44336; color: #fff; }
            #drawaria-video-editor .download-btn { background: #0ff; color: #000; }
            #drawaria-video-editor .single-image-btn { background: #666; color: #fff; }
            #drawaria-video-editor .multi-image-btn { background: #007bff; color: #fff; }
            #drawaria-video-editor .size-btn { background: #555; color: #fff; }
            #drawaria-video-editor .playback-btn { background: #337ab7; color: #fff; }
            #drawaria-video-editor .diagonal-btn { background: #2a5a8a; color: #fff; }
            #drawaria-video-editor .effect-btn { background: #d9534f; color: #fff; }
            #drawaria-video-editor .zoom-btn { background: #5cb85c; color: #fff; }
            #drawaria-video-editor .preview-btn { background: #f0ad4e; color: #000; }
            #drawaria-video-editor .file-nav-btn { background: #6c757d; color: #fff; }
            #drawaria-video-editor .audio-btn { background: #666; color: #fff; }
            #drawaria-video-editor .remove-effects-btn { background: #a52a2a; color: #fff; }
            #drawaria-video-editor .load-url-btn { background: #17a2b8; color: #fff; }
            #drawaria-video-editor .soundcloud-btn { background: #ff5500; color: #fff; }
            #drawaria-video-editor .screen-rec-btn { background: #9c27b0; color: #fff; }
            #drawaria-video-editor .close-editor-btn { background: #dc3545; color: #fff; }

            #drawaria-video-editor .widget-btn {
                background: #ff5500;
                color: #fff;
                font-size: 12px;
                padding: 5px 10px;
                min-width: auto;
                width: 35px;
                height: 35px;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            /* Animaciones */
            @keyframes pulse {
                0% { transform: scale(1); }
                50% { transform: scale(1.05); }
                100% { transform: scale(1); }
            }

            #drawaria-video-editor .recording-btn {
                animation: pulse 1.5s infinite;
                background: #f44336 !important;
            }

            /* Controles de grabación de pantalla */
            #drawaria-video-editor #screen-recording-controls {
                position: fixed;
                bottom: 20px;
                left: 20px;
                z-index: 10001;
                background: rgba(0,0,0,0.7);
                padding: 10px;
                border-radius: 8px;
                box-shadow: 0 0 15px rgba(0, 100, 255, 0.5);
                backdrop-filter: blur(5px);
                border: 1px solid #333;
            }

            #drawaria-video-editor #recording-timer {
                color: #00ffff;
                font-weight: bold;
                font-size: 18px;
                margin-top: 5px;
                text-align: center;
            }

            /* Toast notifications */
            #drawaria-video-editor #toast-container {
                position: fixed;
                top: 20px;
                right: 20px;
                z-index: 10001;
                display: flex;
                flex-direction: column;
                gap: 10px;
                width: 300px;
            }

            #drawaria-video-editor .toast {
                background: rgba(30, 30, 30, 0.9);
                color: white;
                padding: 15px;
                border-radius: 8px;
                border-left: 4px solid #007bff;
                box-shadow: 0 5px 15px rgba(0,0,0,0.3);
                transition: transform 0.3s ease, opacity 0.3s ease;
            }

            #drawaria-video-editor .toast.success { border-left-color: #28a745; }
            #drawaria-video-editor .toast.error { border-left-color: #dc3545; }
            #drawaria-video-editor .toast.warning { border-left-color: #ffc107; }
            #drawaria-video-editor .toast.info { border-left-color: #17a2b8; }

            #drawaria-video-editor .soundcloud-badge {
                background: linear-gradient(135deg, #f55125, #ff8800);
                padding: 4px 10px;
                border-radius: 12px;
                font-weight: bold;
                font-size: 12px;
                display: inline-block;
                margin: 5px 0;
            }

            #drawaria-video-editor .newgrounds-badge {
                background: linear-gradient(135deg, #00b4ff, #004799);
                padding: 4px 10px;
                border-radius: 12px;
                font-weight: bold;
                font-size: 12px;
                display: inline-block;
                margin: 5px 0;
            }

            #drawaria-video-editor input[type="text"],
            #drawaria-video-editor input[type="range"] {
                background: #2a2a2a;
                border: 1px solid #444;
                border-radius: 4px;
                color: white;
                padding: 8px;
            }

            #drawaria-video-editor input[type="range"] {
                padding: 0;
                height: 30px;
            }

            /* Widget de SoundCloud */
            #drawaria-video-editor #soundcloud-widget-container {
                position: fixed;
                bottom: 10px;
                left: 10px;
                background: rgba(0,0,0,0.8);
                padding: 10px;
                border-radius: 8px;
                border: 1px solid #333;
                z-index: 10000;
                transition: opacity 0.3s ease;
                backdrop-filter: blur(3px);
            }

            #drawaria-video-editor #soundcloud-widget-container.hidden {
                display: none;
            }

            #drawaria-video-editor #soundcloud-widget {
                width: 300px;
                height: 166px;
                border: none;
                border-radius: 4px;
            }

            #drawaria-video-editor .widget-controls {
                display: flex;
                gap: 10px;
                margin-top: 5px;
                align-items: center;
            }

            #drawaria-video-editor .widget-info {
                color: #fff;
                font-size: 12px;
                margin-top: 5px;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
                max-width: 280px;
            }

            /* Responsive */
            @media (max-width: 768px) {
                #drawaria-video-editor #main-container {
                    flex-direction: column;
                    height: auto;
                }

                #drawaria-video-editor #left-panel,
                #drawaria-video-editor #right-panel {
                    width: 100%;
                    flex: none;
                }

                #drawaria-video-editor #canvas {
                    margin: 20px auto;
                    max-width: 90%;
                    max-height: 50vh;
                }
            }


            .hidden { display: none !important; }
        `;
        document.head.appendChild(style);

        // HTML del editor
        editorContainer.innerHTML = `
            <div id="toast-container"></div>

            <div id="main-container">
                <div id="left-panel">
                    <div id="controls">
                        <div class="control-group">
                            <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
                                <p style="font-size: 19px; margin: 0; font-weight: bold;">Drawaria.online Video Editor</p>
                                <button class="button close-editor-btn" onclick="window.drawariaVideoEditor.close()">✖ Cerrar</button>
                            </div>
                            <p style="font-size: 14px; margin: 0; color: #aaa;">Imagen URL:</p>
                            <div class="url-container">
                                <input type="text" id="imageUrl" placeholder="https://i.ibb.co/QFnyrtyD/drawaria-video-editor.png"
                                       value="https://i.ibb.co/WWhBWyMG/editor-video-drawaria.png" style="flex: 1;">
                                <button class="button load-url-btn" onclick="window.drawariaVideoEditor.loadImageFromUrl()">🔗 Cargar URL</button>
                            </div>
                        </div>

                        <div class="control-group">
                            <p style="font-size: 14px; margin: 0; color: #aaa;">🎶 Cargar Audio:</p>
                            <div class="url-container">
                                <input type="text" id="audioUrl"
                                       placeholder="SoundCloud, Newgrounds o URL directa de audio..."
                                       value="https://audio.ngfiles.com/581000/581799_Remix--Super-Mario-Bros.mp3?f1405275853"
                                       style="flex: 1;">
                                <button class="button soundcloud-btn" onclick="window.drawariaVideoEditor.loadAudioFromUrl()">🎵 Cargar Audio</button>
                            </div>
                            <div class="control-row">
                                <button class="button load-url-btn" onclick="window.drawariaVideoEditor.testAudioUrl()">🔍 Comprobar URL</button>
                                <button class="button load-url-btn" onclick="window.drawariaVideoEditor.testAudioCapture()">🔊 Probar Captura</button>
                            </div>
                            <div style="display: flex; align-items: center; gap: 8px; margin-top: 5px;">
                                <span class="soundcloud-badge">SoundCloud</span>
                                <span class="newgrounds-badge">Newgrounds</span>
                            </div>
                        </div>

                        <div class="control-group">
                            <p style="font-size: 14px; margin: 0; color: #aaa;">Ajustar Tamaño:</p>
                            <div class="control-row">
                                <button class="button size-btn" onclick="window.drawariaVideoEditor.setCanvasSize('small')">Pequeño</button>
                                <button class="button size-btn" onclick="window.drawariaVideoEditor.setCanvasSize('medium')">Mediano</button>
                                <button class="button size-btn" onclick="window.drawariaVideoEditor.setCanvasSize('large')">Grande</button>
                                <button class="button size-btn" onclick="window.drawariaVideoEditor.setCanvasSize('drawaria')">Drawaria</button>
                            </div>
                        </div>

                        <div class="control-group">
                            <div class="control-row">
                                <label for="speedSlider">Velocidad: <span id="speedValue">2.0x</span></label>
                                <input type="range" id="speedSlider" min="0.1" max="10" step="0.1" value="2"
                                       oninput="window.drawariaVideoEditor.updateSpeed()" style="flex: 1; margin: 0 10px;">
                            </div>
                            <div class="control-row">
                                <button class="button zoom-btn" onclick="window.drawariaVideoEditor.zoomImage(0.1)">🔍 Zoom In</button>
                                <button class="button zoom-btn" onclick="window.drawariaVideoEditor.zoomImage(-0.1)">🔎 Zoom Out</button>
                            </div>
                        </div>

                        <div class="control-group">
                            <p style="font-size: 14px; margin: 0; color: #aaa;">Dirección de Scroll:</p>
                            <div class="control-row">
                                <button class="button playback-btn" onclick="window.drawariaVideoEditor.setScrollMode('right')">Derecha</button>
                                <button class="button playback-btn" onclick="window.drawariaVideoEditor.setScrollMode('left')">Izquierda</button>
                                <button class="button playback-btn" onclick="window.drawariaVideoEditor.setScrollMode('up')">Arriba</button>
                                <button class="button playback-btn" onclick="window.drawariaVideoEditor.setScrollMode('down')">Abajo</button>
                                <button class="button playback-btn" onclick="window.drawariaVideoEditor.setScrollMode('static')">Estático</button>
                            </div>
                        </div>

                        <div class="control-group">
                            <button class="button preview-btn" id="previewBtn" onclick="window.drawariaVideoEditor.togglePreviewMode()">🖼️ Previsualizar</button>
                            <button class="button start-btn" id="startBtn" onclick="window.drawariaVideoEditor.startAnimation()">▷ Iniciar Grabación</button>
                            <button class="button screen-rec-btn" onclick="window.drawariaVideoEditor.startScreenRecording()">🎥 Compartir Pantalla</button>
                        </div>



                        <div class="control-group">
                            <button class="button playback-btn" id="pauseBtn" onclick="window.drawariaVideoEditor.togglePause()">⏸ Pausar/Reanudar</button>
                            <button class="button stop-btn" id="stopBtn" style="display:none;" onclick="window.drawariaVideoEditor.stopRecording()">⏹ Parar y Descargar</button>
                            <button class="button emergency-btn" id="emergencyBtn" style="display:none;" onclick="window.drawariaVideoEditor.emergencyStop()">🛑 PARAR AHORA</button>
                        </div>

                        <div class="control-group">
                            <p style="font-size: 14px; margin: 0; color: #aaa;">Efectos Visuales:</p>
                            <div class="control-row">
                                <button class="button effect-btn" onclick="window.drawariaVideoEditor.toggleEffect('snow')">❄️ Nieve</button>
                                <button class="button effect-btn" onclick="window.drawariaVideoEditor.toggleEffect('sparkles')">✨ Destellos</button>
                                <button class="button effect-btn" onclick="window.drawariaVideoEditor.toggleEffect('fire')">🔥 Fuego</button>
                            </div>
                            <div class="control-row">
                                <button class="button remove-effects-btn" onclick="window.drawariaVideoEditor.removeAllEffects()">❌ Remover Efectos</button>
                            </div>
                        </div>

                        <div id="status" style="margin-top: 10px; font-size: 14px; color: #888; text-align: center; min-height: 20px;"></div>
                    </div>
                </div>

                <div id="right-panel">
                    <div style="position: relative; width: 100%;">
                        <canvas id="canvas"></canvas>
                        <button class="button download-btn" id="downloadBtn" style="display:none; width: 90%; margin-top: 15px;"
                                onclick="window.drawariaVideoEditor.downloadVideo()">
                            ↓ Descargar como WebM ↓
                        </button>
                        <div style="position: absolute; top: 5px; right: 5px; color: #aaa; font-size: 12px; background: rgba(0,0,0,0.5); padding: 3px 10px; border-radius: 5px;">
                            Resolución: <span id="resolutionDisplay">862x718</span>
                        </div>
                    </div>
                </div>
            </div>

            <div id="screen-recording-controls" style="display:none;">
                <button class="button recording-btn" id="screenStopBtn" onclick="window.drawariaVideoEditor.stopScreenRecording()">
                    ■ Detener Grabación
                </button>
                <div id="recording-timer">00:00</div>
            </div>

            <div id="soundcloud-widget-container" class="hidden">
                <iframe id="soundcloud-widget"
                    scrolling="no"
                    frameborder="no"
                    allow="autoplay; encrypted-media; fullscreen"
                    sandbox="allow-scripts allow-presentation">
                </iframe>
                <div class="widget-controls">
                    <button class="button widget-btn" onclick="window.drawariaVideoEditor.soundCloudManager.play()">▶</button>
                    <button class="button widget-btn" onclick="window.drawariaVideoEditor.soundCloudManager.pause()">⏸</button>
                    <button class="button widget-btn" onclick="window.drawariaVideoEditor.toggleWidgetVisibility()">✖</button>
                </div>
                <div class="widget-info" id="widget-info">Widget SoundCloud</div>
            </div>

            <audio id="backgroundMusic" loop crossOrigin="anonymous"></audio>

                        <div class="control-group">
                            <button class="button multi-image-btn" onclick="document.getElementById('multiFileInput').click()">🖼️ Múltiples Imágenes</button>
                            <input type="file" id="multiFileInput" accept="image/*" multiple style="display: none;">
                            <button class="button single-image-btn" onclick="document.getElementById('singleFileInput').click()">Importar imagen</button>
                            <input type="file" id="singleFileInput" accept="image/*" style="display: none;">
                            <button class="button audio-btn" onclick="document.getElementById('audioInput').click()">Archivo Local</button>
                            <input type="file" id="audioInput" accept="audio/*" style="display: none;">
                        </div>
        `;

        document.body.appendChild(editorContainer);
        return editorContainer;
    }

    // ==========================================
    //  MANAGER DE SOUNDCLOUD WIDGET API (MEJORADO)
    // ==========================================
    class SoundCloudWidgetManager {
        constructor() {
            this.widget = null;
            this.isLoaded = false;
            this.currentTrack = null;
            this.isPlaying = false;
            this.hasUserInteracted = false;
            this.detectUserInteraction();
        }

        isSoundCloudUrl(url) {
            const soundcloudPatterns = [
                /^https?:\/\/(www\.)?soundcloud\.com\//,
                /^https?:\/\/on\.soundcloud\.com\//
            ];
            return soundcloudPatterns.some(pattern => pattern.test(url));
        }

        async loadSoundCloudTrack(soundcloudUrl) {
            try {
                window.drawariaVideoEditor.updateStatus('🎵 Cargando SoundCloud (API oficial)...');

                const iframe = window.drawariaVideoEditor.container.querySelector('#soundcloud-widget');
                const widgetUrl = `https://w.soundcloud.com/player/?url=${encodeURIComponent(soundcloudUrl)}&auto_play=false&hide_related=true&show_comments=false&show_user=true&visual=true`;

                iframe.setAttribute('allow', 'autoplay; encrypted-media; fullscreen');
                iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-presentation');
                iframe.src = widgetUrl;

                window.drawariaVideoEditor.container.querySelector('#soundcloud-widget-container').classList.remove('hidden');

                return new Promise((resolve, reject) => {
                    const timeout = setTimeout(() => {
                        reject(new Error('Timeout cargando SoundCloud'));
                    }, 15000);

                    iframe.onload = () => {
                        clearTimeout(timeout);
                        resolve({ title: 'SoundCloud Track', user: { username: 'Usuario' }});

                        window.drawariaVideoEditor.container.querySelector('#widget-info').textContent = 'SoundCloud Track cargado';
                        window.drawariaVideoEditor.updateStatus('✅ SoundCloud cargado', 'success');
                        this.isLoaded = true;
                    };
                });

            } catch (error) {
                console.error('Error con SoundCloud:', error);
                throw new Error(`SoundCloud: ${error.message}`);
            }
        }

        play() {
            if (!this.hasUserInteracted) {
                window.drawariaVideoEditor.updateStatus('👆 Haz clic en cualquier botón primero', 'warning');
                return;
            }

            if (this.widget && this.isLoaded) {
                this.widget.play();
                this.isPlaying = true;
                window.drawariaVideoEditor.updateStatus('▶️ Reproduciendo SoundCloud', 'info');
            }
        }

        pause() {
            if (this.widget && this.isLoaded) {
                this.widget.pause();
                this.isPlaying = false;
                window.drawariaVideoEditor.updateStatus('⏸ SoundCloud pausado', 'info');
            }
        }

        detectUserInteraction() {
            const detectInteraction = () => {
                this.hasUserInteracted = true;
                document.removeEventListener('click', detectInteraction);
                document.removeEventListener('keydown', detectInteraction);
            };

            document.addEventListener('click', detectInteraction);
            document.addEventListener('keydown', detectInteraction);
        }
    }

    // ==========================================
    //  SISTEMA DE MÚLTIPLES ARCHIVOS DE AUDIO
    // ==========================================
    class MultiAudioManager {
        constructor() {
            this.audioContext = null;
            this.audioSources = new Map();
            this.masterGain = null;
            this.outputDestination = null;
        }

        async init() {
            try {
                this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
                this.masterGain = this.audioContext.createGain();
                this.outputDestination = this.audioContext.createMediaStreamDestination();

                this.masterGain.connect(this.outputDestination);

                window.drawariaVideoEditor.updateStatus('🎵 Sistema de múltiple audio inicializado', 'success');
                return true;
            } catch (error) {
                console.error('Error inicializando Web Audio API:', error);
                window.drawariaVideoEditor.updateStatus('❌ Error inicializando sistema de audio', 'error');
                return false;
            }
        }

        async loadAudioFile(file, id = null) {
            if (!this.audioContext) {
                await this.init();
            }

            const audioId = id || `audio_${Date.now()}`;

            try {
                const arrayBuffer = await file.arrayBuffer();
                const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer);

                const source = this.audioContext.createBufferSource();
                const gainNode = this.audioContext.createGain();

                source.buffer = audioBuffer;
                source.loop = true;

                source.connect(gainNode);
                gainNode.connect(this.masterGain);

                this.audioSources.set(audioId, {
                    source: source,
                    gain: gainNode,
                    buffer: audioBuffer,
                    isPlaying: false,
                    file: file
                });

                window.drawariaVideoEditor.updateStatus(`✅ Audio ${file.name} cargado (ID: ${audioId})`, 'success');
                return audioId;

            } catch (error) {
                console.error('Error cargando audio:', error);
                window.drawariaVideoEditor.updateStatus(`❌ Error cargando ${file.name}`, 'error');
                throw error;
            }
        }

        getAudioStream() {
            return this.outputDestination ? this.outputDestination.stream : null;
        }

        listLoadedAudio() {
            const list = [];
            this.audioSources.forEach((audio, id) => {
                list.push({
                    id: id,
                    name: audio.file.name,
                    isPlaying: audio.isPlaying,
                    volume: audio.gain.gain.value
                });
            });
            return list;
        }
    }

    // Clase principal del editor
    class DrawariaVideoEditor {
        constructor(container) {
            this.container = container;
            this.initializeVariables();
            this.setupEventListeners();
            this.initializeCanvas();
            this.showNotification('Editor de Video cargado - ¡Listo para usar!', 'success');
        }

        initializeVariables() {
            // Variables globales del editor
            this.mediaRecorder = null;
            this.recordedChunks = [];
            this.videoBlob = null;
            this.isRecording = false;
            this.animationRunning = false;
            this.animationFrameId = null;
            this.scrollSpeed = 2;
            this.scrollMode = 'right';
            this.isPaused = false;
            this.zoomLevel = 1.0;
            this.isPreviewMode = false;
            this.imageLoaded = false;
            this.previewOffset = { x: 0, y: 0 };
            this.isDragging = false;
            this.dragStartX = 0;
            this.dragStartY = 0;
            this.scrollPos = { x: 0, y: 0, directionX: 1, directionY: 1 };
            this.activeEffects = new Set();
            this.snowFlakes = [];
            this.sparkles = [];
            this.fireParticles = [];
            this.isScreenRecording = false;
            this.recordingStartTime = null;
            this.recordingTimerInterval = null;

            this.sizePresets = {
                'small': { width: 640, height: 480 },
                'medium': { width: 960, height: 720 },
                'large': { width: 1280, height: 960 },
                'drawaria': { width: 862, height: 718 }
            };

            this.canvasSize = 'drawaria';
            this.img = new Image();
            this.img.crossOrigin = "anonymous";
            this.img.oncontextmenu = () => false;

            // Inicializar managers de audio
            this.soundCloudManager = new SoundCloudWidgetManager();
            this.multiAudioManager = new MultiAudioManager();
        }

        setupEventListeners() {
            // Configurar manejo de archivos
            const singleFileInput = this.container.querySelector('#singleFileInput');
            const multiFileInput = this.container.querySelector('#multiFileInput');
            const audioInput = this.container.querySelector('#audioInput');

            singleFileInput.addEventListener('change', (e) => {
                if (e.target.files && e.target.files.length > 0) {
                    this.handleSingleFile(e.target.files);
                }
                e.target.value = '';
            });

            multiFileInput.addEventListener('change', (e) => {
                if (e.target.files && e.target.files.length > 0) {
                    this.handleMultiFiles(Array.from(e.target.files));
                }
                e.target.value = '';
            });

            audioInput.addEventListener('change', (e) => {
                if (e.target.files && e.target.files.length > 0) {
                    this.handleAudioFile(e.target.files);
                }
                e.target.value = '';
            });

            // Configurar canvas para arrastrar
            const canvas = this.container.querySelector('#canvas');
            canvas.addEventListener('mousedown', (e) => this.startDrag(e));
            canvas.addEventListener('mousemove', (e) => this.drag(e));
            canvas.addEventListener('mouseup', (e) => this.stopDrag(e));

            // Atajos de teclado
            document.addEventListener('keydown', (e) => this.handleKeyDown(e));
        }

        initializeCanvas() {
            this.setCanvasSize('drawaria');
            this.updateSpeed();

            // Cargar imagen por defecto
            const defaultUrl = this.container.querySelector('#imageUrl').value;
            if (defaultUrl) {
                this.loadImageFromUrl();
            }
        }

        // ==========================================
        //  FUNCIONES DE AUDIO MEJORADAS (DESDE TU PÁGINA)
        // ==========================================

        checkBrowserCompatibility() {
            const issues = [];

            if (!window.MediaRecorder || !MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
                issues.push('MediaRecorder API no soportado');
            }

            if (!window.navigator.mediaDevices || !window.navigator.mediaDevices.getDisplayMedia) {
                issues.push('getDisplayMedia API no soportado');
            }

            if (issues.length > 0) {
                const message = `⚠️ Problemas de compatibilidad: ${issues.join(', ')}`;
                this.showNotification(message, 'warning');
                return false;
            }

            return true;
        }

        isNewgroundsUrl(url) {
            return url.includes('audio.ngfiles.com') || url.includes('newgrounds.com/audio');
        }

        async loadNewgroundsAudio(newgroundsUrl) {
            try {
                this.updateStatus('🎵 Cargando Newgrounds (audio.ngfiles.com)...', 'info');

                const proxyHosts = [
                    'https://corsproxy.io/?',
                    'https://thingproxy.freeboard.io/fetch/',
                    'https://api.codetabs.com/v1/proxy?quest='
                ];

                for (const proxy of proxyHosts) {
                    try {
                        const proxyUrl = `${proxy}${encodeURIComponent(newgroundsUrl)}`;
                        const response = await fetch(proxyUrl, { mode: 'cors' });

                        if (!response.ok) continue;

                        const blob = await response.blob();
                        if (blob.size === 0) continue;

                        const audioPlayer = this.container.querySelector('#backgroundMusic');
                        const audioUrl = URL.createObjectURL(blob);
                        audioPlayer.src = audioUrl;

                        return new Promise((resolve) => {
                            audioPlayer.addEventListener('canplaythrough', () => {
                                const fileName = newgroundsUrl.split('/').pop();
                                this.updateStatus(`✅ Audio Newgrounds cargado: ${fileName}`, 'success');
                                this.showNotification(`Audio Newgrounds cargado: ${fileName}`, 'success');
                                resolve();
                            }, { once: true });
                        });

                    } catch (error) {
                        console.warn(`Proxy ${proxy} falló:`, error);
                        continue;
                    }
                }

                throw new Error('No se pudo cargar el audio de Newgrounds');

            } catch (error) {
                console.error('Error con Newgrounds:', error);
                this.updateStatus(`❌ Error Newgrounds: ${error.message}`, 'error');
                throw error;
            }
        }

        async loadAudioFromUrl() {
            const audioUrl = this.container.querySelector('#audioUrl').value.trim();
            if (!audioUrl) {
                this.showNotification('❌ URL de audio requerida', 'error');
                return;
            }

            try {
                if (this.soundCloudManager.isSoundCloudUrl(audioUrl)) {
                    await this.soundCloudManager.loadSoundCloudTrack(audioUrl);
                    return;
                }

                if (this.isNewgroundsUrl(audioUrl)) {
                    await this.loadNewgroundsAudio(audioUrl);
                    return;
                }

                this.updateStatus('🎶 Cargando audio desde URL...', 'info');
                const audioPlayer = this.container.querySelector('#backgroundMusic');
                audioPlayer.crossOrigin = "anonymous";

                const testAudio = new Audio();
                testAudio.src = audioUrl;

                return new Promise((resolve, reject) => {
                    testAudio.onloadeddata = function() {
                        audioPlayer.src = audioUrl;
                        audioPlayer.load();

                        audioPlayer.addEventListener('canplaythrough', function() {
                            const fileName = audioUrl.split('/').pop().split('?') || 'Audio cargado';
                            window.drawariaVideoEditor.updateStatus(`✅ Audio cargado: ${fileName}`, 'success');
                            window.drawariaVideoEditor.showNotification(`Audio cargado: ${fileName}`, 'success');
                            resolve();
                        }, { once: true });
                    };

                    testAudio.onerror = function() {
                        reject(new Error('No se pudo cargar el audio'));
                    };

                    testAudio.load();
                });

            } catch (error) {
                console.error('Error cargando audio:', error);
                this.updateStatus(`❌ Error de audio: ${error.message}`, 'error');
                this.showNotification(`Error de audio: ${error.message}`, 'error');
            }
        }

        async testAudioUrl() {
            const audioUrl = this.container.querySelector('#audioUrl').value.trim();
            if (!audioUrl) {
                this.showNotification('❌ Ingresa una URL para probar', 'error');
                return;
            }

            this.updateStatus('🔍 Analizando URL de audio...', 'info');

            try {
                const testAudio = new Audio();
                testAudio.src = audioUrl;

                return new Promise((resolve) => {
                    testAudio.onloadeddata = () => {
                        if (this.soundCloudManager.isSoundCloudUrl(audioUrl)) {
                            this.updateStatus('✅ SoundCloud detectado - Compatible con API', 'success');
                        } else if (this.isNewgroundsUrl(audioUrl)) {
                            this.updateStatus('✅ Newgrounds detectado - Compatible', 'success');
                        } else if (audioUrl.match(/\.(mp3|wav|ogg|m4a|aac|flac)(\?.*)?$/i)) {
                            this.updateStatus('✅ Formato de audio directo detectado', 'success');
                        } else {
                            this.updateStatus('⚠️ Tipo de URL desconocido - Podría funcionar', 'warning');
                        }
                        resolve();
                    };

                    testAudio.onerror = () => {
                        this.updateStatus('❌ Error al probar la URL', 'error');
                    };

                    testAudio.load();
                });

            } catch (error) {
                this.updateStatus(`❌ Error probando URL: ${error.message}`, 'error');
            }
        }

        testAudioCapture() {
            const audioPlayer = this.container.querySelector('#backgroundMusic');

            if (!audioPlayer || !audioPlayer.src) {
                this.showNotification('❌ No hay audio cargado para probar', 'error');
                return;
            }

            try {
                const audioStream = audioPlayer.captureStream();

                if (audioStream.getAudioTracks().length > 0) {
                    this.showNotification('✅ Audio compatible con captura', 'success');
                    console.log('✅ Pistas de audio encontradas:', audioStream.getAudioTracks().length);

                    audioPlayer.play().then(() => {
                        console.log('✅ Audio reproduciéndose correctamente');
                        this.updateStatus('🎵 Audio funcionando - Listo para grabación', 'success');
                    }).catch(e => {
                        console.warn('⚠️ Error auto-play:', e);
                        this.updateStatus('⚠️ Audio cargado - Requiere interacción del usuario', 'warning');
                    });

                } else {
                    this.showNotification('⚠️ Audio cargado pero no tiene pistas capturables', 'warning');
                }

            } catch (error) {
                this.showNotification('❌ Error en captura de audio: ' + error.message, 'error');
                console.error('❌ Error probando captura:', error);
            }
        }

        async prepareAudioForRecording() {
            const audioPlayer = this.container.querySelector('#backgroundMusic');

            if (!audioPlayer || !audioPlayer.src) {
                console.log('ℹ️ No hay audio cargado');
                return false;
            }

            try {
                audioPlayer.load();
                audioPlayer.currentTime = 0;

                return new Promise((resolve) => {
                    const timeoutId = setTimeout(() => {
                        console.warn('⚠️ Timeout preparando audio');
                        resolve(false);
                    }, 3000);

                    audioPlayer.addEventListener('canplaythrough', () => {
                        clearTimeout(timeoutId);
                        console.log('✅ Audio listo para grabación');
                        resolve(true);
                    }, { once: true });

                    audioPlayer.addEventListener('error', (e) => {
                        clearTimeout(timeoutId);
                        console.error('❌ Error preparando audio:', e);
                        resolve(false);
                    }, { once: true });
                });

            } catch (error) {
                console.error('❌ Error en preparación de audio:', error);
                return false;
            }
        }

        // Métodos principales
        async startAnimation() {
            if (this.isRecording) {
                this.showNotification('🛑 Ya hay una grabación en curso', 'warning');
                return;
            }

            if (!this.imageLoaded) {
                this.showNotification('⚠️ Debes cargar una imagen primero', 'warning');
                return;
            }

            // Salir del modo preview
            if (this.isPreviewMode) {
                this.togglePreviewMode(false);
            }

            // Preparar audio ANTES de iniciar grabación
            await this.prepareAudioForRecording();

            const canvas = this.container.querySelector('#canvas');
            const currentSize = this.sizePresets[this.canvasSize];

            canvas.width = Math.min(currentSize.width, 1920);
            canvas.height = Math.min(currentSize.height, 1080);

            try {
                const stream = canvas.captureStream(30);

                // Intentar agregar audio
                let hasAudio = false;
                const audioPlayer = this.container.querySelector('#backgroundMusic');
                if (audioPlayer && audioPlayer.src) {
                    try {
                        const audioStream = audioPlayer.captureStream();
                        if (audioStream.getAudioTracks().length > 0) {
                            audioStream.getAudioTracks().forEach(track => {
                                stream.addTrack(track);
                            });

                            audioPlayer.currentTime = 0;
                            audioPlayer.play().catch(e => console.warn('Error auto-play:', e));
                            hasAudio = true;
                            console.log('✅ Audio tradicional agregado al stream');
                        }
                    } catch (e) {
                        console.warn('Error capturando audio tradicional:', e);
                    }
                }

                this.recordedChunks = [];

                const selectedMimeType = 'video/webm;codecs=vp9';
                this.mediaRecorder = new MediaRecorder(stream, {
                    mimeType: selectedMimeType,
                    videoBitsPerSecond: 2000000
                });

                this.mediaRecorder.ondataavailable = (event) => {
                    if (event.data && event.data.size > 0) {
                        this.recordedChunks.push(event.data);
                    }
                };

                this.mediaRecorder.onstop = () => {
                    if (this.recordedChunks.length === 0) {
                        this.showNotification('❌ No se grabaron datos', 'error');
                        this.restoreInterface();
                        return;
                    }

                    this.videoBlob = new Blob(this.recordedChunks, { type: selectedMimeType });
                    this.container.querySelector('#downloadBtn').style.display = 'inline-block';
                    this.showNotification('✅ Grabación completada', 'success');
                    this.updateStatus('✅ Grabación completada. Haz clic en descargar');
                    this.restoreInterface();
                };

                this.mediaRecorder.start(100);

                this.isRecording = true;
                this.animationRunning = true;

                this.container.querySelector('#stopBtn').style.display = 'inline-block';
                this.container.querySelector('#emergencyBtn').style.display = 'inline-block';
                this.container.querySelector('#downloadBtn').style.display = 'none';

                setTimeout(() => {
                    this.animate();
                }, 100);

                if (hasAudio) {
                    this.showNotification('🎵 Grabando video con audio', 'success');
                } else {
                    this.showNotification('ℹ️ Grabando solo video (sin audio)', 'info');
                }

                this.updateStatus('🔴 Grabando scroll de imagen...');

            } catch (error) {
                console.error('Error iniciando grabación:', error);
                this.showNotification(`❌ Error al iniciar: ${error.message}`, 'error');
                this.restoreInterface();
            }
        }

        animate() {
            if (!this.animationRunning) {
                cancelAnimationFrame(this.animationFrameId);
                return;
            }

            const canvas = this.container.querySelector('#canvas');
            const ctx = canvas.getContext('2d');
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            const viewWidth = canvas.width / this.zoomLevel;
            const viewHeight = canvas.height / this.zoomLevel;
            const maxScrollX = this.img.width - viewWidth;
            const maxScrollY = this.img.height - viewHeight;

            if (!this.isPaused) {
                switch (this.scrollMode) {
                    case 'right':
                        this.scrollPos.x = Math.min(this.scrollPos.x + this.scrollSpeed, maxScrollX);
                        break;
                    case 'left':
                        this.scrollPos.x = Math.max(this.scrollPos.x - this.scrollSpeed, 0);
                        break;
                    case 'up':
                        this.scrollPos.y = Math.max(this.scrollPos.y - this.scrollSpeed, 0);
                        break;
                    case 'down':
                        this.scrollPos.y = Math.min(this.scrollPos.y + this.scrollSpeed, maxScrollY);
                        break;
                    case 'static':
                        break;
                }
            }

            // Dibujar la imagen
            ctx.drawImage(this.img,
                this.scrollPos.x, this.scrollPos.y,
                viewWidth, viewHeight,
                0, 0,
                canvas.width, canvas.height
            );

            // Efectos visuales
            if (this.activeEffects.has('snow')) this.drawSnow(ctx, canvas);
            if (this.activeEffects.has('sparkles')) this.drawSparkles(ctx, canvas);
            if (this.activeEffects.has('fire')) this.drawFire(ctx, canvas);

            this.animationFrameId = requestAnimationFrame(() => this.animate());
        }

        stopRecording() {
            if (!this.isRecording) return;

            this.animationRunning = false;
            cancelAnimationFrame(this.animationFrameId);

            if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
                this.mediaRecorder.stop();
            }

            this.isRecording = false;
            this.updateStatus('⏸️ Grabación detenida. Preparando video...', 'info');
        }

        emergencyStop() {
            this.stopRecording();
            this.showNotification('🛑 Parada de emergencia activada', 'warning');
        }

        downloadVideo() {
            if (!this.videoBlob) {
                this.showNotification('❌ No hay video para descargar', 'error');
                return;
            }

            const url = URL.createObjectURL(this.videoBlob);
            const a = document.createElement('a');
            const timestamp = new Date().toISOString().slice(0, 16).replace(/:/g, '-');

            document.body.appendChild(a);
            a.style.display = 'none';
            a.href = url;
            a.download = `drawaria-video-${timestamp}.webm`;
            a.click();

            setTimeout(() => {
                document.body.removeChild(a);
                URL.revokeObjectURL(url);
            }, 1000);

            this.showNotification('✅ Video descargado con éxito', 'success');
            this.videoBlob = null;
            this.recordedChunks = [];
            this.container.querySelector('#downloadBtn').style.display = 'none';
        }

        restoreInterface() {
            this.container.querySelector('#stopBtn').style.display = 'none';
            this.container.querySelector('#emergencyBtn').style.display = 'none';

            const audioPlayer = this.container.querySelector('#backgroundMusic');
            if (audioPlayer && audioPlayer.src) {
                audioPlayer.pause();
                audioPlayer.currentTime = 0;
            }
        }

        // Métodos de control
        loadImageFromUrl() {
            const imageUrl = this.container.querySelector('#imageUrl').value.trim();

            if (!imageUrl) {
                this.showNotification('❌ URL de imagen requerida', 'error');
                return;
            }

            this.updateStatus('🔄 Cargando imagen desde URL...', 'info');

            this.img.onload = () => {
                this.imageLoaded = true;
                this.updateStatus('✅ Imagen cargada con éxito', 'success');
                this.togglePreviewMode(true);
                this.showNotification('Imagen cargada correctamente', 'success');
            };

            this.img.onerror = () => {
                this.updateStatus('❌ Error al cargar imagen', 'error');
                this.showNotification('Error al cargar imagen', 'error');
                this.imageLoaded = false;
            };

            this.img.src = imageUrl;
        }

        setCanvasSize(size) {
            const canvas = this.container.querySelector('#canvas');
            if (!this.sizePresets[size]) return;

            canvas.width = this.sizePresets[size].width;
            canvas.height = this.sizePresets[size].height;
            this.canvasSize = size;

            this.container.querySelector('#resolutionDisplay').textContent =
                `${this.sizePresets[size].width}x${this.sizePresets[size].height}`;

            this.updateStatus(`📏 Tamaño: ${size.toUpperCase()}`, 'info');
            this.showNotification(`Tamaño cambiado a ${size.toUpperCase()}`, 'info');
        }

        updateSpeed() {
            const slider = this.container.querySelector('#speedSlider');
            this.scrollSpeed = parseFloat(slider.value);
            this.container.querySelector('#speedValue').textContent = `${this.scrollSpeed.toFixed(1)}x`;
            this.updateStatus(`⚡ Velocidad: ${this.scrollSpeed.toFixed(1)}x`, 'info');
        }

        zoomImage(amount) {
            const canvas = this.container.querySelector('#canvas');
            this.zoomLevel = Math.max(0.1, Math.min(5.0, this.zoomLevel + amount));
            this.updateStatus(`🔍 Zoom: ${(this.zoomLevel * 100).toFixed(0)}%`, 'info');

            if (this.imageLoaded && this.isPreviewMode) {
                this.drawPreviewOverlay();
            }
        }

        setScrollMode(mode) {
            this.scrollMode = mode;
            this.updateStatus(`🎬 Dirección: ${mode.toUpperCase()}`, 'info');
        }

        togglePause() {
            this.isPaused = !this.isPaused;
            const button = this.container.querySelector('#pauseBtn');
            button.textContent = this.isPaused ? '▶ Reanudar' : '⏸ Pausar';
            this.updateStatus(this.isPaused ? '⏸ Animación pausada' : '▶ Animación reanudada', 'info');
        }

        togglePreviewMode(forceState) {
            this.isPreviewMode = (typeof forceState !== 'undefined') ? forceState : !this.isPreviewMode;
            const canvas = this.container.querySelector('#canvas');
            const previewBtn = this.container.querySelector('#previewBtn');

            if (!this.imageLoaded) {
                this.updateStatus('❌ Carga una imagen para usar previsualización', 'error');
                this.isPreviewMode = false;
                return;
            }

            if (this.isPreviewMode) {
                previewBtn.textContent = '🔄 Salir de Previ';
                canvas.style.cursor = 'move';
                this.drawPreviewOverlay();
                this.updateStatus('🔄 Modo Previsualización activado', 'info');
            } else {
                previewBtn.textContent = '🖼 Previsualizar';
                canvas.style.cursor = 'crosshair';
                const ctx = canvas.getContext('2d');
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                this.updateStatus('🎮 Editor listo para comenzar', 'success');
            }
        }

        drawPreviewOverlay() {
            if (!this.imageLoaded) return;

            const canvas = this.container.querySelector('#canvas');
            const ctx = canvas.getContext('2d');
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            const viewWidth = canvas.width / this.zoomLevel;
            const viewHeight = canvas.height / this.zoomLevel;

            ctx.drawImage(this.img,
                this.previewOffset.x, this.previewOffset.y,
                viewWidth, viewHeight,
                0, 0,
                canvas.width, canvas.height
            );

            ctx.strokeStyle = "#4da6ff";
            ctx.lineWidth = 2;
            ctx.strokeRect(0, 0, canvas.width, canvas.height);
        }

        // Efectos visuales
        toggleEffect(effect) {
            if (this.activeEffects.has(effect)) {
                this.activeEffects.delete(effect);
                this.updateStatus(`❌ Efecto '${effect}' desactivado`, 'info');

                if (effect === 'fire') this.fireParticles = [];
                else if (effect === 'sparkles') this.sparkles = [];
                else if (effect === 'snow') this.snowFlakes = [];
            } else {
                this.activeEffects.add(effect);
                this.updateStatus(`🎨 Efecto '${effect}' activado`, 'success');
            }
        }

        removeAllEffects() {
            this.activeEffects.clear();
            this.snowFlakes = [];
            this.sparkles = [];
            this.fireParticles = [];
            this.updateStatus('💥 Todos los efectos removidos', 'info');
        }

        drawSnow(ctx, canvas) {
            if (Math.random() < 0.3) {
                this.snowFlakes.push({
                    x: Math.random() * canvas.width,
                    y: -10,
                    size: 2 + Math.random() * 3,
                    speed: 0.5 + Math.random() * 2
                });
            }

            ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
            this.snowFlakes.forEach((flake, index) => {
                ctx.beginPath();
                ctx.arc(flake.x, flake.y, flake.size, 0, 2 * Math.PI);
                ctx.fill();

                flake.y += flake.speed;
                if (flake.y > canvas.height) this.snowFlakes.splice(index, 1);
            });
        }

        drawSparkles(ctx, canvas) {
            if (Math.random() < 0.5) {
                this.sparkles.push({
                    x: Math.random() * canvas.width,
                    y: Math.random() * canvas.height,
                    size: 1 + Math.random() * 2,
                    opacity: 1,
                    fadeSpeed: 0.02 + Math.random() * 0.03
                });
            }

            this.sparkles.forEach((sparkle, index) => {
                ctx.fillStyle = `rgba(255, 255, 255, ${sparkle.opacity})`;
                ctx.beginPath();
                ctx.arc(sparkle.x, sparkle.y, sparkle.size, 0, Math.PI * 2);
                ctx.fill();

                sparkle.opacity -= sparkle.fadeSpeed;
                if (sparkle.opacity <= 0) this.sparkles.splice(index, 1);
            });
        }

        drawFire(ctx, canvas) {
            if (Math.random() < 0.5) {
                const size = 5 + Math.random() * 10;
                this.fireParticles.push({
                    x: Math.random() * canvas.width,
                    y: canvas.height,
                    size: size,
                    vx: (Math.random() - 0.5) * 2,
                    vy: -1 - Math.random() * 3,
                    opacity: 1,
                    color: `hsl(50, 100%, ${70 + Math.random() * 30}%)`
                });
            }

            this.fireParticles.forEach((p, index) => {
                ctx.save();
                ctx.globalAlpha = p.opacity;
                ctx.fillStyle = p.color;
                ctx.beginPath();
                ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
                ctx.fill();
                ctx.restore();

                p.x += p.vx;
                p.y += p.vy;
                p.opacity -= 0.02;
                p.size *= 0.98;

                if (p.opacity <= 0 || p.size < 0.5) {
                    this.fireParticles.splice(index, 1);
                }
            });
        }

        // Manejo de archivos
        handleSingleFile(file) {
            if (!file || !file.type.startsWith('image/')) {
                this.showNotification('❌ Solo se permiten archivos de imagen', 'error');
                return;
            }

            const fileURL = URL.createObjectURL(file);
            this.container.querySelector('#imageUrl').value = fileURL;

            this.img.onload = () => {
                this.imageLoaded = true;
                this.updateStatus(`✅ ${file.name} cargado`, 'success');
                this.showNotification(`Imagen ${file.name} cargada`, 'success');
                this.togglePreviewMode(true);
            };

            this.img.src = fileURL;
        }

        handleMultiFiles(files) {
            const imageFiles = files.filter(file => file.type && file.type.startsWith('image/'));
            if (imageFiles.length === 0) {
                this.showNotification('❌ No se encontraron imágenes válidas', 'error');
                return;
            }

            this.updateStatus(`✅ ${imageFiles.length} imágenes cargadas`, 'success');
            this.showNotification(`${imageFiles.length} imágenes cargadas`, 'success');
        }

        handleAudioFile(file) {
            if (!file || !file.type || !file.type.startsWith('audio/')) {
                this.showNotification('❌ Solo se permiten archivos de audio válidos', 'error');
                return;
            }

            // Método tradicional
            const audioPlayer = this.container.querySelector('#backgroundMusic');
            const fileURL = URL.createObjectURL(file);
            audioPlayer.src = fileURL;

            audioPlayer.addEventListener('canplaythrough', () => {
                this.updateStatus(`✅ ${file.name} cargado`, 'success');
                this.showNotification(`Audio ${file.name} cargado`, 'success');
            }, { once: true });

            // Método múltiple (Web Audio API)
            this.multiAudioManager.loadAudioFile(file).then(audioId => {
                this.showNotification(`🎵 ${file.name} agregado al mixer multiaudio`, 'info');
            }).catch(error => {
                console.warn('Fallback al método tradicional:', error);
            });
        }

        // Controles de arrastre
        startDrag(e) {
            if (!this.isPreviewMode && this.scrollMode !== 'static') return;
            this.isDragging = true;
            this.dragStartX = e.offsetX;
            this.dragStartY = e.offsetY;
        }

        drag(e) {
            if (!this.isDragging || (!this.isPreviewMode && this.scrollMode !== 'static')) return;

            const canvas = this.container.querySelector('#canvas');
            const dx = (e.offsetX - this.dragStartX) / this.zoomLevel;
            const dy = (e.offsetY - this.dragStartY) / this.zoomLevel;

            if (this.isPreviewMode) {
                this.previewOffset.x -= dx;
                this.previewOffset.y -= dy;
                this.drawPreviewOverlay();
            }

            this.dragStartX = e.offsetX;
            this.dragStartY = e.offsetY;
        }

        stopDrag() {
            this.isDragging = false;
        }

        // Grabación de pantalla
        async startScreenRecording() {
            if (this.isRecording) {
                this.showNotification('🛑 Ya hay una grabación en curso', 'warning');
                return;
            }

            if (!this.checkBrowserCompatibility()) {
                this.showNotification('❌ Navegador no compatible', 'error');
                return;
            }

            try {
                const displayStream = await navigator.mediaDevices.getDisplayMedia({
                    video: { cursor: "always" },
                    audio: true
                });

                this.recordedChunks = [];
                this.mediaRecorder = new MediaRecorder(displayStream, {
                    mimeType: 'video/webm;codecs=vp9',
                    videoBitsPerSecond: 5000000
                });

                this.mediaRecorder.ondataavailable = e => {
                    if (e.data.size > 0) {
                        this.recordedChunks.push(e.data);
                    }
                };

                this.mediaRecorder.onstop = () => {
                    this.videoBlob = new Blob(this.recordedChunks, { type: 'video/webm' });
                    this.container.querySelector('#downloadBtn').style.display = 'inline-block';
                    this.container.querySelector('#screen-recording-controls').style.display = 'none';
                    this.isRecording = false;
                    this.isScreenRecording = false;
                    displayStream.getTracks().forEach(track => track.stop());
                    this.showNotification('✅ Grabación de pantalla completada', 'success');
                };

                this.mediaRecorder.start(100);
                this.isRecording = true;
                this.isScreenRecording = true;

                this.container.querySelector('#screen-recording-controls').style.display = 'block';
                this.recordingStartTime = Date.now();
                this.recordingTimerInterval = setInterval(() => this.updateRecordingTimer(), 1000);

                this.showNotification('🔴 Grabando pantalla...', 'info');

            } catch (error) {
                this.showNotification(`❌ Error en grabación: ${error.message}`, 'error');
            }
        }

        stopScreenRecording() {
            if (this.mediaRecorder && this.isScreenRecording) {
                this.mediaRecorder.stop();
                clearInterval(this.recordingTimerInterval);
                this.showNotification('⏹ Grabación detenida', 'info');
            }
        }

        updateRecordingTimer() {
            if (!this.isScreenRecording) return;

            const elapsed = Math.floor((Date.now() - this.recordingStartTime) / 1000);
            const minutes = Math.floor(elapsed / 60).toString().padStart(2, '0');
            const seconds = (elapsed % 60).toString().padStart(2, '0');

            this.container.querySelector('#recording-timer').textContent = `${minutes}:${seconds}`;
        }

        // Manejo de teclado
        handleKeyDown(e) {
            if (e.target.tagName === 'INPUT' || e.target.isContentEditable) return;

            switch (e.key.toLowerCase()) {
                case ' ':
                    e.preventDefault();
                    if (this.animationRunning) this.togglePause();
                    break;
                case 'r':
                    e.preventDefault();
                    if (!this.isRecording) this.startAnimation();
                    break;
                case 's':
                    e.preventDefault();
                    if (this.isRecording) this.stopRecording();
                    break;
                case 'p':
                    e.preventDefault();
                    this.togglePreviewMode();
                    break;
                case 'escape':
                    e.preventDefault();
                    if (this.isRecording) this.emergencyStop();
                    break;
            }
        }

        // Utilidades
        showNotification(message, type = 'info') {
            const container = this.container.querySelector('#toast-container');

            const toast = document.createElement('div');
            toast.className = `toast ${type}`;
            toast.textContent = message;

            container.appendChild(toast);

            setTimeout(() => {
                toast.style.transform = 'translateX(0)';
                toast.style.opacity = '1';
            }, 10);

            setTimeout(() => {
                toast.style.transform = 'translateX(100%)';
                toast.style.opacity = '0';

                setTimeout(() => {
                    if (toast.parentNode) {
                        toast.parentNode.removeChild(toast);
                    }
                }, 300);
            }, 5000);
        }

        updateStatus(message, type = 'info') {
            const statusElement = this.container.querySelector('#status');
            statusElement.textContent = message;

            let color = '#888';
            switch(type) {
                case 'success': color = '#4CAF50'; break;
                case 'error': color = '#F44336'; break;
                case 'warning': color = '#FFC107'; break;
                case 'info': color = '#2196F3'; break;
            }

            statusElement.style.color = color;
        }

        toggleWidgetVisibility() {
            const container = this.container.querySelector('#soundcloud-widget-container');
            container.classList.toggle('hidden');
        }

        // Método para cerrar el editor
        close() {
            if (this.isRecording) {
                this.emergencyStop();
            }

            this.container.style.display = 'none';
            this.showNotification('Editor cerrado', 'info');
        }

        // Método para mostrar el editor
        show() {
            this.container.style.display = 'block';
            this.showNotification('Editor de Video abierto', 'success');
        }
    }

    // Función para crear botón de acceso al editor
    function createEditorButton() {
        const button = document.createElement('button');
        button.innerHTML = '🎥 Video Editor';
        button.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 999998;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            padding: 12px 20px;
            border-radius: 25px;
            font-weight: bold;
            font-size: 14px;
            cursor: pointer;
            box-shadow: 0 4px 15px rgba(0,0,0,0.3);
            transition: all 0.3s ease;
            backdrop-filter: blur(10px);
        `;

        button.addEventListener('mouseenter', () => {
            button.style.transform = 'translateY(-2px) scale(1.05)';
            button.style.boxShadow = '0 6px 20px rgba(0,0,0,0.4)';
        });

        button.addEventListener('mouseleave', () => {
            button.style.transform = 'translateY(0) scale(1)';
            button.style.boxShadow = '0 4px 15px rgba(0,0,0,0.3)';
        });

        button.addEventListener('click', () => {
            if (window.drawariaVideoEditor) {
                window.drawariaVideoEditor.show();
            }
        });

        document.body.appendChild(button);
        return button;
    }

    // Inicialización
    function initializeEditor() {
        console.log('🎬 Inicializando Drawaria Video Editor...');

        try {
            // Crear el editor
            const editorContainer = createVideoEditor();
            const editor = new DrawariaVideoEditor(editorContainer);

            // Crear botón de acceso
            createEditorButton();

            // Hacer el editor accesible globalmente
            window.drawariaVideoEditor = editor;

            console.log('✅ Drawaria Video Editor inicializado correctamente');

            setTimeout(() => {
                console.log('🎉 Editor completamente funcional');
                console.log('📌 Usa el botón flotante en la esquina superior derecha');
                console.log('⌨️ Atajos: Espacio=Pausa, R=Grabar, S=Parar, P=Preview, ESC=Emergencia');
                console.log('🎵 Sistema de audio mejorado con SoundCloud y Newgrounds');
            }, 1000);

        } catch (error) {
            console.error('❌ Error inicializando editor:', error);

            const errorNotification = document.createElement('div');
            errorNotification.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                z-index: 999999;
                background: #f44336;
                color: white;
                padding: 15px 20px;
                border-radius: 8px;
                font-weight: bold;
                box-shadow: 0 4px 15px rgba(0,0,0,0.3);
            `;
            errorNotification.textContent = '❌ Error cargando Video Editor';
            document.body.appendChild(errorNotification);

            setTimeout(() => {
                if (errorNotification.parentNode) {
                    errorNotification.parentNode.removeChild(errorNotification);
                }
            }, 5000);
        }
    }

    // Función para verificar si estamos en drawaria.online
    function isDrawariaPage() {
        return window.location.hostname.includes('drawaria.online');
    }

    // Función para esperar a que la página cargue
    function waitForPageLoad() {
        return new Promise((resolve) => {
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', resolve);
            } else {
                resolve();
            }
        });
    }

    // Función principal de inicialización
    async function main() {
        try {
            if (!isDrawariaPage()) {
                console.log('🔄 Script cargado pero no está en drawaria.online');
                return;
            }

            await waitForPageLoad();

            setTimeout(() => {
                initializeEditor();
            }, 2000);

            console.log('✅ Script de Drawaria Video Editor cargado exitosamente');

        } catch (error) {
            console.error('❌ Error en inicialización principal:', error);
        }
    }

    // Función para limpiar recursos al cerrar la página
    function cleanup() {
        if (window.drawariaVideoEditor) {
            try {
                if (window.drawariaVideoEditor.isRecording) {
                    window.drawariaVideoEditor.emergencyStop();
                }
                console.log('🧹 Recursos del editor limpiados');
            } catch (error) {
                console.error('Error durante limpieza:', error);
            }
        }
    }

    window.addEventListener('beforeunload', cleanup);
    window.addEventListener('unload', cleanup);

    // Agregar comando de menú de Tampermonkey
    if (typeof GM_registerMenuCommand !== 'undefined') {
        GM_registerMenuCommand('🎥 Abrir Video Editor', function() {
            if (window.drawariaVideoEditor) {
                window.drawariaVideoEditor.show();
            } else {
                alert('El editor no está disponible. Recarga la página.');
            }
        });

        GM_registerMenuCommand('🛑 Cerrar Video Editor', function() {
            if (window.drawariaVideoEditor) {
                window.drawariaVideoEditor.close();
            }
        });
    }

    // Detectar cambios de página
    let currentUrl = window.location.href;
    const urlChangeObserver = new MutationObserver(() => {
        if (window.location.href !== currentUrl) {
            currentUrl = window.location.href;
            console.log('🔄 URL cambió, verificando si reinicializar editor...');

            if (isDrawariaPage() && !window.drawariaVideoEditor) {
                setTimeout(() => {
                    initializeEditor();
                }, 1000);
            }
        }
    });

    urlChangeObserver.observe(document.body, {
        childList: true,
        subtree: true
    });

    // Agregar estilos CSS globales
    const globalStyles = document.createElement('style');
    globalStyles.textContent = `
        body.drawaria-video-editor-active {
            overflow: hidden !important;
        }

        @keyframes drawaria-editor-float {
            0%, 100% { transform: translateY(0px); }
            50% { transform: translateY(-5px); }
        }

        #drawaria-video-editor button:focus {
            outline: 2px solid #4da6ff !important;
            outline-offset: 2px;
        }

        @media (prefers-color-scheme: dark) {
            #drawaria-video-editor {
                filter: brightness(1.1);
            }
        }
    `;
    document.head.appendChild(globalStyles);

    // Inicializar cuando la página esté lista
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', main);
    } else {
        main();
    }

       // Mensaje de bienvenida en consola
    console.log(`
    🎬 ================================
    📹 DRAWARIA VIDEO EDITOR v1.0
    ================================
    ✅ Script cargado correctamente
    🌐 Sitio: ${window.location.hostname}
    📅 Fecha: ${new Date().toLocaleDateString()}

    📋 CARACTERÍSTICAS MEJORADAS:
    • 🎥 Grabación de canvas con audio
    • 🖼️ Soporte para múltiples imágenes
    • 🎵 SoundCloud Widget API mejorado
    • 🎶 Newgrounds con proxies CORS
    • ✨ Efectos visuales avanzados
    • 📱 Grabación de pantalla
    • 🔊 Test de captura de audio
    • ⌨️ Controles de teclado

    🎯 USO:
    1. Busca el botón flotante "🎥 Video Editor"
    2. Carga una imagen desde URL o archivo
    3. Configura velocidad y dirección
    4. Carga audio desde SoundCloud/Newgrounds
    5. ¡Graba tu video con audio!

    🎵 AUDIO MEJORADO:
    • SoundCloud: URLs completas soportadas
    • Newgrounds: Múltiples proxies CORS
    • Test de captura: Verifica compatibilidad
    • Multi-audio: Web Audio API integrado

    📞 SOPORTE:
    • GitHub: Reporta issues y sugerencias
    • Consola: Logs detallados disponibles
    • Hotkeys: Espacio, R, S, P, ESC
    • Audio test: Botón "🔊 Probar Captura"
    ================================
    `);

    // Función para mostrar información de depuración
    window.drawariaDebugInfo = function() {
        console.log('🐛 INFORMACIÓN DE DEPURACIÓN:');
        console.log('📊 Estado del Editor:', window.drawariaVideoEditor ? 'Iniciado' : 'No iniciado');
        console.log('🌐 URL actual:', window.location.href);
        console.log('📱 User Agent:', navigator.userAgent);
        console.log('🎥 MediaRecorder:', typeof MediaRecorder !== 'undefined' ? 'Soportado' : 'No soportado');
        console.log('🖥️ Screen Capture:', navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia ? 'Soportado' : 'No soportado');
        console.log('🔊 Audio Context:', typeof AudioContext !== 'undefined' || typeof webkitAudioContext !== 'undefined' ? 'Soportado' : 'No soportado');

        if (window.drawariaVideoEditor) {
            console.log('🎬 Estado de grabación:', window.drawariaVideoEditor.isRecording);
            console.log('🖼️ Imagen cargada:', window.drawariaVideoEditor.imageLoaded);
            console.log('▶️ Modo de scroll:', window.drawariaVideoEditor.scrollMode);
            console.log('⚡ Velocidad:', window.drawariaVideoEditor.scrollSpeed);
            console.log('🎵 SoundCloud Manager:', window.drawariaVideoEditor.soundCloudManager ? 'Disponible' : 'No disponible');
            console.log('🎚️ Multi Audio Manager:', window.drawariaVideoEditor.multiAudioManager ? 'Disponible' : 'No disponible');
        }
    };

    // Función para mostrar información de compatibilidad de audio
    window.drawariaAudioInfo = function() {
        console.log('🎵 INFORMACIÓN DE AUDIO:');

        // Test MediaRecorder
        const supportedTypes = [
            'video/webm;codecs=vp9,opus',
            'video/webm;codecs=vp8,opus',
            'video/webm;codecs=vp9',
            'video/webm;codecs=vp8'
        ];

        console.log('📊 Codecs soportados:');
        supportedTypes.forEach(type => {
            const supported = MediaRecorder.isTypeSupported ? MediaRecorder.isTypeSupported(type) : false;
            console.log(`  ${supported ? '✅' : '❌'} ${type}`);
        });

        // Test Audio Context
        try {
            const AudioContext = window.AudioContext || window.webkitAudioContext;
            if (AudioContext) {
                const testContext = new AudioContext();
                console.log('✅ AudioContext disponible');
                console.log('📊 Sample Rate:', testContext.sampleRate);
                console.log('📊 State:', testContext.state);
                testContext.close();
            }
        } catch (e) {
            console.log('❌ AudioContext error:', e.message);
        }

        // Test HTMLMediaElement.captureStream()
        try {
            const testAudio = document.createElement('audio');
            if (typeof testAudio.captureStream === 'function' || typeof testAudio.mozCaptureStream === 'function') {
                console.log('✅ HTMLMediaElement.captureStream() disponible');
            } else {
                console.log('❌ HTMLMediaElement.captureStream() no disponible');
            }
        } catch (e) {
            console.log('❌ Error testing captureStream:', e.message);
        }
    };

    // Función para test rápido de SoundCloud
    window.testSoundCloud = function(url) {
        if (!url) {
            console.log('❌ Proporciona una URL de SoundCloud');
            console.log('Ejemplo: testSoundCloud("https://soundcloud.com/artist/track")');
            return;
        }

        if (window.drawariaVideoEditor && window.drawariaVideoEditor.soundCloudManager) {
            const isValid = window.drawariaVideoEditor.soundCloudManager.isSoundCloudUrl(url);
            console.log(isValid ? '✅ URL de SoundCloud válida' : '❌ URL de SoundCloud inválida');

            if (isValid) {
                console.log('🎵 Puedes usar esta URL en el editor');
                console.log('📋 Copia y pega en el campo "🎶 Cargar Audio"');
            }
        } else {
            console.log('❌ Editor no inicializado. Abre el editor primero.');
        }
    };

    // Función para mostrar ayuda
    window.drawariaHelp = function() {
        console.log(`
        🆘 AYUDA - DRAWARIA VIDEO EDITOR
        ================================

        📋 COMANDOS DISPONIBLES EN CONSOLA:
        • drawariaDebugInfo() - Información de depuración
        • drawariaAudioInfo() - Compatibilidad de audio
        • testSoundCloud("url") - Test URL SoundCloud
        • drawariaHelp() - Mostrar esta ayuda

        ⌨️ ATAJOS DE TECLADO:
        • ESPACIO - Pausar/Reanudar grabación
        • R - Iniciar grabación
        • S - Parar grabación
        • P - Toggle previsualización
        • ESC - Parada de emergencia

        🎵 FORMATOS DE AUDIO SOPORTADOS:
        • SoundCloud: URLs completas de tracks
        • Newgrounds: audio.ngfiles.com/*
        • Archivos: MP3, WAV, OGG, M4A, AAC
        • URLs directas con headers CORS

        🎥 FORMATOS DE GRABACIÓN:
        • WebM VP9 con Opus (preferido)
        • WebM VP8 con Opus (fallback)
        • WebM VP9 solo video
        • WebM VP8 solo video

        🛠️ SOLUCIÓN DE PROBLEMAS:
        1. Audio no se graba: Usar "🔊 Probar Captura"
        2. Imagen no carga: Verificar dominio CORS
        3. Grabación falla: Revisar compatibilidad navegador
        4. SoundCloud no funciona: Verificar URL completa

        📞 SOPORTE:
        • Consola del navegador (F12) para logs
        • GitHub issues para reportes
        • Documentación en código fuente
        ================================
        `);
    };

    // Event listener para detectar errores de audio específicamente
    window.addEventListener('error', (event) => {
        if (event.error && event.error.message) {
            const message = event.error.message.toLowerCase();

            if (message.includes('audio') || message.includes('sound') || message.includes('media')) {
                console.warn('🎵 Error relacionado con audio detectado:', event.error.message);
                console.log('💡 Sugerencia: Ejecuta drawariaAudioInfo() para verificar compatibilidad');
            }

            if (message.includes('cors') || message.includes('cross-origin')) {
                console.warn('🌐 Error CORS detectado:', event.error.message);
                console.log('💡 Sugerencia: Usa dominios compatibles como i.ibb.co o imgur.com para imágenes');
            }
        }
    });

    // Agregar script de SoundCloud Widget API si no existe
    function loadSoundCloudWidgetAPI() {
        if (typeof SC !== 'undefined' && SC.Widget) {
            console.log('✅ SoundCloud Widget API ya disponible');
            return Promise.resolve();
        }

        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = 'https://w.soundcloud.com/player/api.js';
            script.async = true;

            script.onload = () => {
                console.log('✅ SoundCloud Widget API cargado');
                resolve();
            };

            script.onerror = () => {
                console.warn('⚠️ No se pudo cargar SoundCloud Widget API');
                reject(new Error('SoundCloud API load failed'));
            };

            document.head.appendChild(script);
        });
    }

    // Función para verificar y preparar el entorno
    async function prepareEnvironment() {
        console.log('🔧 Preparando entorno...');

        try {
            // Cargar SoundCloud Widget API
            await loadSoundCloudWidgetAPI();
        } catch (error) {
            console.warn('⚠️ SoundCloud Widget API no disponible, continuando sin él');
        }

        // Verificar permisos necesarios
        if (navigator.permissions) {
            try {
                const micPermission = await navigator.permissions.query({ name: 'microphone' });
                console.log('🎤 Permisos de micrófono:', micPermission.state);

                if ('display-capture' in navigator.permissions) {
                    const displayPermission = await navigator.permissions.query({ name: 'display-capture' });
                    console.log('🖥️ Permisos de pantalla:', displayPermission.state);
                }
            } catch (error) {
                console.log('ℹ️ No se pudieron verificar permisos, continuando...');
            }
        }

        console.log('✅ Entorno preparado');
    }

    // Función de inicialización principal mejorada
    async function initializeEditorWithEnvironment() {
        try {
            console.log('🚀 Inicializando Drawaria Video Editor con entorno completo...');

            // Preparar entorno
            await prepareEnvironment();

            // Inicializar editor
            initializeEditor();

            // Mostrar comandos disponibles
            setTimeout(() => {
                console.log('🎉 ¡Editor listo!');
                console.log('💡 Tip: Ejecuta drawariaHelp() para ver todos los comandos disponibles');
                console.log('🔊 Tip: Usa drawariaAudioInfo() para verificar compatibilidad de audio');
            }, 2000);

        } catch (error) {
            console.error('❌ Error en inicialización completa:', error);
            // Intentar inicialización básica como fallback
            initializeEditor();
        }
    }

    // Detectar si el usuario tiene SoundCloud abierto en otras pestañas
    function detectExistingSoundCloud() {
        try {
            // Intentar detectar si hay SoundCloud en localStorage
            const soundCloudData = localStorage.getItem('sc_anonymous_id');
            if (soundCloudData) {
                console.log('🎵 SoundCloud detectado en el navegador - Compatibilidad mejorada disponible');
            }
        } catch (error) {
            // Ignorar errores de localStorage
        }
    }

    // Modificar la inicialización principal para usar la nueva función
    async function main() {
        try {
            if (!isDrawariaPage()) {
                console.log('🔄 Script cargado pero no está en drawaria.online');
                return;
            }

            await waitForPageLoad();

            // Detectar entorno SoundCloud existente
            detectExistingSoundCloud();

            setTimeout(() => {
                // Usar la función de inicialización mejorada
                initializeEditorWithEnvironment();
            }, 2000);

            console.log('✅ Script de Drawaria Video Editor cargado exitosamente');

        } catch (error) {
            console.error('❌ Error en inicialización principal:', error);
        }
    }

    // Llamada principal
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', main);
    } else {
        main();
    }

})();