Drawaria Video Editor

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

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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();
    }

})();