{
"manifest_version": 3,
"name": "Media Loader",
"version": "1.0",
"description": "Load and play music and videos from YouTube and Vimeo",
"permissions": ["storage", "tabs"],
"host_permissions": [
"https://www.youtube.com/",
"https://player.vimeo.com/"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_title": "Open Media Loader",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
}
}

Settings
SyncWave

    <!-- Load Audio Section -->
    <section class="section" id="load-music-section">
        <div class="section-header">
            <legend>Load Audio</legend>
        </div>
        
        <fieldset>
            <label for="music-url">Audio URL</label>
            <input type="text" id="music-url" name="music-url" placeholder="Enter YouTube or Vimeo URL">

            <label for="music-file">Upload Audio File</label>
            <input type="file" id="music-file" name="music-file" accept="audio/*">

            <label for="music-start">Start Time (seconds)</label>
            <input type="number" id="music-start" name="music-start" placeholder="Start Time (seconds)" min="0">

            <button type="button" id="load-music" class="load-button">Load Audio</button>
        </fieldset>
        <div id="music-player-container" class="player-container"></div>
    </section>

    <!-- Load Video Section -->
    <section class="section" id="load-video-section">
        <fieldset>
            <legend>Load Video</legend>
            
            <label for="video-url">Video URL</label>
            <input type="text" id="video-url" name="video-url" placeholder="Enter YouTube or Vimeo URL">

            <label for="video-file">Upload Video File</label>
            <input type="file" id="video-file" name="video-file" accept="video/*">

            <label for="video-start">Start Time (seconds)</label>
            <input type="number" id="video-start" name="video-start" placeholder="Start Time (seconds)" min="0">

            <button type="button" id="load-video" class="load-button">Load Video</button>
        </fieldset>
        <div id="video-player-container" class="player-container"></div>
    </section>

    <!-- Playback Controls -->
    <section class="controls">
        <button type="button" id="play-button" disabled aria-label="Play">Play</button>
        <button type="button" id="pause-resume-button" disabled aria-label="Pause">Pause</button>
        <button type="button" id="play-start-button" disabled aria-label="Play from Start">Play from Start</button>
    </section>

    <!-- Message Container -->
    <section id="message-container" class="message-container" role="alert" aria-live="assertive"></section>

    <!-- Settings Modal (Remains Unchanged) -->
    <div id="settings-modal" class="modal" role="dialog" aria-labelledby="settings-modal-title" aria-modal="true" hidden>
        <div class="modal-content">
            <button class="close-button" aria-label="Close Settings Modal">&times;</button>
            <h2 id="settings-modal-title">Settings</h2>
            <form>
                <label for="fullscreen-toggle">
                    <input type="checkbox" id="fullscreen-toggle" name="fullscreen-toggle">
                    Full Screen on Play
                </label>
                <!-- Additional settings can go here -->
            </form>
        </div>
    </div>
</main>

<!-- Your Dashboard JS -->
<script src="dashboard.js"></script>
"use strict";

document.addEventListener('DOMContentLoaded', () => {
// === Element References ===
const elements = {
music: {
urlInput: document.getElementById('music-url'),
fileInput: document.getElementById('music-file'),
startInput: document.getElementById('music-start'),
loadButton: document.getElementById('load-music'),
playerContainer: document.getElementById('music-player-container')
},
video: {
urlInput: document.getElementById('video-url'),
fileInput: document.getElementById('video-file'),
startInput: document.getElementById('video-start'),
loadButton: document.getElementById('load-video'),
playerContainer: document.getElementById('video-player-container')
},
controls: {
playButton: document.getElementById('play-button'),
pauseResumeButton: document.getElementById('pause-resume-button'),
playStartButton: document.getElementById('play-start-button')
},
messageContainer: document.getElementById('message-container'),
settings: {
button: document.getElementById('settings-button'),
modal: document.getElementById('settings-modal'),
closeButton: document.querySelector('.close-button'),
fullscreenToggle: document.getElementById('fullscreen-toggle')
}
};


// === State Management ===
const state = {
    music: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLAudioElement | HTMLIFrameElement, start: Number }
    video: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLVideoElement | HTMLIFrameElement, start: Number }
    isPaused: false,
    fullscreenOnPlay: false
};

// === Utility Functions ===

/**
 * Formats seconds into 'XmYs' (e.g., 125 seconds -> '2m5s')
 * @param {number} seconds - The time in seconds.
 * @returns {string} Formatted time string.
 */
function formatTime(seconds) {
    if (isNaN(seconds) || seconds < 0) return '';
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return `${minutes}m${remainingSeconds}s`;
}

/**
 * Capitalize the first letter of a string.
 * @param {string} text - The string to capitalize.
 * @returns {string} Capitalized string.
 */
function capitalize(text) {
    if (!text) return '';
    return text.charAt(0).toUpperCase() + text.slice(1);
}

/**
 * Displays a message to the user.
 * @param {string} message - The message to display.
 * @param {string} type - The type of message ('success', 'error', 'info').
 */
function showMessage(message, type) {
    elements.messageContainer.innerHTML = '';
    const msgDiv = document.createElement('div');
    msgDiv.textContent = message;
    msgDiv.classList.add('message', type); // 'success', 'error', 'info'
    elements.messageContainer.appendChild(msgDiv);

    // Automatically hide message after 5 seconds
    setTimeout(() => {
        if (elements.messageContainer.contains(msgDiv)) {
            elements.messageContainer.removeChild(msgDiv);
        }
    }, 5000);
}

/**
 * Shows a loading spinner in the specified container.
 * @param {HTMLElement} container - The container to show the loader in.
 */
function showLoading(container) {
    container.innerHTML = '';
    const loader = document.createElement('div');
    loader.classList.add('loader'); // Define loader styles in CSS
    container.appendChild(loader);
}

/**
 * Hides the loading spinner from the specified container.
 * @param {HTMLElement} container - The container to hide the loader from.
 */
function hideLoading(container) {
    const loader = container.querySelector('.loader');
    if (loader) {
        container.removeChild(loader);
    }
}

/**
 * Traps keyboard focus within a specified element.
 * @param {HTMLElement} element - The element to trap focus within.
 */
function trapFocus(element) {
    const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]),' +
        ' textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"],' +
        ' [contenteditable]';
    const focusableElements = element.querySelectorAll(focusableElementsString);
    const firstTabStop = focusableElements[0];
    const lastTabStop = focusableElements[focusableElements.length - 1];

    // Listen for and trap the keyboard
    element.addEventListener('keydown', trapTabKey);

    function trapTabKey(e) {
        // Check for TAB key press
        if (e.key === 'Tab') {
            // SHIFT + TAB
            if (e.shiftKey) {
                if (document.activeElement === firstTabStop) {
                    e.preventDefault();
                    lastTabStop.focus();
                }
            } else { // TAB
                if (document.activeElement === lastTabStop) {
                    e.preventDefault();
                    firstTabStop.focus();
                }
            }
        }
    }

    // Remove trap when modal is closed
    function removeTrapKey(e) {
        element.removeEventListener('keydown', trapTabKey);
    }

    // Store the function reference to remove it later
    element.removeTrapKey = removeTrapKey;
}

function removeTrapFocus() {
    if (elements.settings.modal.removeTrapKey) {
        elements.settings.modal.removeTrapKey();
    }
}

// === Initialization ===
loadSettings();

// === Event Listeners ===
elements.music.loadButton.addEventListener('click', handleLoadMusic);
elements.video.loadButton.addEventListener('click', handleLoadVideo);
elements.controls.playButton.addEventListener('click', handlePlay);
elements.controls.pauseResumeButton.addEventListener('click', handlePauseResume);
elements.controls.playStartButton.addEventListener('click', handlePlayFromStart);

// Settings Modal Event Listeners
elements.settings.button.addEventListener('click', openSettingsModal);
elements.settings.closeButton.addEventListener('click', closeSettingsModal);
window.addEventListener('click', (event) => {
    if (event.target === elements.settings.modal) {
        closeSettingsModal();
    }
});
document.addEventListener('keydown', (event) => {
    if (event.key === 'Escape' && !elements.settings.modal.hasAttribute('hidden')) {
        closeSettingsModal();
    }
});
elements.settings.fullscreenToggle.addEventListener('change', (event) => {
    state.fullscreenOnPlay = event.target.checked;
    saveSettings();
});

// === Handler Functions ===

// Load Music Handler
function handleLoadMusic() {
    const url = elements.music.urlInput.value.trim();
    const file = elements.music.fileInput.files[0];
    const start = parseInt(elements.music.startInput.value) || 0;

    // Show loading indicator
    showLoading(elements.music.playerContainer);

    // Unload existing music if any
    if (state.music) {
        unloadMedia('music');
    }

    if (file) {
        if (file.size > 10 * 1024 * 1024) { // 10MB limit
            showMessage('Audio file size exceeds 10MB limit.', 'error');
            hideLoading(elements.music.playerContainer);
            return;
        }

        // Handle local audio file
        const fileUrl = URL.createObjectURL(file);
        const audioElement = document.createElement('audio');
        audioElement.controls = true;
        audioElement.src = fileUrl;
        audioElement.id = 'loaded-music';
        audioElement.setAttribute('aria-label', 'Loaded Audio Player');
        audioElement.style.width = '100%';
        audioElement.style.height = 'auto';
        elements.music.playerContainer.innerHTML = '';
        elements.music.playerContainer.appendChild(audioElement);

        // Set start time if applicable
        if (start > 0) {
            audioElement.currentTime = start;
        }

        state.music = {
            type: 'file',
            element: audioElement,
            start: start
        };
        showMessage('Local audio file loaded.', 'success');
        hideLoading(elements.music.playerContainer);
    } else if (url && isValidMediaURL(url)) {
        const mediaInfo = extractMediaInfo(url);
        if (mediaInfo) {
            if (mediaInfo.platform === 'youtube') {
                embedYouTubeIframe(mediaInfo.id, start, 'music');
            } else if (mediaInfo.platform === 'vimeo') {
                embedVimeoIframe(mediaInfo.id, start, 'music');
            }
            showMessage(`Loaded ${capitalize(mediaInfo.platform)} audio.`, 'success');
            hideLoading(elements.music.playerContainer);
        } else {
            showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
            hideLoading(elements.music.playerContainer);
        }
    } else {
        showMessage('Please enter a URL or select an audio file.', 'error');
        hideLoading(elements.music.playerContainer);
    }

    checkReadyToPlay();
    saveSettings();
}

// Load Video Handler
function handleLoadVideo() {
    const url = elements.video.urlInput.value.trim();
    const file = elements.video.fileInput.files[0];
    const start = parseInt(elements.video.startInput.value) || 0;

    // Show loading indicator
    showLoading(elements.video.playerContainer);

    // Unload existing video if any
    if (state.video) {
        unloadMedia('video');
    }

    if (file) {
        if (file.size > 50 * 1024 * 1024) { // 50MB limit
            showMessage('Video file size exceeds 50MB limit.', 'error');
            hideLoading(elements.video.playerContainer);
            return;
        }

        // Handle local video file
        const fileUrl = URL.createObjectURL(file);
        const videoElement = document.createElement('video');
        videoElement.controls = true;
        videoElement.src = fileUrl;
        videoElement.id = 'loaded-video';
        videoElement.setAttribute('aria-label', 'Loaded Video Player');
        videoElement.style.width = '100%';
        videoElement.style.height = 'auto';
        elements.video.playerContainer.innerHTML = '';
        elements.video.playerContainer.appendChild(videoElement);

        // Set start time if applicable
        if (start > 0) {
            videoElement.currentTime = start;
        }

        state.video = {
            type: 'file',
            element: videoElement,
            start: start
        };
        showMessage('Local video file loaded.', 'success');
        hideLoading(elements.video.playerContainer);
    } else if (url && isValidMediaURL(url)) {
        const mediaInfo = extractMediaInfo(url);
        if (mediaInfo) {
            if (mediaInfo.platform === 'youtube') {
                embedYouTubeIframe(mediaInfo.id, start, 'video');
            } else if (mediaInfo.platform === 'vimeo') {
                embedVimeoIframe(mediaInfo.id, start, 'video');
            }
            showMessage(`Loaded ${capitalize(mediaInfo.platform)} video.`, 'success');
            hideLoading(elements.video.playerContainer);
        } else {
            showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
            hideLoading(elements.video.playerContainer);
        }
    } else {
        showMessage('Please enter a URL or select a video file.', 'error');
        hideLoading(elements.video.playerContainer);
    }

    checkReadyToPlay();
    saveSettings();
}

// Play Handler
function handlePlay() {
    // Play Music
    if (state.music) {
        if (state.music.type === 'file') {
            state.music.element.play();
            if (state.fullscreenOnPlay) {
                enterFullscreen(state.music.element);
            }
        } else {
            // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
            showMessage('Cannot control external media playback programmatically.', 'info');
        }
    }

    // Play Video
    if (state.video) {
        if (state.video.type === 'file') {
            state.video.element.play();
            if (state.fullscreenOnPlay) {
                enterFullscreen(state.video.element);
            }
        } else {
            // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
            showMessage('Cannot control external media playback programmatically.', 'info');
        }
    }

    state.isPaused = false;
    elements.controls.pauseResumeButton.textContent = 'Pause';
    showMessage('Playback started!', 'success');
}

// Pause/Resume Handler
function handlePauseResume() {
    if (state.isPaused) {
        resumeMedia();
    } else {
        pauseMedia();
    }
}

// Pause Media
function pauseMedia() {
    // Pause Music
    if (state.music) {
        if (state.music.type === 'file') {
            state.music.element.pause();
        } else {
            // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
            showMessage('Cannot pause external media playback programmatically.', 'info');
        }
    }

    // Pause Video
    if (state.video) {
        if (state.video.type === 'file') {
            state.video.element.pause();
        } else {
            // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
            showMessage('Cannot pause external media playback programmatically.', 'info');
        }
    }

    state.isPaused = true;
    elements.controls.pauseResumeButton.textContent = 'Resume';
    showMessage('Playback paused.', 'info');
}

// Resume Media
function resumeMedia() {
    // Resume Music
    if (state.music) {
        if (state.music.type === 'file') {
            state.music.element.play();
        } else {
            // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
            showMessage('Cannot resume external media playback programmatically.', 'info');
        }
    }

    // Resume Video
    if (state.video) {
        if (state.video.type === 'file') {
            state.video.element.play();
        } else {
            // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
            showMessage('Cannot resume external media playback programmatically.', 'info');
        }
    }

    state.isPaused = false;
    elements.controls.pauseResumeButton.textContent = 'Pause';
    showMessage('Playback resumed.', 'success');
}

// Play From Start Handler
function handlePlayFromStart() {
    // Play from Start Music
    if (state.music) {
        if (state.music.type === 'file') {
            state.music.element.currentTime = state.music.start;
            state.music.element.play();
            if (state.fullscreenOnPlay) {
                enterFullscreen(state.music.element);
            }
        } else {
            // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
            showMessage('Cannot control external media playback programmatically.', 'info');
        }
    }

    // Play from Start Video
    if (state.video) {
        if (state.video.type === 'file') {
            state.video.element.currentTime = state.video.start;
            state.video.element.play();
            if (state.fullscreenOnPlay) {
                enterFullscreen(state.video.element);
            }
        } else {
            // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
            showMessage('Cannot control external media playback programmatically.', 'info');
        }
    }

    state.isPaused = false;
    elements.controls.pauseResumeButton.textContent = 'Pause';
    showMessage('Playback restarted!', 'success');
}

// === Settings Modal Functions ===
function openSettingsModal() {
    elements.settings.modal.removeAttribute('hidden');
    elements.settings.modal.setAttribute('aria-hidden', 'false');
    elements.settings.modal.querySelector('.close-button').focus();
    trapFocus(elements.settings.modal);
}

function closeSettingsModal() {
    elements.settings.modal.setAttribute('hidden', '');
    elements.settings.modal.setAttribute('aria-hidden', 'true');
    elements.settings.button.focus();
    removeTrapFocus();
}

// === Media Embedding Functions ===

/**
 * Embeds a YouTube video into the specified container using an iframe.
 * Adds 'autoplay=1' and 'mute=1' to initiate buffering upon load.
 * Removes the redundant 'allowfullscreen' attribute.
 * @param {string} videoId - The YouTube video ID.
 * @param {number} start - The start time in seconds.
 * @param {string} mediaType - 'music' or 'video'.
 */
function embedYouTubeIframe(videoId, start, mediaType) {
    const container = elements[mediaType].playerContainer;
    container.innerHTML = ''; // Clear previous content

    const iframe = document.createElement('iframe');
    iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1&mute=1&start=${start}&controls=1&rel=0`;
    iframe.width = '100%';
    iframe.height = '360';
    iframe.frameBorder = '0';
    iframe.allow = 'autoplay; fullscreen; picture-in-picture';
    // Remove the 'allowfullscreen' attribute if it's being set separately
    // Using 'allow' instead to include fullscreen
    // iframe.allowFullscreen = true; // Removed to prevent CSP conflict

    iframe.setAttribute('title', 'YouTube video player');

    container.appendChild(iframe);

    state[mediaType] = {
        type: 'youtube',
        element: iframe,
        start: start
    };
}

/**
 * Embeds a Vimeo video into the specified container using an iframe.
 * Adds 'autoplay=1' and 'muted=1' to initiate buffering upon load.
 * Removes the redundant 'allowfullscreen' attribute.
 * @param {string} videoId - The Vimeo video ID.
 * @param {number} start - The start time in seconds.
 * @param {string} mediaType - 'music' or 'video'.
 */
function embedVimeoIframe(videoId, start, mediaType) {
    const container = elements[mediaType].playerContainer;
    container.innerHTML = ''; // Clear previous content

    const iframe = document.createElement('iframe');
    iframe.src = `https://player.vimeo.com/video/${videoId}?autoplay=1&muted=1#t=${start}s`;
    iframe.width = '100%';
    iframe.height = '360';
    iframe.frameBorder = '0';
    iframe.allow = 'autoplay; fullscreen; picture-in-picture';
    // Remove the 'allowfullscreen' attribute if it's being set separately
    // Using 'allow' instead to include fullscreen
    // iframe.allowFullscreen = true; // Removed to prevent CSP conflict

    iframe.setAttribute('title', 'Vimeo video player');

    container.appendChild(iframe);

    state[mediaType] = {
        type: 'vimeo',
        element: iframe,
        start: start
    };
}

// === Settings Management ===

/**
 * Loads settings from Chrome storage.
 */
function loadSettings() {
    try {
        chrome.storage.local.get(['mediaSettings'], (result) => {
            if (chrome.runtime.lastError) {
                throw new Error(chrome.runtime.lastError);
            }

            if (result.mediaSettings) {
                const { music, video, fullscreenOnPlay: fsPlay } = result.mediaSettings;

                if (music) {
                    if (music.type === 'youtube' || music.type === 'vimeo') {
                        const url = music.type === 'youtube' 
                            ? `https://www.youtube.com/watch?v=${music.id}` 
                            : `https://vimeo.com/${music.id}`;
                        elements.music.urlInput.value = url;
                        elements.music.startInput.value = music.start || 0;
                        // Optionally, auto-load the media by triggering the load button
                        // handleLoadMusic();
                    }
                    // Handle file-based music loading if necessary
                }

                if (video) {
                    if (video.type === 'youtube' || video.type === 'vimeo') {
                        const url = video.type === 'youtube' 
                            ? `https://www.youtube.com/watch?v=${video.id}` 
                            : `https://vimeo.com/${video.id}`;
                        elements.video.urlInput.value = url;
                        elements.video.startInput.value = video.start || 0;
                        // Optionally, auto-load the media by triggering the load button
                        // handleLoadVideo();
                    }
                    // Handle file-based video loading if necessary
                }

                if (typeof fsPlay === 'boolean') {
                    state.fullscreenOnPlay = fsPlay;
                    elements.settings.fullscreenToggle.checked = fsPlay;
                }
            }
        });
    } catch (error) {
        console.error('Error loading settings:', error);
        showMessage('Failed to load settings.', 'error');
    }
}

/**
 * Saves settings to Chrome storage.
 */
function saveSettings() {
    const settings = {
        music: state.music,
        video: state.video,
        fullscreenOnPlay: state.fullscreenOnPlay
    };
    try {
        chrome.storage.local.set({ mediaSettings: settings }, () => {
            if (chrome.runtime.lastError) {
                throw new Error(chrome.runtime.lastError);
            }
            console.log('Settings saved.');
        });
    } catch (error) {
        console.error('Error saving settings:', error);
        showMessage('Error saving settings.', 'error');
    }
}

/**
 * Unloads media from the specified type.
 * @param {string} mediaType - 'music' or 'video'.
 */
function unloadMedia(mediaType) {
    if (state[mediaType]) {
        if (state[mediaType].type === 'file') {
            if (state[mediaType].element.src) {
                URL.revokeObjectURL(state[mediaType].element.src);
                state[mediaType].element.src = '';
                state[mediaType].element.remove();
            }
        } else if (state[mediaType].type === 'youtube' || state[mediaType].type === 'vimeo') {
            const iframe = state[mediaType].element;
            iframe.src = ''; // Reset iframe src to stop the media
        }
        state[mediaType] = null;
    }
}

// === Playback Controls ===

/**
 * Enables or disables playback controls based on media loading state.
 */
function checkReadyToPlay() {
    // Enable Play button only when at least one of audio or video is loaded
    const readyAudio = state.music && (state.music.type === 'file' || state.music.type === 'youtube' || state.music.type === 'vimeo');
    const readyVideo = state.video && (state.video.type === 'file' || state.video.type === 'youtube' || state.video.type === 'vimeo');
    const ready = readyAudio || readyVideo;

    elements.controls.playButton.disabled = !ready;
    elements.controls.pauseResumeButton.disabled = !ready;
    elements.controls.playStartButton.disabled = !ready;
}

/**
 * Enters fullscreen mode for the specified element.
 * @param {HTMLElement} element - The element to enter fullscreen.
 */
function enterFullscreen(element) {
    if (element && element.requestFullscreen) {
        element.requestFullscreen().then(() => {
            showMessage('Entered fullscreen mode.', 'success');
        }).catch(err => {
            console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
            showMessage('Failed to enter fullscreen mode.', 'error');
        });
    } else {
        showMessage('Fullscreen not supported on this element.', 'error');
    }
}

// === New Utility Functions ===

/**
 * Validates whether the URL is a valid YouTube or Vimeo URL.
 * @param {string} url - The URL to validate.
 * @returns {boolean} True if valid, else false.
 */
function isValidMediaURL(url) {
    try {
        const parsedUrl = new URL(url);
        const hostname = parsedUrl.hostname.toLowerCase();
        const pathname = parsedUrl.pathname;

        // YouTube RegEx Patterns
        const youtubeRegex = /^(?:\/watch\/?|\/embed\/|\/v\/)?([a-zA-Z0-9_-]{11})$/;
        // Vimeo RegEx Patterns
        const vimeoRegex = /^\/(?:video\/)?(\d+)$/;

        if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
            // Extract YouTube video ID
            let videoId = '';
            if (hostname === 'youtu.be') {
                videoId = pathname.slice(1);
            } else {
                videoId = parsedUrl.searchParams.get('v') || '';
            }
            return youtubeRegex.test(`/${videoId}`);
        } else if (hostname.includes('vimeo.com')) {
            // Extract Vimeo video ID
            const match = pathname.match(vimeoRegex);
            return match && match[1].length > 0;
        }

        return false;
    } catch (e) {
        return false;
    }
}

/**
 * Extracts media information from the URL.
 * @param {string} url - The media URL.
 * @returns {Object|null} An object with platform and id, or null if invalid.
 */
function extractMediaInfo(url) {
    try {
        const parsedUrl = new URL(url);
        const hostname = parsedUrl.hostname.toLowerCase();
        const pathname = parsedUrl.pathname;

        // YouTube Patterns
        if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
            let videoId = '';
            if (hostname === 'youtu.be') {
                videoId = pathname.slice(1);
            } else {
                videoId = parsedUrl.searchParams.get('v') || '';
            }

            // Validate videoId length
            if (videoId.length === 11) {
                return { platform: 'youtube', id: videoId };
            }
        }

        // Vimeo Patterns
        if (hostname.includes('vimeo.com')) {
            const vimeoMatch = pathname.match(/^\/(?:video\/)?(\d+)$/);
            if (vimeoMatch && vimeoMatch[1]) {
                return { platform: 'vimeo', id: vimeoMatch[1] };
            }
        }

        return null;
    } catch (e) {
        return null;
    }
}
});

chrome.action.onClicked.addListener(() => {
const dashboardURL = chrome.runtime.getURL("dashboard.html");


// Query for any existing tabs with the dashboard URL
chrome.tabs.query({ url: dashboardURL }, (tabs) => {
    if (chrome.runtime.lastError) {
        console.error("Tab Query Error:", chrome.runtime.lastError);
        return;
    }

    if (tabs.length > 0) {
        // Activate the first existing dashboard tab
        chrome.tabs.update(tabs[0].id, { active: true }, (updatedTab) => {
            if (chrome.runtime.lastError) {
                console.error("Tab Update Error:", chrome.runtime.lastError);
            }
        });
    } else {
        // Create a new dashboard tab
        chrome.tabs.create({ url: dashboardURL, active: true }, (newTab) => {
            if (chrome.runtime.lastError) {
                console.error("Tab Creation Error:", chrome.runtime.lastError);
            }
        });
    }
});
});

/* General Styles */
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}

.container {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
max-width: 800px;
margin: 0 auto;
}

.section {
width: 100%;
margin-bottom: 20px;
background-color: #fff;
padding: 15px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* Header with Settings Button and Main Title /
.header {
width: 100%;
display: flex;
align-items: center;
justify-content: center; / Center the content */
margin-bottom: 20px;
position: relative;
}

.settings-button {
position: absolute;
left: 0;
background: #fff;
border: 1px solid #ccc;
border-radius: 5px;
padding: 5px;
cursor: pointer;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.3s ease, border-color 0.3s ease;
}

.settings-button:hover {
background-color: #f0f0f0;
border-color: #999;
}

.settings-icon {
width: 20px;
height: 20px;
}

.main-title {
font-size: 2em;
font-weight: bold;
margin: 0;
opacity: 0;
animation: fadeInShake 5s forwards;
}

@keyframes fadeInShake {
0% {
opacity: 0;
transform: translateX(0);
color: #FF0000; /* Red /
}
10% {
opacity: 0.2;
transform: translateX(-10px);
color: #FF7F00; / Orange /
}
20% {
opacity: 0.4;
transform: translateX(10px);
color: #FFFF00; / Yellow /
}
30% {
opacity: 0.6;
transform: translateX(-10px);
color: #00FF00; / Green /
}
40% {
opacity: 0.7;
transform: translateX(10px);
color: #0000FF; / Blue /
}
50% {
opacity: 0.8;
transform: translateX(-10px);
color: #4B0082; / Indigo /
}
60% {
opacity: 0.85;
transform: translateX(10px);
color: #8B00FF; / Violet /
}
70% {
opacity: 0.9;
transform: translateX(-10px);
color: #FF00FF; / Magenta /
}
80% {
opacity: 0.95;
transform: translateX(10px);
color: #000000; / Black /
}
100% {
opacity: 1;
transform: translateX(0);
color: #000000; / Black */
}
}

/* Section Header */
.section-header {
display: flex;
align-items: center;
margin-bottom: 10px;
}

.section-header legend {
font-size: 1.2em;
font-weight: bold;
margin: 0;
}

/* Controls */
.controls {
display: flex;
gap: 10px;
margin-bottom: 20px;
}

.controls button {
padding: 10px 20px;
cursor: pointer;
border: none;
border-radius: 5px;
background-color: #4285f4;
color: #fff;
transition: background-color 0.3s ease;
}

.controls button:disabled {
background-color: #a0c3ff;
cursor: not-allowed;
}

.controls button:hover:not(:disabled) {
background-color: #357ae8;
}

/* Modal Styles */
.modal[hidden] {
display: none;
}

.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex; /* Visible when not hidden */
align-items: center;
justify-content: center;
z-index: 1000;
}

.modal-content {
background-color: #fff;
padding: 20px 30px;
border-radius: 8px;
width: 90%;
max-width: 400px;
position: relative;
}

.close-button {
position: absolute;
top: 10px;
right: 15px;
background: none;
border: none;
font-size: 24px;
cursor: pointer;
}

.modal-content h2 {
margin-top: 0;
}

/* Form Elements */
fieldset {
border: none;
padding: 0;
}

fieldset label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}

fieldset input[type="text"],
fieldset input[type="number"],
fieldset input[type="file"] {
width: 100%;
padding: 8px;
margin-bottom: 15px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
}

fieldset .load-button {
width: 100%;
padding: 10px;
background-color: #34a853;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}

fieldset .load-button:hover {
background-color: #2c8e46;
}

/* Player Containers /
.player-container {
margin-top: 10px;
width: 100%;
max-width: 100%;
min-height: 50px;
box-sizing: border-box;
overflow: hidden; / Prevent overflow */
}

/* Responsive Video Elements /
.player-container video,
.player-container iframe {
width: 100%;
height: auto;
max-height: 360px; / Adjust as needed /
border-radius: 8px;
/ Ensure the iframe fills the container */
display: block;
}

/* Messages */
.message-container {
margin-top: 20px;
width: 100%;
}

.message {
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
color: #fff;
}

.message.success {
background-color: #4caf50;
}

.message.error {
background-color: #f44336;
}

.message.info {
background-color: #2196f3;
}

/* Loader /
.loader {
border: 8px solid #f3f3f3; / Light grey /
border-top: 8px solid #4285f4; / Blue */
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 0 auto;
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

/* Responsive Design */
@media (max-width: 600px) {
.container {
padding: 10px;
}


.modal-content {
    padding: 15px 20px;
}

.controls {
    flex-direction: column;
    width: 100%;
}

.controls button {
    width: 100%;
}

.settings-container {
    /* Removed absolute positioning */
}

.settings-button {
    width: 35px;
    height: 35px;
}

.settings-icon {
    width: 18px;
    height: 18px;
}

.main-title {
    font-size: 1.5em;
}
}

i only need the full updated files. the videos are still small when loaded and i dont want them to auto play just buffer. i only tested vimeo urls if that matters. get rid of the load video and load audio texts that are not on the buttons. replace the words upload with local.


Certainly! Below are the fully updated files for your Chrome extension based on your requirements:

Increase Video Size
Prevent Auto-Play (Only Buffer)
Replace "Upload" with "Local" in Labels
Remove "Load Audio" and "Load Video" Texts Outside Buttons
1. manifest.json
No changes were required for this file based on your specifications. However, it's included here for completeness.


{
  "manifest_version": 3,
  "name": "Media Loader",
  "version": "1.0",
  "description": "Load and play music and videos from YouTube and Vimeo",
  "permissions": ["storage", "tabs"],
  "host_permissions": [
    "https://www.youtube.com/*",
    "https://player.vimeo.com/*"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_title": "Open Media Loader",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'"
  }
}
2. background.js
Handles the action when the extension icon is clicked, ensuring only one dashboard tab is open.


chrome.action.onClicked.addListener(() => {
    const dashboardURL = chrome.runtime.getURL("dashboard.html");
    
    // Query for any existing tabs with the dashboard URL
    chrome.tabs.query({ url: dashboardURL }, (tabs) => {
        if (chrome.runtime.lastError) {
            console.error("Tab Query Error:", chrome.runtime.lastError);
            return;
        }

        if (tabs.length > 0) {
            // Activate the first existing dashboard tab
            chrome.tabs.update(tabs[0].id, { active: true }, (updatedTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Update Error:", chrome.runtime.lastError);
                }
            });
        } else {
            // Create a new dashboard tab
            chrome.tabs.create({ url: dashboardURL, active: true }, (newTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Creation Error:", chrome.runtime.lastError);
                }
            });
        }
    });
});
3. dashboard.html
Updated to remove the "Load Audio" and "Load Video" legends and replace "Upload" with "Local" in labels.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Media Loader Dashboard</title>
    <link rel="stylesheet" href="styles.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <main class="container">
        <!-- Header with Settings Button and SyncWave Title -->
        <header class="header">
            <button id="settings-button" class="settings-button" title="Settings" aria-label="Open Settings">
                <img src="icons/settings.svg" alt="Settings" class="settings-icon" aria-hidden="true">
            </button>
            <h1 class="main-title">SyncWave</h1>
        </header>
        
        <!-- Load Audio Section -->
        <section class="section" id="load-music-section">
            <!-- Removed the legend "Load Audio" -->
            
            <fieldset>
                <label for="music-url">Audio URL</label>
                <input type="text" id="music-url" name="music-url" placeholder="Enter YouTube or Vimeo URL">

                <label for="music-file">Local Audio File</label>
                <input type="file" id="music-file" name="music-file" accept="audio/*">

                <label for="music-start">Start Time (seconds)</label>
                <input type="number" id="music-start" name="music-start" placeholder="Start Time (seconds)" min="0">

                <button type="button" id="load-music" class="load-button">Load Audio</button>
            </fieldset>
            <div id="music-player-container" class="player-container"></div>
        </section>

        <!-- Load Video Section -->
        <section class="section" id="load-video-section">
            <!-- Removed the legend "Load Video" -->
            
            <fieldset>
                <label for="video-url">Video URL</label>
                <input type="text" id="video-url" name="video-url" placeholder="Enter YouTube or Vimeo URL">

                <label for="video-file">Local Video File</label>
                <input type="file" id="video-file" name="video-file" accept="video/*">

                <label for="video-start">Start Time (seconds)</label>
                <input type="number" id="video-start" name="video-start" placeholder="Start Time (seconds)" min="0">

                <button type="button" id="load-video" class="load-button">Load Video</button>
            </fieldset>
            <div id="video-player-container" class="player-container"></div>
        </section>

        <!-- Playback Controls -->
        <section class="controls">
            <button type="button" id="play-button" disabled aria-label="Play">Play</button>
            <button type="button" id="pause-resume-button" disabled aria-label="Pause">Pause</button>
            <button type="button" id="play-start-button" disabled aria-label="Play from Start">Play from Start</button>
        </section>

        <!-- Message Container -->
        <section id="message-container" class="message-container" role="alert" aria-live="assertive"></section>

        <!-- Settings Modal (Remains Unchanged) -->
        <div id="settings-modal" class="modal" role="dialog" aria-labelledby="settings-modal-title" aria-modal="true" hidden>
            <div class="modal-content">
                <button class="close-button" aria-label="Close Settings Modal">&times;</button>
                <h2 id="settings-modal-title">Settings</h2>
                <form>
                    <label for="fullscreen-toggle">
                        <input type="checkbox" id="fullscreen-toggle" name="fullscreen-toggle">
                        Full Screen on Play
                    </label>
                    <!-- Additional settings can go here -->
                </form>
            </div>
        </div>
    </main>

    <!-- Your Dashboard JS -->
    <script src="dashboard.js"></script>
</body>
</html>
4. dashboard.js
Removed autoplay=1 from YouTube and Vimeo embed URLs to prevent auto-playing and ensure buffering only. Also increased iframe heights for larger video display.


"use strict";

document.addEventListener('DOMContentLoaded', () => {
    // === Element References ===
    const elements = {
        music: {
            urlInput: document.getElementById('music-url'),
            fileInput: document.getElementById('music-file'),
            startInput: document.getElementById('music-start'),
            loadButton: document.getElementById('load-music'),
            playerContainer: document.getElementById('music-player-container')
        },
        video: {
            urlInput: document.getElementById('video-url'),
            fileInput: document.getElementById('video-file'),
            startInput: document.getElementById('video-start'),
            loadButton: document.getElementById('load-video'),
            playerContainer: document.getElementById('video-player-container')
        },
        controls: {
            playButton: document.getElementById('play-button'),
            pauseResumeButton: document.getElementById('pause-resume-button'),
            playStartButton: document.getElementById('play-start-button')
        },
        messageContainer: document.getElementById('message-container'),
        settings: {
            button: document.getElementById('settings-button'),
            modal: document.getElementById('settings-modal'),
            closeButton: document.querySelector('.close-button'),
            fullscreenToggle: document.getElementById('fullscreen-toggle')
        }
    };

    // === State Management ===
    const state = {
        music: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLAudioElement | HTMLIFrameElement, start: Number }
        video: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLVideoElement | HTMLIFrameElement, start: Number }
        isPaused: false,
        fullscreenOnPlay: false
    };

    // === Utility Functions ===

    /**
     * Formats seconds into 'XmYs' (e.g., 125 seconds -> '2m5s')
     * @param {number} seconds - The time in seconds.
     * @returns {string} Formatted time string.
     */
    function formatTime(seconds) {
        if (isNaN(seconds) || seconds < 0) return '';
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = seconds % 60;
        return `${minutes}m${remainingSeconds}s`;
    }

    /**
     * Capitalize the first letter of a string.
     * @param {string} text - The string to capitalize.
     * @returns {string} Capitalized string.
     */
    function capitalize(text) {
        if (!text) return '';
        return text.charAt(0).toUpperCase() + text.slice(1);
    }

    /**
     * Displays a message to the user.
     * @param {string} message - The message to display.
     * @param {string} type - The type of message ('success', 'error', 'info').
     */
    function showMessage(message, type) {
        elements.messageContainer.innerHTML = '';
        const msgDiv = document.createElement('div');
        msgDiv.textContent = message;
        msgDiv.classList.add('message', type); // 'success', 'error', 'info'
        elements.messageContainer.appendChild(msgDiv);

        // Automatically hide message after 5 seconds
        setTimeout(() => {
            if (elements.messageContainer.contains(msgDiv)) {
                elements.messageContainer.removeChild(msgDiv);
            }
        }, 5000);
    }

    /**
     * Shows a loading spinner in the specified container.
     * @param {HTMLElement} container - The container to show the loader in.
     */
    function showLoading(container) {
        container.innerHTML = '';
        const loader = document.createElement('div');
        loader.classList.add('loader'); // Define loader styles in CSS
        container.appendChild(loader);
    }

    /**
     * Hides the loading spinner from the specified container.
     * @param {HTMLElement} container - The container to hide the loader from.
     */
    function hideLoading(container) {
        const loader = container.querySelector('.loader');
        if (loader) {
            container.removeChild(loader);
        }
    }

    /**
     * Traps keyboard focus within a specified element.
     * @param {HTMLElement} element - The element to trap focus within.
     */
    function trapFocus(element) {
        const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]),' +
            ' textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"],' +
            ' [contenteditable]';
        const focusableElements = element.querySelectorAll(focusableElementsString);
        const firstTabStop = focusableElements[0];
        const lastTabStop = focusableElements[focusableElements.length - 1];

        // Listen for and trap the keyboard
        element.addEventListener('keydown', trapTabKey);

        function trapTabKey(e) {
            // Check for TAB key press
            if (e.key === 'Tab') {
                // SHIFT + TAB
                if (e.shiftKey) {
                    if (document.activeElement === firstTabStop) {
                        e.preventDefault();
                        lastTabStop.focus();
                    }
                } else { // TAB
                    if (document.activeElement === lastTabStop) {
                        e.preventDefault();
                        firstTabStop.focus();
                    }
                }
            }
        }

        // Remove trap when modal is closed
        function removeTrapKey(e) {
            element.removeEventListener('keydown', trapTabKey);
        }

        // Store the function reference to remove it later
        element.removeTrapKey = removeTrapKey;
    }

    function removeTrapFocus() {
        if (elements.settings.modal.removeTrapKey) {
            elements.settings.modal.removeTrapKey();
        }
    }

    // === Initialization ===
    loadSettings();

    // === Event Listeners ===
    elements.music.loadButton.addEventListener('click', handleLoadMusic);
    elements.video.loadButton.addEventListener('click', handleLoadVideo);
    elements.controls.playButton.addEventListener('click', handlePlay);
    elements.controls.pauseResumeButton.addEventListener('click', handlePauseResume);
    elements.controls.playStartButton.addEventListener('click', handlePlayFromStart);

    // Settings Modal Event Listeners
    elements.settings.button.addEventListener('click', openSettingsModal);
    elements.settings.closeButton.addEventListener('click', closeSettingsModal);
    window.addEventListener('click', (event) => {
        if (event.target === elements.settings.modal) {
            closeSettingsModal();
        }
    });
    document.addEventListener('keydown', (event) => {
        if (event.key === 'Escape' && !elements.settings.modal.hasAttribute('hidden')) {
            closeSettingsModal();
        }
    });
    elements.settings.fullscreenToggle.addEventListener('change', (event) => {
        state.fullscreenOnPlay = event.target.checked;
        saveSettings();
    });

    // === Handler Functions ===

    // Load Music Handler
    function handleLoadMusic() {
        const url = elements.music.urlInput.value.trim();
        const file = elements.music.fileInput.files[0];
        const start = parseInt(elements.music.startInput.value) || 0;

        // Show loading indicator
        showLoading(elements.music.playerContainer);

        // Unload existing music if any
        if (state.music) {
            unloadMedia('music');
        }

        if (file) {
            if (file.size > 10 * 1024 * 1024) { // 10MB limit
                showMessage('Audio file size exceeds 10MB limit.', 'error');
                hideLoading(elements.music.playerContainer);
                return;
            }

            // Handle local audio file
            const fileUrl = URL.createObjectURL(file);
            const audioElement = document.createElement('audio');
            audioElement.controls = true;
            audioElement.src = fileUrl;
            audioElement.id = 'loaded-music';
            audioElement.setAttribute('aria-label', 'Loaded Audio Player');
            audioElement.style.width = '100%';
            audioElement.style.height = 'auto';
            elements.music.playerContainer.innerHTML = '';
            elements.music.playerContainer.appendChild(audioElement);

            // Set start time if applicable
            if (start > 0) {
                audioElement.currentTime = start;
            }

            state.music = {
                type: 'file',
                element: audioElement,
                start: start
            };
            showMessage('Local audio file loaded.', 'success');
            hideLoading(elements.music.playerContainer);
        } else if (url && isValidMediaURL(url)) {
            const mediaInfo = extractMediaInfo(url);
            if (mediaInfo) {
                if (mediaInfo.platform === 'youtube') {
                    embedYouTubeIframe(mediaInfo.id, start, 'music');
                } else if (mediaInfo.platform === 'vimeo') {
                    embedVimeoIframe(mediaInfo.id, start, 'music');
                }
                showMessage(`Loaded ${capitalize(mediaInfo.platform)} audio.`, 'success');
                hideLoading(elements.music.playerContainer);
            } else {
                showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
                hideLoading(elements.music.playerContainer);
            }
        } else {
            showMessage('Please enter a URL or select an audio file.', 'error');
            hideLoading(elements.music.playerContainer);
        }

        checkReadyToPlay();
        saveSettings();
    }

    // Load Video Handler
    function handleLoadVideo() {
        const url = elements.video.urlInput.value.trim();
        const file = elements.video.fileInput.files[0];
        const start = parseInt(elements.video.startInput.value) || 0;

        // Show loading indicator
        showLoading(elements.video.playerContainer);

        // Unload existing video if any
        if (state.video) {
            unloadMedia('video');
        }

        if (file) {
            if (file.size > 50 * 1024 * 1024) { // 50MB limit
                showMessage('Video file size exceeds 50MB limit.', 'error');
                hideLoading(elements.video.playerContainer);
                return;
            }

            // Handle local video file
            const fileUrl = URL.createObjectURL(file);
            const videoElement = document.createElement('video');
            videoElement.controls = true;
            videoElement.src = fileUrl;
            videoElement.id = 'loaded-video';
            videoElement.setAttribute('aria-label', 'Loaded Video Player');
            videoElement.style.width = '100%';
            videoElement.style.height = 'auto';
            elements.video.playerContainer.innerHTML = '';
            elements.video.playerContainer.appendChild(videoElement);

            // Set start time if applicable
            if (start > 0) {
                videoElement.currentTime = start;
            }

            state.video = {
                type: 'file',
                element: videoElement,
                start: start
            };
            showMessage('Local video file loaded.', 'success');
            hideLoading(elements.video.playerContainer);
        } else if (url && isValidMediaURL(url)) {
            const mediaInfo = extractMediaInfo(url);
            if (mediaInfo) {
                if (mediaInfo.platform === 'youtube') {
                    embedYouTubeIframe(mediaInfo.id, start, 'video');
                } else if (mediaInfo.platform === 'vimeo') {
                    embedVimeoIframe(mediaInfo.id, start, 'video');
                }
                showMessage(`Loaded ${capitalize(mediaInfo.platform)} video.`, 'success');
                hideLoading(elements.video.playerContainer);
            } else {
                showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
                hideLoading(elements.video.playerContainer);
            }
        } else {
            showMessage('Please enter a URL or select a video file.', 'error');
            hideLoading(elements.video.playerContainer);
        }

        checkReadyToPlay();
        saveSettings();
    }

    // Play Handler
    function handlePlay() {
        // Play Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.music.element);
                }
            } else {
                // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
                showMessage('Cannot control external media playback programmatically.', 'info');
            }
        }

        // Play Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.video.element);
                }
            } else {
                // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
                showMessage('Cannot control external media playback programmatically.', 'info');
            }
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback started!', 'success');
    }

    // Pause/Resume Handler
    function handlePauseResume() {
        if (state.isPaused) {
            resumeMedia();
        } else {
            pauseMedia();
        }
    }

    // Pause Media
    function pauseMedia() {
        // Pause Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.pause();
            } else {
                // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
                showMessage('Cannot pause external media playback programmatically.', 'info');
            }
        }

        // Pause Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.pause();
            } else {
                // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
                showMessage('Cannot pause external media playback programmatically.', 'info');
            }
        }

        state.isPaused = true;
        elements.controls.pauseResumeButton.textContent = 'Resume';
        showMessage('Playback paused.', 'info');
    }

    // Resume Media
    function resumeMedia() {
        // Resume Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.play();
            } else {
                // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
                showMessage('Cannot resume external media playback programmatically.', 'info');
            }
        }

        // Resume Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.play();
            } else {
                // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
                showMessage('Cannot resume external media playback programmatically.', 'info');
            }
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback resumed.', 'success');
    }

    // Play From Start Handler
    function handlePlayFromStart() {
        // Play from Start Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.currentTime = state.music.start;
                state.music.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.music.element);
                }
            } else {
                // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
                showMessage('Cannot control external media playback programmatically.', 'info');
            }
        }

        // Play from Start Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.currentTime = state.video.start;
                state.video.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.video.element);
                }
            } else {
                // Embedded iframes (YouTube/Vimeo) cannot be programmatically controlled without APIs
                showMessage('Cannot control external media playback programmatically.', 'info');
            }
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback restarted!', 'success');
    }

    // === Settings Modal Functions ===
    function openSettingsModal() {
        elements.settings.modal.removeAttribute('hidden');
        elements.settings.modal.setAttribute('aria-hidden', 'false');
        elements.settings.modal.querySelector('.close-button').focus();
        trapFocus(elements.settings.modal);
    }

    function closeSettingsModal() {
        elements.settings.modal.setAttribute('hidden', '');
        elements.settings.modal.setAttribute('aria-hidden', 'true');
        elements.settings.button.focus();
        removeTrapFocus();
    }

    // === Media Embedding Functions ===

    /**
     * Embeds a YouTube video into the specified container using an iframe.
     * Mutes the video and starts at the specified time without autoplay.
     * @param {string} videoId - The YouTube video ID.
     * @param {number} start - The start time in seconds.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function embedYouTubeIframe(videoId, start, mediaType) {
        const container = elements[mediaType].playerContainer;
        container.innerHTML = ''; // Clear previous content

        let src = `https://www.youtube.com/embed/${videoId}?mute=1&start=${start}&controls=1&rel=0`;
        // Note: autoplay=1 removed to prevent auto-play

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.width = '100%';
        iframe.height = '720'; // Increased height
        iframe.frameBorder = '0';
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';

        iframe.setAttribute('title', 'YouTube video player');

        container.appendChild(iframe);

        state[mediaType] = {
            type: 'youtube',
            element: iframe,
            start: start
        };
    }

    /**
     * Embeds a Vimeo video into the specified container using an iframe.
     * Mutes the video and starts at the specified time without autoplay.
     * @param {string} videoId - The Vimeo video ID.
     * @param {number} start - The start time in seconds.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function embedVimeoIframe(videoId, start, mediaType) {
        const container = elements[mediaType].playerContainer;
        container.innerHTML = ''; // Clear previous content

        let src = `https://player.vimeo.com/video/${videoId}?muted=1#t=${start}s`;
        // Note: autoplay=1 removed to prevent auto-play

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.width = '100%';
        iframe.height = '720'; // Increased height
        iframe.frameBorder = '0';
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';

        iframe.setAttribute('title', 'Vimeo video player');

        container.appendChild(iframe);

        state[mediaType] = {
            type: 'vimeo',
            element: iframe,
            start: start
        };
    }

    // === Settings Management ===

    /**
     * Loads settings from Chrome storage.
     */
    function loadSettings() {
        try {
            chrome.storage.local.get(['mediaSettings'], (result) => {
                if (chrome.runtime.lastError) {
                    throw new Error(chrome.runtime.lastError);
                }

                if (result.mediaSettings) {
                    const { music, video, fullscreenOnPlay: fsPlay } = result.mediaSettings;

                    if (music) {
                        if (music.type === 'youtube' 
                            || music.type === 'vimeo') {
                            const url = music.type === 'youtube' 
                                ? `https://www.youtube.com/watch?v=${music.id}` 
                                : `https://vimeo.com/${music.id}`;
                            elements.music.urlInput.value = url;
                            elements.music.startInput.value = music.start || 0;
                            // Optionally, auto-load the media by triggering the load button
                            // handleLoadMusic();
                        }
                        // Handle file-based music loading if necessary
                    }

                    if (video) {
                        if (video.type === 'youtube' 
                            || video.type === 'vimeo') {
                            const url = video.type === 'youtube' 
                                ? `https://www.youtube.com/watch?v=${video.id}` 
                                : `https://vimeo.com/${video.id}`;
                            elements.video.urlInput.value = url;
                            elements.video.startInput.value = video.start || 0;
                            // Optionally, auto-load the media by triggering the load button
                            // handleLoadVideo();
                        }
                        // Handle file-based video loading if necessary
                    }

                    if (typeof fsPlay === 'boolean') {
                        state.fullscreenOnPlay = fsPlay;
                        elements.settings.fullscreenToggle.checked = fsPlay;
                    }
                }
            });
        } catch (error) {
            console.error('Error loading settings:', error);
            showMessage('Failed to load settings.', 'error');
        }
    }

    /**
     * Saves settings to Chrome storage.
     */
    function saveSettings() {
        const settings = {
            music: state.music,
            video: state.video,
            fullscreenOnPlay: state.fullscreenOnPlay
        };
        try {
            chrome.storage.local.set({ mediaSettings: settings }, () => {
                if (chrome.runtime.lastError) {
                    throw new Error(chrome.runtime.lastError);
                }
                console.log('Settings saved.');
            });
        } catch (error) {
            console.error('Error saving settings:', error);
            showMessage('Error saving settings.', 'error');
        }
    }

    /**
     * Unloads media from the specified type.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function unloadMedia(mediaType) {
        if (state[mediaType]) {
            if (state[mediaType].type === 'file') {
                if (state[mediaType].element.src) {
                    URL.revokeObjectURL(state[mediaType].element.src);
                    state[mediaType].element.src = '';
                    state[mediaType].element.remove();
                }
            } else if (state[mediaType].type === 'youtube' 
                || state[mediaType].type === 'vimeo') {
                const iframe = state[mediaType].element;
                iframe.src = ''; // Reset iframe src to stop the media
            }
            state[mediaType] = null;
        }
    }

    // === Playback Controls ===

    /**
     * Enables or disables playback controls based on media loading state.
     */
    function checkReadyToPlay() {
        // Enable Play button only when at least one of audio or video is loaded
        const readyAudio = state.music 
            && (state.music.type === 'file' 
                || state.music.type === 'youtube' 
                || state.music.type === 'vimeo');
        const readyVideo = state.video 
            && (state.video.type === 'file' 
                || state.video.type === 'youtube' 
                || state.video.type === 'vimeo');
        const ready = readyAudio || readyVideo;

        elements.controls.playButton.disabled = !ready;
        elements.controls.pauseResumeButton.disabled = !ready;
        elements.controls.playStartButton.disabled = !ready;
    }

    /**
     * Enters fullscreen mode for the specified element.
     * @param {HTMLElement} element - The element to enter fullscreen.
     */
    function enterFullscreen(element) {
        if (element && element.requestFullscreen) {
            element.requestFullscreen().then(() => {
                showMessage('Entered fullscreen mode.', 'success');
            }).catch(err => {
                console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
                showMessage('Failed to enter fullscreen mode.', 'error');
            });
        } else {
            showMessage('Fullscreen not supported on this element.', 'error');
        }
    }

    // === New Utility Functions ===

    /**
     * Validates whether the URL is a valid YouTube or Vimeo URL.
     * @param {string} url - The URL to validate.
     * @returns {boolean} True if valid, else false.
     */
    function isValidMediaURL(url) {
        try {
            const parsedUrl = new URL(url);
            const hostname = parsedUrl.hostname.toLowerCase();
            const pathname = parsedUrl.pathname;

            // YouTube RegEx Patterns
            const youtubeRegex = /^(?:\/watch\/?|\/embed\/|\/v\/)?([a-zA-Z0-9_-]{11})$/;
            // Vimeo RegEx Patterns
            const vimeoRegex = /^\/(?:video\/)?(\d+)$/;

            if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
                // Extract YouTube video ID
                let videoId = '';
                if (hostname === 'youtu.be') {
                    videoId = pathname.slice(1);
                } else {
                    videoId = parsedUrl.searchParams.get('v') || '';
                }
                return youtubeRegex.test(`/${videoId}`);
            } else if (hostname.includes('vimeo.com')) {
                // Extract Vimeo video ID
                const match = pathname.match(vimeoRegex);
                return match && match[1].length > 0;
            }

            return false;
        } catch (e) {
            return false;
        }
    }

    /**
     * Extracts media information from the URL.
     * @param {string} url - The media URL.
     * @returns {Object|null} An object with platform and id, or null if invalid.
     */
    function extractMediaInfo(url) {
        try {
            const parsedUrl = new URL(url);
            const hostname = parsedUrl.hostname.toLowerCase();
            const pathname = parsedUrl.pathname;

            // YouTube Patterns
            if (hostname.includes('youtube.com') 
                || hostname === 'youtu.be') {
                let videoId = '';
                if (hostname === 'youtu.be') {
                    videoId = pathname.slice(1);
                } else {
                    videoId = parsedUrl.searchParams.get('v') || '';
                }

                // Validate videoId length
                if (videoId.length === 11) {
                    return { platform: 'youtube', id: videoId };
                }
            }

            // Vimeo Patterns
            if (hostname.includes('vimeo.com')) {
                const vimeoMatch = pathname.match(/^\/(?:video\/)?(\d+)$/);
                if (vimeoMatch && vimeoMatch[1]) {
                    return { platform: 'vimeo', id: vimeoMatch[1] };
                }
            }

            return null;
        } catch (e) {
            return null;
        }
    }
});
Key Changes:

Prevent Auto-Play: Removed autoplay=1 from both YouTube and Vimeo iframe URLs to ensure media doesn't auto-play but only buffers.
YouTube Embed URL Changed From:

https://www.youtube.com/embed/${videoId}?autoplay=1&mute=1&start=${start}&controls=1&rel=0
To:

https://www.youtube.com/embed/${videoId}?mute=1&start=${start}&controls=1&rel=0
Vimeo Embed URL Changed From:

https://player.vimeo.com/video/${videoId}?autoplay=1&muted=1#t=${start}s
To:

https://player.vimeo.com/video/${videoId}?muted=1#t=${start}s
Increased Player Size: Changed the iframe heights from 360 to 720 pixels for larger video displays.
5. styles.css
Updated the maximum height for video and audio players to display larger content.


/* General Styles */
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px;
    max-width: 800px;
    margin: 0 auto;
}

.section {
    width: 100%;
    margin-bottom: 20px;
    background-color: #fff;
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* Header with Settings Button and Main Title */
.header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center; /* Center the content */
    margin-bottom: 20px;
    position: relative;
}

.settings-button {
    position: absolute;
    left: 0;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 5px;
    cursor: pointer;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

.settings-button:hover {
    background-color: #f0f0f0;
    border-color: #999;
}

.settings-icon {
    width: 20px;
    height: 20px;
}

.main-title {
    font-size: 2em;
    font-weight: bold;
    margin: 0;
    opacity: 0;
    animation: fadeInShake 5s forwards;
}

@keyframes fadeInShake {
    0% {
        opacity: 0;
        transform: translateX(0);
        color: #FF0000; /* Red */
    }
    10% {
        opacity: 0.2;
        transform: translateX(-10px);
        color: #FF7F00; /* Orange */
    }
    20% {
        opacity: 0.4;
        transform: translateX(10px);
        color: #FFFF00; /* Yellow */
    }
    30% {
        opacity: 0.6;
        transform: translateX(-10px);
        color: #00FF00; /* Green */
    }
    40% {
        opacity: 0.7;
        transform: translateX(10px);
        color: #0000FF; /* Blue */
    }
    50% {
        opacity: 0.8;
        transform: translateX(-10px);
        color: #4B0082; /* Indigo */
    }
    60% {
        opacity: 0.85;
        transform: translateX(10px);
        color: #8B00FF; /* Violet */
    }
    70% {
        opacity: 0.9;
        transform: translateX(-10px);
        color: #FF00FF; /* Magenta */
    }
    80% {
        opacity: 0.95;
        transform: translateX(10px);
        color: #000000; /* Black */
    }
    100% {
        opacity: 1;
        transform: translateX(0);
        color: #000000; /* Black */
    }
}

/* Section Header */
.section-header {
    display: flex;
    align-items: center;
    margin-bottom: 10px;
}

.section-header legend {
    font-size: 1.2em;
    font-weight: bold;
    margin: 0;
}

/* Controls */
.controls {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.controls button {
    padding: 10px 20px;
    cursor: pointer;
    border: none;
    border-radius: 5px;
    background-color: #4285f4;
    color: #fff;
    transition: background-color 0.3s ease;
}

.controls button:disabled {
    background-color: #a0c3ff;
    cursor: not-allowed;
}

.controls button:hover:not(:disabled) {
    background-color: #357ae8;
}

/* Modal Styles */
.modal[hidden] {
    display: none;
}

.modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex; /* Visible when not hidden */
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.modal-content {
    background-color: #fff;
    padding: 20px 30px;
    border-radius: 8px;
    width: 90%;
    max-width: 400px;
    position: relative;
}

.close-button {
    position: absolute;
    top: 10px;
    right: 15px;
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
}

.modal-content h2 {
    margin-top: 0;
}

/* Form Elements */
fieldset {
    border: none;
    padding: 0;
}

fieldset label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

fieldset input[type="text"],
fieldset input[type="number"],
fieldset input[type="file"] {
    width: 100%;
    padding: 8px;
    margin-bottom: 15px;
    box-sizing: border-box;
    border: 1px solid #ccc;
    border-radius: 4px;
}

fieldset .load-button {
    width: 100%;
    padding: 10px;
    background-color: #34a853;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

fieldset .load-button:hover {
    background-color: #2c8e46;
}

/* Player Containers */
.player-container {
    margin-top: 10px;
    width: 100%;
    max-width: 100%;
    min-height: 50px;
    box-sizing: border-box;
    overflow: hidden; /* Prevent overflow */
}

/* Responsive Video and Audio Elements */
.player-container video,
.player-container iframe {
    width: 100%;
    height: auto;
    max-height: 720px; /* Increased from 360px to 720px */
    border-radius: 8px;
    /* Ensure the iframe fills the container */
    display: block;
}

/* Messages */
.message-container {
    margin-top: 20px;
    width: 100%;
}

.message {
    padding: 10px;
    border-radius: 5px;
    margin-bottom: 10px;
    color: #fff;
}

.message.success {
    background-color: #4caf50;
}

.message.error {
    background-color: #f44336;
}

.message.info {
    background-color: #2196f3;
}

/* Loader */
.loader {
    border: 8px solid #f3f3f3; /* Light grey */
    border-top: 8px solid #4285f4; /* Blue */
    border-radius: 50%;
    width: 40px;
    height: 40px;
    animation: spin 1s linear infinite;
    margin: 0 auto;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Responsive Design */
@media (max-width: 600px) {
    .container {
        padding: 10px;
    }

    .modal-content {
        padding: 15px 20px;
    }

    .controls {
        flex-direction: column;
        width: 100%;
    }

    .controls button {
        width: 100%;
    }

    .settings-container {
        /* Removed absolute positioning */
    }

    .settings-button {
        width: 35px;
        height: 35px;
    }

    .settings-icon {
        width: 18px;
        height: 18px;
    }

    .main-title {
        font-size: 1.5em;
    }
}
Key Changes:

Increased Player Size: Changed the max-height for both <video> and <iframe> elements from 360px to 720px to display larger videos.

.player-container video,
.player-container iframe {
    width: 100%;
    height: auto;
    max-height: 720px; /* Increased from 360px to 720px */
    border-radius: 8px;
    /* Ensure the iframe fills the container */
    display: block;
}
Removed Legends: The legends such as <legend>Load Audio</legend> and <legend>Load Video</legend> were removed from dashboard.html to eliminate "Load Audio" and "Load Video" texts outside the buttons.
Replaced "Upload" with "Local": Updated labels in dashboard.html to replace "Upload Audio File" with "Local Audio File" and "Upload Video File" with "Local Video File."
Summary of Changes
Player Size Increased: The video and audio players now have a max-height of 720px instead of 360px, providing a larger display area for media content.
Auto-Play Disabled: Removed autoplay=1 from both YouTube and Vimeo embed URLs to ensure that media does not auto-play. Files will now only buffer, allowing users to initiate playback manually.
Label Updates: Changed all instances of "Upload" to "Local" in the labels to better reflect the functionality.
Removed Unnecessary Texts: Eliminated the "Load Audio" and "Load Video" texts that were outside of the action buttons to streamline the interface.
Additional Enhancements:
Maintained responsive design for various screen sizes.
Ensured that the extension remains accessible with appropriate ARIA labels and focus management.
Please replace your existing files with the updated versions above. Ensure that all file paths (like icons and scripts) are correctly referenced in your project structure. After making these changes, reload your Chrome extension to see the updates in action.

If you encounter any issues or need further modifications, feel free to ask!


the videos loaded with a vimeo url are still to small. they didnt play when play button was pressed. they didnt start buffering when load button was pressed.


Apologies for the inconvenience you're experiencing. Let's address the issues one by one:

Vimeo Videos Too Small
Play Button Not Functioning
Failed Buffering on Load
To resolve these, we'll need to make the following updates:

Increase the Size of Vimeo Videos: Adjust the iframe dimensions and ensure responsive design.
Enable Play Button Functionality: Integrate Vimeo's Player API to allow programmatic control.
Ensure Buffering on Load: Properly initialize the Vimeo player without autoplay to allow buffering.
Additionally, we'll need to update the manifest.json to accommodate the Vimeo Player API's script source.

Updated Files
1. manifest.json
Changes:

Updated the content_security_policy to allow scripts from https://player.vimeo.com.

{
  "manifest_version": 3,
  "name": "Media Loader",
  "version": "1.0",
  "description": "Load and play music and videos from YouTube and Vimeo",
  "permissions": ["storage", "tabs"],
  "host_permissions": [
    "https://www.youtube.com/*",
    "https://player.vimeo.com/*"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_title": "Open Media Loader",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self' https://player.vimeo.com; object-src 'self'"
  }
}
2. dashboard.html
Changes:

Included Vimeo's Player API script.
Removed legends for "Load Audio" and "Load Video".
Replaced "Upload" with "Local" in labels.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Media Loader Dashboard</title>
    <link rel="stylesheet" href="styles.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <main class="container">
        <!-- Header with Settings Button and SyncWave Title -->
        <header class="header">
            <button id="settings-button" class="settings-button" title="Settings" aria-label="Open Settings">
                <img src="icons/settings.svg" alt="Settings" class="settings-icon" aria-hidden="true">
            </button>
            <h1 class="main-title">SyncWave</h1>
        </header>
        
        <!-- Load Audio Section -->
        <section class="section" id="load-music-section">
            <fieldset>
                <label for="music-url">Audio URL</label>
                <input type="text" id="music-url" name="music-url" placeholder="Enter YouTube or Vimeo URL">

                <label for="music-file">Local Audio File</label>
                <input type="file" id="music-file" name="music-file" accept="audio/*">

                <label for="music-start">Start Time (seconds)</label>
                <input type="number" id="music-start" name="music-start" placeholder="Start Time (seconds)" min="0">

                <button type="button" id="load-music" class="load-button">Load</button>
            </fieldset>
            <div id="music-player-container" class="player-container"></div>
        </section>

        <!-- Load Video Section -->
        <section class="section" id="load-video-section">
            <fieldset>
                <label for="video-url">Video URL</label>
                <input type="text" id="video-url" name="video-url" placeholder="Enter YouTube or Vimeo URL">

                <label for="video-file">Local Video File</label>
                <input type="file" id="video-file" name="video-file" accept="video/*">

                <label for="video-start">Start Time (seconds)</label>
                <input type="number" id="video-start" name="video-start" placeholder="Start Time (seconds)" min="0">

                <button type="button" id="load-video" class="load-button">Load</button>
            </fieldset>
            <div id="video-player-container" class="player-container"></div>
        </section>

        <!-- Playback Controls -->
        <section class="controls">
            <button type="button" id="play-button" disabled aria-label="Play">Play</button>
            <button type="button" id="pause-resume-button" disabled aria-label="Pause">Pause</button>
            <button type="button" id="play-start-button" disabled aria-label="Play from Start">Play from Start</button>
        </section>

        <!-- Message Container -->
        <section id="message-container" class="message-container" role="alert" aria-live="assertive"></section>

        <!-- Settings Modal (Remains Unchanged) -->
        <div id="settings-modal" class="modal" role="dialog" aria-labelledby="settings-modal-title" aria-modal="true" hidden>
            <div class="modal-content">
                <button class="close-button" aria-label="Close Settings Modal">&times;</button>
                <h2 id="settings-modal-title">Settings</h2>
                <form>
                    <label for="fullscreen-toggle">
                        <input type="checkbox" id="fullscreen-toggle" name="fullscreen-toggle">
                        Full Screen on Play
                    </label>
                    <!-- Additional settings can go here -->
                </form>
            </div>
        </div>
    </main>

    <!-- Vimeo Player API -->
    <script src="https://player.vimeo.com/api/player.js"></script>
    
    <!-- Your Dashboard JS -->
    <script src="dashboard.js"></script>
</body>
</html>
3. dashboard.js
Changes:

Integrated Vimeo's Player API for better control.
Increased iframe height for larger video display.
Modified load and play functions to interact with the Vimeo Player.
Ensured proper buffering without autoplay.

"use strict";

document.addEventListener('DOMContentLoaded', () => {
    // === Element References ===
    const elements = {
        music: {
            urlInput: document.getElementById('music-url'),
            fileInput: document.getElementById('music-file'),
            startInput: document.getElementById('music-start'),
            loadButton: document.getElementById('load-music'),
            playerContainer: document.getElementById('music-player-container')
        },
        video: {
            urlInput: document.getElementById('video-url'),
            fileInput: document.getElementById('video-file'),
            startInput: document.getElementById('video-start'),
            loadButton: document.getElementById('load-video'),
            playerContainer: document.getElementById('video-player-container')
        },
        controls: {
            playButton: document.getElementById('play-button'),
            pauseResumeButton: document.getElementById('pause-resume-button'),
            playStartButton: document.getElementById('play-start-button')
        },
        messageContainer: document.getElementById('message-container'),
        settings: {
            button: document.getElementById('settings-button'),
            modal: document.getElementById('settings-modal'),
            closeButton: document.querySelector('.close-button'),
            fullscreenToggle: document.getElementById('fullscreen-toggle')
        }
    };

    // === State Management ===
    const state = {
        music: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLAudioElement | Player, start: Number }
        video: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLVideoElement | Player, start: Number }
        isPaused: false,
        fullscreenOnPlay: false
    };

    // === Utility Functions ===

    /**
     * Formats seconds into 'XmYs' (e.g., 125 seconds -> '2m5s')
     * @param {number} seconds - The time in seconds.
     * @returns {string} Formatted time string.
     */
    function formatTime(seconds) {
        if (isNaN(seconds) || seconds < 0) return '';
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = seconds % 60;
        return `${minutes}m${remainingSeconds}s`;
    }

    /**
     * Capitalize the first letter of a string.
     * @param {string} text - The string to capitalize.
     * @returns {string} Capitalized string.
     */
    function capitalize(text) {
        if (!text) return '';
        return text.charAt(0).toUpperCase() + text.slice(1);
    }

    /**
     * Displays a message to the user.
     * @param {string} message - The message to display.
     * @param {string} type - The type of message ('success', 'error', 'info').
     */
    function showMessage(message, type) {
        elements.messageContainer.innerHTML = '';
        const msgDiv = document.createElement('div');
        msgDiv.textContent = message;
        msgDiv.classList.add('message', type); // 'success', 'error', 'info'
        elements.messageContainer.appendChild(msgDiv);

        // Automatically hide message after 5 seconds
        setTimeout(() => {
            if (elements.messageContainer.contains(msgDiv)) {
                elements.messageContainer.removeChild(msgDiv);
            }
        }, 5000);
    }

    /**
     * Shows a loading spinner in the specified container.
     * @param {HTMLElement} container - The container to show the loader in.
     */
    function showLoading(container) {
        container.innerHTML = '';
        const loader = document.createElement('div');
        loader.classList.add('loader'); // Define loader styles in CSS
        container.appendChild(loader);
    }

    /**
     * Hides the loading spinner from the specified container.
     * @param {HTMLElement} container - The container to hide the loader from.
     */
    function hideLoading(container) {
        const loader = container.querySelector('.loader');
        if (loader) {
            container.removeChild(loader);
        }
    }

    /**
     * Traps keyboard focus within a specified element.
     * @param {HTMLElement} element - The element to trap focus within.
     */
    function trapFocus(element) {
        const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]),' +
            ' textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"],' +
            ' [contenteditable]';
        const focusableElements = element.querySelectorAll(focusableElementsString);
        const firstTabStop = focusableElements[0];
        const lastTabStop = focusableElements[focusableElements.length - 1];

        // Listen for and trap the keyboard
        element.addEventListener('keydown', trapTabKey);

        function trapTabKey(e) {
            // Check for TAB key press
            if (e.key === 'Tab') {
                // SHIFT + TAB
                if (e.shiftKey) {
                    if (document.activeElement === firstTabStop) {
                        e.preventDefault();
                        lastTabStop.focus();
                    }
                } else { // TAB
                    if (document.activeElement === lastTabStop) {
                        e.preventDefault();
                        firstTabStop.focus();
                    }
                }
            }
        }

        // Remove trap when modal is closed
        function removeTrapKey(e) {
            element.removeEventListener('keydown', trapTabKey);
        }

        // Store the function reference to remove it later
        element.removeTrapKey = removeTrapKey;
    }

    function removeTrapFocus() {
        if (elements.settings.modal.removeTrapKey) {
            elements.settings.modal.removeTrapKey();
        }
    }

    // === Initialization ===
    loadSettings();

    // === Event Listeners ===
    elements.music.loadButton.addEventListener('click', handleLoadMusic);
    elements.video.loadButton.addEventListener('click', handleLoadVideo);
    elements.controls.playButton.addEventListener('click', handlePlay);
    elements.controls.pauseResumeButton.addEventListener('click', handlePauseResume);
    elements.controls.playStartButton.addEventListener('click', handlePlayFromStart);

    // Settings Modal Event Listeners
    elements.settings.button.addEventListener('click', openSettingsModal);
    elements.settings.closeButton.addEventListener('click', closeSettingsModal);
    window.addEventListener('click', (event) => {
        if (event.target === elements.settings.modal) {
            closeSettingsModal();
        }
    });
    document.addEventListener('keydown', (event) => {
        if (event.key === 'Escape' && !elements.settings.modal.hasAttribute('hidden')) {
            closeSettingsModal();
        }
    });
    elements.settings.fullscreenToggle.addEventListener('change', (event) => {
        state.fullscreenOnPlay = event.target.checked;
        saveSettings();
    });

    // === Handler Functions ===

    // Load Music Handler
    function handleLoadMusic() {
        const url = elements.music.urlInput.value.trim();
        const file = elements.music.fileInput.files[0];
        const start = parseInt(elements.music.startInput.value) || 0;

        // Show loading indicator
        showLoading(elements.music.playerContainer);

        // Unload existing music if any
        if (state.music) {
            unloadMedia('music');
        }

        if (file) {
            if (file.size > 10 * 1024 * 1024) { // 10MB limit
                showMessage('Audio file size exceeds 10MB limit.', 'error');
                hideLoading(elements.music.playerContainer);
                return;
            }

            // Handle local audio file
            const fileUrl = URL.createObjectURL(file);
            const audioElement = document.createElement('audio');
            audioElement.controls = true;
            audioElement.src = fileUrl;
            audioElement.id = 'loaded-music';
            audioElement.setAttribute('aria-label', 'Loaded Audio Player');
            audioElement.style.width = '100%';
            audioElement.style.height = 'auto';
            elements.music.playerContainer.innerHTML = '';
            elements.music.playerContainer.appendChild(audioElement);

            // Set start time if applicable
            if (start > 0) {
                audioElement.currentTime = start;
            }

            state.music = {
                type: 'file',
                element: audioElement,
                start: start
            };
            showMessage('Local audio file loaded.', 'success');
            hideLoading(elements.music.playerContainer);
        } else if (url && isValidMediaURL(url)) {
            const mediaInfo = extractMediaInfo(url);
            if (mediaInfo) {
                if (mediaInfo.platform === 'youtube') {
                    embedYouTubeIframe(mediaInfo.id, start, 'music');
                } else if (mediaInfo.platform === 'vimeo') {
                    embedVimeoPlayer(mediaInfo.id, start, 'music');
                }
                showMessage(`Loaded ${capitalize(mediaInfo.platform)} audio.`, 'success');
                hideLoading(elements.music.playerContainer);
            } else {
                showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
                hideLoading(elements.music.playerContainer);
            }
        } else {
            showMessage('Please enter a URL or select an audio file.', 'error');
            hideLoading(elements.music.playerContainer);
        }

        checkReadyToPlay();
        saveSettings();
    }

    // Load Video Handler
    function handleLoadVideo() {
        const url = elements.video.urlInput.value.trim();
        const file = elements.video.fileInput.files[0];
        const start = parseInt(elements.video.startInput.value) || 0;

        // Show loading indicator
        showLoading(elements.video.playerContainer);

        // Unload existing video if any
        if (state.video) {
            unloadMedia('video');
        }

        if (file) {
            if (file.size > 50 * 1024 * 1024) { // 50MB limit
                showMessage('Video file size exceeds 50MB limit.', 'error');
                hideLoading(elements.video.playerContainer);
                return;
            }

            // Handle local video file
            const fileUrl = URL.createObjectURL(file);
            const videoElement = document.createElement('video');
            videoElement.controls = true;
            videoElement.src = fileUrl;
            videoElement.id = 'loaded-video';
            videoElement.setAttribute('aria-label', 'Loaded Video Player');
            videoElement.style.width = '100%';
            videoElement.style.height = 'auto';
            elements.video.playerContainer.innerHTML = '';
            elements.video.playerContainer.appendChild(videoElement);

            // Set start time if applicable
            if (start > 0) {
                videoElement.currentTime = start;
            }

            state.video = {
                type: 'file',
                element: videoElement,
                start: start
            };
            showMessage('Local video file loaded.', 'success');
            hideLoading(elements.video.playerContainer);
        } else if (url && isValidMediaURL(url)) {
            const mediaInfo = extractMediaInfo(url);
            if (mediaInfo) {
                if (mediaInfo.platform === 'youtube') {
                    embedYouTubeIframe(mediaInfo.id, start, 'video');
                } else if (mediaInfo.platform === 'vimeo') {
                    embedVimeoPlayer(mediaInfo.id, start, 'video');
                }
                showMessage(`Loaded ${capitalize(mediaInfo.platform)} video.`, 'success');
                hideLoading(elements.video.playerContainer);
            } else {
                showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
                hideLoading(elements.video.playerContainer);
            }
        } else {
            showMessage('Please enter a URL or select a video file.', 'error');
            hideLoading(elements.video.playerContainer);
        }

        checkReadyToPlay();
        saveSettings();
    }

    // Play Handler
    function handlePlay() {
        // Play Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.music.element);
                }
            } else if (state.music.type === 'vimeo') {
                state.music.element.play().catch(error => {
                    console.error('Error playing Vimeo audio:', error);
                    showMessage('Failed to play Vimeo audio.', 'error');
                });
            }
            // Add YouTube control if implemented
        }

        // Play Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.video.element);
                }
            } else if (state.video.type === 'vimeo') {
                state.video.element.play().catch(error => {
                    console.error('Error playing Vimeo video:', error);
                    showMessage('Failed to play Vimeo video.', 'error');
                });
            }
            // Add YouTube control if implemented
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback started!', 'success');
    }

    // Pause/Resume Handler
    function handlePauseResume() {
        if (state.isPaused) {
            resumeMedia();
        } else {
            pauseMedia();
        }
    }

    // Pause Media
    function pauseMedia() {
        // Pause Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.pause();
            } else if (state.music.type === 'vimeo') {
                state.music.element.pause().catch(error => {
                    console.error('Error pausing Vimeo audio:', error);
                    showMessage('Failed to pause Vimeo audio.', 'error');
                });
            }
        }

        // Pause Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.pause();
            } else if (state.video.type === 'vimeo') {
                state.video.element.pause().catch(error => {
                    console.error('Error pausing Vimeo video:', error);
                    showMessage('Failed to pause Vimeo video.', 'error');
                });
            }
        }

        state.isPaused = true;
        elements.controls.pauseResumeButton.textContent = 'Resume';
        showMessage('Playback paused.', 'info');
    }

    // Resume Media
    function resumeMedia() {
        // Resume Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.play();
            } else if (state.music.type === 'vimeo') {
                state.music.element.play().catch(error => {
                    console.error('Error resuming Vimeo audio:', error);
                    showMessage('Failed to resume Vimeo audio.', 'error');
                });
            }
        }

        // Resume Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.play();
            } else if (state.video.type === 'vimeo') {
                state.video.element.play().catch(error => {
                    console.error('Error resuming Vimeo video:', error);
                    showMessage('Failed to resume Vimeo video.', 'error');
                });
            }
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback resumed.', 'success');
    }

    // Play From Start Handler
    function handlePlayFromStart() {
        // Play from Start Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.currentTime = state.music.start;
                state.music.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.music.element);
                }
            } else if (state.music.type === 'vimeo') {
                state.music.element.setCurrentTime(state.music.start).then(() => {
                    return state.music.element.play();
                }).catch(error => {
                    console.error('Error playing from start in Vimeo audio:', error);
                    showMessage('Failed to play from start in Vimeo audio.', 'error');
                });
            }
        }

        // Play from Start Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.currentTime = state.video.start;
                state.video.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.video.element);
                }
            } else if (state.video.type === 'vimeo') {
                state.video.element.setCurrentTime(state.video.start).then(() => {
                    return state.video.element.play();
                }).catch(error => {
                    console.error('Error playing from start in Vimeo video:', error);
                    showMessage('Failed to play from start in Vimeo video.', 'error');
                });
            }
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback restarted!', 'success');
    }

    // === Settings Modal Functions ===
    function openSettingsModal() {
        elements.settings.modal.removeAttribute('hidden');
        elements.settings.modal.setAttribute('aria-hidden', 'false');
        elements.settings.modal.querySelector('.close-button').focus();
        trapFocus(elements.settings.modal);
    }

    function closeSettingsModal() {
        elements.settings.modal.setAttribute('hidden', '');
        elements.settings.modal.setAttribute('aria-hidden', 'true');
        elements.settings.button.focus();
        removeTrapFocus();
    }

    // === Media Embedding Functions ===

    /**
     * Embeds a YouTube video into the specified container using an iframe.
     * Mutes the video and starts at the specified time without autoplay.
     * @param {string} videoId - The YouTube video ID.
     * @param {number} start - The start time in seconds.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function embedYouTubeIframe(videoId, start, mediaType) {
        const container = elements[mediaType].playerContainer;
        container.innerHTML = ''; // Clear previous content

        let src = `https://www.youtube.com/embed/${videoId}?mute=1&start=${start}&controls=1&rel=0`;
        // Note: autoplay=1 removed to prevent auto-play

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.width = '100%';
        iframe.height = '720'; // Increased height
        iframe.frameBorder = '0';
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';

        iframe.setAttribute('title', 'YouTube video player');

        container.appendChild(iframe);

        state[mediaType] = {
            type: 'youtube',
            element: iframe,
            start: start
        };
    }

    /**
     * Embeds a Vimeo video into the specified container using the Player API.
     * Mutes the video and starts at the specified time without autoplay.
     * @param {string} videoId - The Vimeo video ID.
     * @param {number} start - The start time in seconds.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function embedVimeoPlayer(videoId, start, mediaType) {
        const container = elements[mediaType].playerContainer;
        container.innerHTML = ''; // Clear previous content

        const iframe = document.createElement('iframe');
        const src = `https://player.vimeo.com/video/${videoId}?muted=1&autopause=0&background=0`;
        iframe.src = src;
        iframe.width = '100%';
        iframe.height = '720'; // Increased height
        iframe.frameBorder = '0';
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';

        iframe.setAttribute('title', 'Vimeo video player');

        container.appendChild(iframe);

        const player = new Vimeo.Player(iframe, {
            id: videoId,
            width: container.clientWidth,
            muted: true,
            autoplay: false,
            start: start
        });

        state[mediaType] = {
            type: 'vimeo',
            element: player,
            start: start
        };

        // Ensure buffering by loading the video without autoplay
        player.setVolume(0).catch(error => {
            console.error(`Error setting volume for Vimeo ${mediaType}:`, error);
        });
    }

    // === Settings Management ===

    /**
     * Loads settings from Chrome storage.
     */
    function loadSettings() {
        try {
            chrome.storage.local.get(['mediaSettings'], (result) => {
                if (chrome.runtime.lastError) {
                    throw new Error(chrome.runtime.lastError);
                }

                if (result.mediaSettings) {
                    const { music, video, fullscreenOnPlay: fsPlay } = result.mediaSettings;

                    if (music) {
                        if (music.type === 'youtube' 
                            || music.type === 'vimeo') {
                            const url = music.type === 'youtube' 
                                ? `https://www.youtube.com/watch?v=${music.id}` 
                                : `https://vimeo.com/${music.id}`;
                            elements.music.urlInput.value = url;
                            elements.music.startInput.value = music.start || 0;
                            // Optionally, auto-load the media by triggering the load button
                            // handleLoadMusic();
                        }
                        // Handle file-based music loading if necessary
                    }

                    if (video) {
                        if (video.type === 'youtube' 
                            || video.type === 'vimeo') {
                            const url = video.type === 'youtube' 
                                ? `https://www.youtube.com/watch?v=${video.id}` 
                                : `https://vimeo.com/${video.id}`;
                            elements.video.urlInput.value = url;
                            elements.video.startInput.value = video.start || 0;
                            // Optionally, auto-load the media by triggering the load button
                            // handleLoadVideo();
                        }
                        // Handle file-based video loading if necessary
                    }

                    if (typeof fsPlay === 'boolean') {
                        state.fullscreenOnPlay = fsPlay;
                        elements.settings.fullscreenToggle.checked = fsPlay;
                    }
                }
            });
        } catch (error) {
            console.error('Error loading settings:', error);
            showMessage('Failed to load settings.', 'error');
        }
    }

    /**
     * Saves settings to Chrome storage.
     */
    function saveSettings() {
        const settings = {
            music: state.music,
            video: state.video,
            fullscreenOnPlay: state.fullscreenOnPlay
        };
        try {
            chrome.storage.local.set({ mediaSettings: settings }, () => {
                if (chrome.runtime.lastError) {
                    throw new Error(chrome.runtime.lastError);
                }
                console.log('Settings saved.');
            });
        } catch (error) {
            console.error('Error saving settings:', error);
            showMessage('Error saving settings.', 'error');
        }
    }

    /**
     * Unloads media from the specified type.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function unloadMedia(mediaType) {
        if (state[mediaType]) {
            if (state[mediaType].type === 'file') {
                if (state[mediaType].element.src) {
                    URL.revokeObjectURL(state[mediaType].element.src);
                    state[mediaType].element.src = '';
                    state[mediaType].element.remove();
                }
            } else if (state[mediaType].type === 'youtube') {
                const iframe = state[mediaType].element;
                iframe.src = ''; // Reset iframe src to stop the media
            } else if (state[mediaType].type === 'vimeo') {
                const player = state[mediaType].element;
                player.unload().catch(error => {
                    console.error(`Error unloading Vimeo ${mediaType}:`, error);
                });
            }
            state[mediaType] = null;
        }
    }

    // === Playback Controls ===

    /**
     * Enables or disables playback controls based on media loading state.
     */
    function checkReadyToPlay() {
        // Enable Play button only when at least one of audio or video is loaded
        const readyAudio = state.music 
            && (state.music.type === 'file' 
                || state.music.type === 'youtube' 
                || state.music.type === 'vimeo');
        const readyVideo = state.video 
            && (state.video.type === 'file' 
                || state.video.type === 'youtube' 
                || state.video.type === 'vimeo');
        const ready = readyAudio || readyVideo;

        elements.controls.playButton.disabled = !ready;
        elements.controls.pauseResumeButton.disabled = !ready;
        elements.controls.playStartButton.disabled = !ready;
    }

    /**
     * Enters fullscreen mode for the specified element.
     * @param {HTMLElement} element - The element to enter fullscreen.
     */
    function enterFullscreen(element) {
        if (element && element.element && element.element.requestFullscreen) {
            element.element.requestFullscreen().then(() => {
                showMessage('Entered fullscreen mode.', 'success');
            }).catch(err => {
                console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
                showMessage('Failed to enter fullscreen mode.', 'error');
            });
        } else if (element && element.requestFullscreen) {
            element.requestFullscreen().then(() => {
                showMessage('Entered fullscreen mode.', 'success');
            }).catch(err => {
                console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
                showMessage('Failed to enter fullscreen mode.', 'error');
            });
        } else {
            showMessage('Fullscreen not supported on this element.', 'error');
        }
    }

    // === New Utility Functions ===

    /**
     * Validates whether the URL is a valid YouTube or Vimeo URL.
     * @param {string} url - The URL to validate.
     * @returns {boolean} True if valid, else false.
     */
    function isValidMediaURL(url) {
        try {
            const parsedUrl = new URL(url);
            const hostname = parsedUrl.hostname.toLowerCase();
            const pathname = parsedUrl.pathname;

            // YouTube RegEx Patterns
            const youtubeRegex = /^(?:\/watch\/?|\/embed\/|\/v\/)?([a-zA-Z0-9_-]{11})$/;
            // Vimeo RegEx Patterns
            const vimeoRegex = /^\/(?:video\/)?(\d+)$/;

            if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
                // Extract YouTube video ID
                let videoId = '';
                if (hostname === 'youtu.be') {
                    videoId = pathname.slice(1);
                } else {
                    videoId = parsedUrl.searchParams.get('v') || '';
                }
                return youtubeRegex.test(`/${videoId}`);
            } else if (hostname.includes('vimeo.com')) {
                // Extract Vimeo video ID
                const match = pathname.match(vimeoRegex);
                return match && match[1].length > 0;
            }

            return false;
        } catch (e) {
            return false;
        }
    }

    /**
     * Extracts media information from the URL.
     * @param {string} url - The media URL.
     * @returns {Object|null} An object with platform and id, or null if invalid.
     */
    function extractMediaInfo(url) {
        try {
            const parsedUrl = new URL(url);
            const hostname = parsedUrl.hostname.toLowerCase();
            const pathname = parsedUrl.pathname;

            // YouTube Patterns
            if (hostname.includes('youtube.com') 
                || hostname === 'youtu.be') {
                let videoId = '';
                if (hostname === 'youtu.be') {
                    videoId = pathname.slice(1);
                } else {
                    videoId = parsedUrl.searchParams.get('v') || '';
                }

                // Validate videoId length
                if (videoId.length === 11) {
                    return { platform: 'youtube', id: videoId };
                }
            }

            // Vimeo Patterns
            if (hostname.includes('vimeo.com')) {
                const vimeoMatch = pathname.match(/^\/(?:video\/)?(\d+)$/);
                if (vimeoMatch && vimeoMatch[1]) {
                    return { platform: 'vimeo', id: vimeoMatch[1] };
                }
            }

            return null;
        } catch (e) {
            return null;
        }
    }
});
Key Changes:

Integrated Vimeo Player API:
Added the Vimeo Player API script in dashboard.html.
Created Player instances for Vimeo videos in dashboard.js for better control.
Increased Video Size:
Updated iframe heights to 720px for larger video displays.
Play Button Functionality:
Implemented play, pause, and setCurrentTime methods for Vimeo players using the Vimeo Player API.
Buffering Without Autoplay:
Ensured that videos load without autoplay by removing autoplay=1 and setting autopause=0 and background=0 in Vimeo embed URLs.
Label Adjustments:
Removed legends and replaced "Upload" with "Local" in the input labels.
4. styles.css
Changes:

Ensured larger player sizes.
Enhanced responsiveness for better display on various devices.

/* General Styles */
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px;
    max-width: 1000px; /* Increased max-width for larger displays */
    margin: 0 auto;
}

.section {
    width: 100%;
    margin-bottom: 20px;
    background-color: #fff;
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* Header with Settings Button and Main Title */
.header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center; /* Center the content */
    margin-bottom: 20px;
    position: relative;
}

.settings-button {
    position: absolute;
    left: 0;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 5px;
    cursor: pointer;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

.settings-button:hover {
    background-color: #f0f0f0;
    border-color: #999;
}

.settings-icon {
    width: 20px;
    height: 20px;
}

.main-title {
    font-size: 2.5em; /* Increased font size for better visibility */
    font-weight: bold;
    margin: 0;
    opacity: 0;
    animation: fadeInShake 5s forwards;
}

@keyframes fadeInShake {
    0% {
        opacity: 0;
        transform: translateX(0);
        color: #FF0000; /* Red */
    }
    10% {
        opacity: 0.2;
        transform: translateX(-10px);
        color: #FF7F00; /* Orange */
    }
    20% {
        opacity: 0.4;
        transform: translateX(10px);
        color: #FFFF00; /* Yellow */
    }
    30% {
        opacity: 0.6;
        transform: translateX(-10px);
        color: #00FF00; /* Green */
    }
    40% {
        opacity: 0.7;
        transform: translateX(10px);
        color: #0000FF; /* Blue */
    }
    50% {
        opacity: 0.8;
        transform: translateX(-10px);
        color: #4B0082; /* Indigo */
    }
    60% {
        opacity: 0.85;
        transform: translateX(10px);
        color: #8B00FF; /* Violet */
    }
    70% {
        opacity: 0.9;
        transform: translateX(-10px);
        color: #FF00FF; /* Magenta */
    }
    80% {
        opacity: 0.95;
        transform: translateX(10px);
        color: #000000; /* Black */
    }
    100% {
        opacity: 1;
        transform: translateX(0);
        color: #000000; /* Black */
    }
}

/* Controls */
.controls {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.controls button {
    padding: 12px 24px; /* Increased padding for better accessibility */
    cursor: pointer;
    border: none;
    border-radius: 5px;
    background-color: #4285f4;
    color: #fff;
    transition: background-color 0.3s ease;
    font-size: 1em;
}

.controls button:disabled {
    background-color: #a0c3ff;
    cursor: not-allowed;
}

.controls button:hover:not(:disabled) {
    background-color: #357ae8;
}

/* Modal Styles */
.modal[hidden] {
    display: none;
}

.modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex; /* Visible when not hidden */
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.modal-content {
    background-color: #fff;
    padding: 20px 30px;
    border-radius: 8px;
    width: 90%;
    max-width: 500px; /* Increased max-width for better layout */
    position: relative;
}

.close-button {
    position: absolute;
    top: 10px;
    right: 15px;
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
}

.modal-content h2 {
    margin-top: 0;
}

/* Form Elements */
fieldset {
    border: none;
    padding: 0;
}

fieldset label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

fieldset input[type="text"],
fieldset input[type="number"],
fieldset input[type="file"] {
    width: 100%;
    padding: 10px; /* Increased padding for better usability */
    margin-bottom: 15px;
    box-sizing: border-box;
    border: 1px solid #ccc;
    border-radius: 4px;
}

fieldset .load-button {
    width: 100%;
    padding: 12px;
    background-color: #34a853;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease;
    font-size: 1em;
}

fieldset .load-button:hover {
    background-color: #2c8e46;
}

/* Player Containers */
.player-container {
    margin-top: 10px;
    width: 100%;
    max-width: 100%;
    min-height: 100px; /* Increased minimum height */
    box-sizing: border-box;
    overflow: hidden; /* Prevent overflow */
}

/* Responsive Video and Audio Elements */
.player-container video,
.player-container iframe {
    width: 100%;
    height: 720px; /* Fixed height for consistency */
    border-radius: 8px;
    /* Ensure the iframe fills the container */
    display: block;
}

/* Messages */
.message-container {
    margin-top: 20px;
    width: 100%;
}

.message {
    padding: 12px;
    border-radius: 5px;
    margin-bottom: 10px;
    color: #fff;
    font-size: 1em;
}

.message.success {
    background-color: #4caf50;
}

.message.error {
    background-color: #f44336;
}

.message.info {
    background-color: #2196f3;
}

/* Loader */
.loader {
    border: 8px solid #f3f3f3; /* Light grey */
    border-top: 8px solid #4285f4; /* Blue */
    border-radius: 50%;
    width: 60px; /* Increased size for better visibility */
    height: 60px; /* Increased size for better visibility */
    animation: spin 1s linear infinite;
    margin: 0 auto;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Responsive Design */
@media (max-width: 800px) {
    .container {
        padding: 15px;
    }

    .modal-content {
        padding: 15px 20px;
    }

    .controls {
        flex-direction: column;
        width: 100%;
    }

    .controls button {
        width: 100%;
    }

    .settings-button {
        width: 35px;
        height: 35px;
    }

    .settings-icon {
        width: 18px;
        height: 18px;
    }

    .main-title {
        font-size: 2em;
    }

    .player-container video,
    .player-container iframe {
        height: 480px; /* Adjusted height for smaller screens */
    }

    .loader {
        width: 50px; /* Adjusted size for smaller screens */
        height: 50px; /* Adjusted size for smaller screens */
    }
}

@media (max-width: 500px) {
    .container {
        padding: 10px;
    }

    .controls button {
        padding: 10px;
        font-size: 0.9em;
    }

    .modal-content {
        padding: 10px 15px;
    }

    .main-title {
        font-size: 1.8em;
    }

    .player-container video,
    .player-container iframe {
        height: 360px; /* Further adjusted height for very small screens */
    }

    .loader {
        width: 40px; /* Further adjusted size for very small screens */
        height: 40px; /* Further adjusted size for very small screens */
    }
}
Key Changes:

Increased Player Size:
Updated the iframe height to 720px for larger displays.
Adjusted minimum heights and padding for better visibility.
Enhanced Responsiveness:
Added media queries to adjust player sizes and button paddings for various screen widths.
Loader Adjustment:
Increased the loader size for better visibility.
Adjusted loader size in media queries for smaller screens.
Typography and Spacing:
Increased font sizes and paddings for better usability and accessibility.
5. background.js
No changes are needed here based on the current requirements. Ensure it matches the following:


chrome.action.onClicked.addListener(() => {
    const dashboardURL = chrome.runtime.getURL("dashboard.html");
    
    // Query for any existing tabs with the dashboard URL
    chrome.tabs.query({ url: dashboardURL }, (tabs) => {
        if (chrome.runtime.lastError) {
            console.error("Tab Query Error:", chrome.runtime.lastError);
            return;
        }

        if (tabs.length > 0) {
            // Activate the first existing dashboard tab
            chrome.tabs.update(tabs[0].id, { active: true }, (updatedTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Update Error:", chrome.runtime.lastError);
                }
            });
        } else {
            // Create a new dashboard tab
            chrome.tabs.create({ url: dashboardURL, active: true }, (newTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Creation Error:", chrome.runtime.lastError);
                }
            });
        }
    });
});
Summary of Actions
Integrated Vimeo Player API: This allows for better control over Vimeo videos, enabling functionalities like play, pause, and set current time programmatically.
Increased Video Size: Updated the iframe heights to 720px to ensure videos are displayed larger.
Play Button Functionality: Utilized the Vimeo Player API to control playback, ensuring that the Play button functions as expected.
Buffering Without Autoplay: Configured the Vimeo embed URLs to load without autoplay, allowing the videos to buffer upon loading.
UI Enhancements: Improved the user interface by increasing font sizes, padding, and ensuring responsiveness across different screen sizes.
Final Steps
Replace Existing Files: Update your project with the provided manifest.json, dashboard.html, dashboard.js, and styles.css.
Reload the Extension:
Go to chrome://extensions/ in your Chrome browser.
Find your "Media Loader" extension.
Click the "Reload" button to apply the changes.
Test Functionality:
Open the extension dashboard.
Load a Vimeo video URL and ensure it displays larger.
Click the "Load" button and verify that the video buffers.
Use the "Play" button to start playback.
Troubleshooting:
Open the Chrome Developer Console (Ctrl+Shift+I or Cmd+Option+I on Mac) to check for any errors.
Ensure that the Vimeo Player API is loading correctly without CSP (Content Security Policy) issues.
If you continue to experience issues, please provide specific error messages or behaviors so I can assist you further.


Failed to load extension
File
~\Desktop\myext
Error
'content_security_policy.extension_pages': Insecure CSP value "https://player.vimeo.com" in directive 'script-src'.
Could not load manifest.
i only need the whole updated files.


Apologies for the inconvenience you're experiencing. Let's address the issues step-by-step and provide you with the complete updated files required to make your Chrome extension function correctly.

1. Issues Identified:
Content Security Policy (CSP) Error:
Chrome extensions enforce strict CSPs. Including external sources like https://player.vimeo.com directly in the script-src directive is not allowed and will lead to manifest loading failures.
Vimeo Videos Too Small:
The video iframes might still have restrictive dimensions preventing larger display.
Play Button Not Functioning & Buffering Issues:
Without proper integration with Vimeo's Player API, controlling playback programmatically is challenging.
2. Solutions Implemented:
CSP Adjustment:
Remove External Script Sources: The content_security_policy in manifest.json no longer includes external sources like https://player.vimeo.com.
Include Vimeo Player API Locally: To interact with Vimeo videos programmatically, we'll include the Vimeo Player API as a local script within the extension.
Increase Video Size:
Adjusted the CSS to ensure video iframes have larger dimensions for better visibility.
Integrate Vimeo Player API Locally:
Download the Vimeo Player API: Since Chrome extensions cannot load external scripts due to CSP restrictions, you need to download the Vimeo Player.js and include it in your extension directory.
Reference the Local Script: Update dashboard.html to reference the locally stored player.js.
Enhanced Playback Controls:
Updated dashboard.js to utilize the Vimeo Player API for controlling playback (play, pause, seek).
3. Updated Files:
Below are the fully updated files. Ensure that you download the player.js from Vimeo's official source and place it in the specified directory as indicated.

A. manifest.json
Key Changes:

Removed external script sources from content_security_policy.
Added player.js as a local script resource.

{
  "manifest_version": 3,
  "name": "Media Loader",
  "version": "1.0",
  "description": "Load and play music and videos from YouTube and Vimeo",
  "permissions": ["storage", "tabs"],
  "host_permissions": [
    "https://www.youtube.com/*",
    "https://player.vimeo.com/*"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_title": "Open Media Loader",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'"
  },
  "web_accessible_resources": [
    {
      "resources": ["lib/player.js"],
      "matches": ["<all_urls>"]
    }
  ]
}
B. background.js
No changes are needed here based on your current requirements. Ensure it matches the following:


chrome.action.onClicked.addListener(() => {
    const dashboardURL = chrome.runtime.getURL("dashboard.html");
    
    // Query for any existing tabs with the dashboard URL
    chrome.tabs.query({ url: dashboardURL }, (tabs) => {
        if (chrome.runtime.lastError) {
            console.error("Tab Query Error:", chrome.runtime.lastError);
            return;
        }

        if (tabs.length > 0) {
            // Activate the first existing dashboard tab
            chrome.tabs.update(tabs[0].id, { active: true }, (updatedTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Update Error:", chrome.runtime.lastError);
                }
            });
        } else {
            // Create a new dashboard tab
            chrome.tabs.create({ url: dashboardURL, active: true }, (newTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Creation Error:", chrome.runtime.lastError);
                }
            });
        }
    });
});
C. dashboard.html
Key Changes:

Removed external script sources.
Included the local player.js for Vimeo integration.
Adjusted labels by replacing "Upload" with "Local".
Removed legends for "Load Audio" and "Load Video".

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Media Loader Dashboard</title>
    <link rel="stylesheet" href="styles.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <main class="container">
        <!-- Header with Settings Button and SyncWave Title -->
        <header class="header">
            <button id="settings-button" class="settings-button" title="Settings" aria-label="Open Settings">
                <img src="icons/settings.svg" alt="Settings" class="settings-icon" aria-hidden="true">
            </button>
            <h1 class="main-title">SyncWave</h1>
        </header>
        
        <!-- Load Audio Section -->
        <section class="section" id="load-music-section">
            <fieldset>
                <label for="music-url">Audio URL</label>
                <input type="text" id="music-url" name="music-url" placeholder="Enter YouTube or Vimeo URL">

                <label for="music-file">Local Audio File</label>
                <input type="file" id="music-file" name="music-file" accept="audio/*">

                <label for="music-start">Start Time (seconds)</label>
                <input type="number" id="music-start" name="music-start" placeholder="Start Time (seconds)" min="0">

                <button type="button" id="load-music" class="load-button">Load</button>
            </fieldset>
            <div id="music-player-container" class="player-container"></div>
        </section>

        <!-- Load Video Section -->
        <section class="section" id="load-video-section">
            <fieldset>
                <label for="video-url">Video URL</label>
                <input type="text" id="video-url" name="video-url" placeholder="Enter YouTube or Vimeo URL">

                <label for="video-file">Local Video File</label>
                <input type="file" id="video-file" name="video-file" accept="video/*">

                <label for="video-start">Start Time (seconds)</label>
                <input type="number" id="video-start" name="video-start" placeholder="Start Time (seconds)" min="0">

                <button type="button" id="load-video" class="load-button">Load</button>
            </fieldset>
            <div id="video-player-container" class="player-container"></div>
        </section>

        <!-- Playback Controls -->
        <section class="controls">
            <button type="button" id="play-button" disabled aria-label="Play">Play</button>
            <button type="button" id="pause-resume-button" disabled aria-label="Pause">Pause</button>
            <button type="button" id="play-start-button" disabled aria-label="Play from Start">Play from Start</button>
        </section>

        <!-- Message Container -->
        <section id="message-container" class="message-container" role="alert" aria-live="assertive"></section>

        <!-- Settings Modal (Remains Unchanged) -->
        <div id="settings-modal" class="modal" role="dialog" aria-labelledby="settings-modal-title" aria-modal="true" hidden>
            <div class="modal-content">
                <button class="close-button" aria-label="Close Settings Modal">&times;</button>
                <h2 id="settings-modal-title">Settings</h2>
                <form>
                    <label for="fullscreen-toggle">
                        <input type="checkbox" id="fullscreen-toggle" name="fullscreen-toggle">
                        Full Screen on Play
                    </label>
                    <!-- Additional settings can go here -->
                </form>
            </div>
        </div>
    </main>

    <!-- Local Vimeo Player API -->
    <script src="lib/player.js"></script>
    
    <!-- Your Dashboard JS -->
    <script src="dashboard.js"></script>
</body>
</html>
**📌 Important:
Download the Vimeo Player.js and place it inside a lib directory within your extension folder. Ensure the file path is lib/player.js.

D. dashboard.js
Key Changes:

Integrated Vimeo's Player API using the local player.js.
Enhanced Play, Pause, and Seek functionalities for Vimeo videos.
Increased iframe heights for better visibility.

"use strict";

document.addEventListener('DOMContentLoaded', () => {
    // === Element References ===
    const elements = {
        music: {
            urlInput: document.getElementById('music-url'),
            fileInput: document.getElementById('music-file'),
            startInput: document.getElementById('music-start'),
            loadButton: document.getElementById('load-music'),
            playerContainer: document.getElementById('music-player-container')
        },
        video: {
            urlInput: document.getElementById('video-url'),
            fileInput: document.getElementById('video-file'),
            startInput: document.getElementById('video-start'),
            loadButton: document.getElementById('load-video'),
            playerContainer: document.getElementById('video-player-container')
        },
        controls: {
            playButton: document.getElementById('play-button'),
            pauseResumeButton: document.getElementById('pause-resume-button'),
            playStartButton: document.getElementById('play-start-button')
        },
        messageContainer: document.getElementById('message-container'),
        settings: {
            button: document.getElementById('settings-button'),
            modal: document.getElementById('settings-modal'),
            closeButton: document.querySelector('.close-button'),
            fullscreenToggle: document.getElementById('fullscreen-toggle')
        }
    };

    // === State Management ===
    const state = {
        music: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLAudioElement | Player, start: Number }
        video: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLVideoElement | Player, start: Number }
        isPaused: false,
        fullscreenOnPlay: false
    };

    // === Utility Functions ===

    /**
     * Formats seconds into 'XmYs' (e.g., 125 seconds -> '2m5s')
     * @param {number} seconds - The time in seconds.
     * @returns {string} Formatted time string.
     */
    function formatTime(seconds) {
        if (isNaN(seconds) || seconds < 0) return '';
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = seconds % 60;
        return `${minutes}m${remainingSeconds}s`;
    }

    /**
     * Capitalize the first letter of a string.
     * @param {string} text - The string to capitalize.
     * @returns {string} Capitalized string.
     */
    function capitalize(text) {
        if (!text) return '';
        return text.charAt(0).toUpperCase() + text.slice(1);
    }

    /**
     * Displays a message to the user.
     * @param {string} message - The message to display.
     * @param {string} type - The type of message ('success', 'error', 'info').
     */
    function showMessage(message, type) {
        elements.messageContainer.innerHTML = '';
        const msgDiv = document.createElement('div');
        msgDiv.textContent = message;
        msgDiv.classList.add('message', type); // 'success', 'error', 'info'
        elements.messageContainer.appendChild(msgDiv);

        // Automatically hide message after 5 seconds
        setTimeout(() => {
            if (elements.messageContainer.contains(msgDiv)) {
                elements.messageContainer.removeChild(msgDiv);
            }
        }, 5000);
    }

    /**
     * Shows a loading spinner in the specified container.
     * @param {HTMLElement} container - The container to show the loader in.
     */
    function showLoading(container) {
        container.innerHTML = '';
        const loader = document.createElement('div');
        loader.classList.add('loader'); // Define loader styles in CSS
        container.appendChild(loader);
    }

    /**
     * Hides the loading spinner from the specified container.
     * @param {HTMLElement} container - The container to hide the loader from.
     */
    function hideLoading(container) {
        const loader = container.querySelector('.loader');
        if (loader) {
            container.removeChild(loader);
        }
    }

    /**
     * Traps keyboard focus within a specified element.
     * @param {HTMLElement} element - The element to trap focus within.
     */
    function trapFocus(element) {
        const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]),' +
            ' textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"],' +
            ' [contenteditable]';
        const focusableElements = element.querySelectorAll(focusableElementsString);
        const firstTabStop = focusableElements[0];
        const lastTabStop = focusableElements[focusableElements.length - 1];

        // Listen for and trap the keyboard
        element.addEventListener('keydown', trapTabKey);

        function trapTabKey(e) {
            // Check for TAB key press
            if (e.key === 'Tab') {
                // SHIFT + TAB
                if (e.shiftKey) {
                    if (document.activeElement === firstTabStop) {
                        e.preventDefault();
                        lastTabStop.focus();
                    }
                } else { // TAB
                    if (document.activeElement === lastTabStop) {
                        e.preventDefault();
                        firstTabStop.focus();
                    }
                }
            }
        }

        // Remove trap when modal is closed
        function removeTrapKey(e) {
            element.removeEventListener('keydown', trapTabKey);
        }

        // Store the function reference to remove it later
        element.removeTrapKey = removeTrapKey;
    }

    function removeTrapFocus() {
        if (elements.settings.modal.removeTrapKey) {
            elements.settings.modal.removeTrapKey();
        }
    }

    // === Initialization ===
    loadSettings();

    // === Event Listeners ===
    elements.music.loadButton.addEventListener('click', handleLoadMusic);
    elements.video.loadButton.addEventListener('click', handleLoadVideo);
    elements.controls.playButton.addEventListener('click', handlePlay);
    elements.controls.pauseResumeButton.addEventListener('click', handlePauseResume);
    elements.controls.playStartButton.addEventListener('click', handlePlayFromStart);

    // Settings Modal Event Listeners
    elements.settings.button.addEventListener('click', openSettingsModal);
    elements.settings.closeButton.addEventListener('click', closeSettingsModal);
    window.addEventListener('click', (event) => {
        if (event.target === elements.settings.modal) {
            closeSettingsModal();
        }
    });
    document.addEventListener('keydown', (event) => {
        if (event.key === 'Escape' && !elements.settings.modal.hasAttribute('hidden')) {
            closeSettingsModal();
        }
    });
    elements.settings.fullscreenToggle.addEventListener('change', (event) => {
        state.fullscreenOnPlay = event.target.checked;
        saveSettings();
    });

    // === Handler Functions ===

    // Load Music Handler
    function handleLoadMusic() {
        const url = elements.music.urlInput.value.trim();
        const file = elements.music.fileInput.files[0];
        const start = parseInt(elements.music.startInput.value) || 0;

        // Show loading indicator
        showLoading(elements.music.playerContainer);

        // Unload existing music if any
        if (state.music) {
            unloadMedia('music');
        }

        if (file) {
            if (file.size > 10 * 1024 * 1024) { // 10MB limit
                showMessage('Audio file size exceeds 10MB limit.', 'error');
                hideLoading(elements.music.playerContainer);
                return;
            }

            // Handle local audio file
            const fileUrl = URL.createObjectURL(file);
            const audioElement = document.createElement('audio');
            audioElement.controls = true;
            audioElement.src = fileUrl;
            audioElement.id = 'loaded-music';
            audioElement.setAttribute('aria-label', 'Loaded Audio Player');
            audioElement.style.width = '100%';
            audioElement.style.height = 'auto';
            elements.music.playerContainer.innerHTML = '';
            elements.music.playerContainer.appendChild(audioElement);

            // Set start time if applicable
            if (start > 0) {
                audioElement.currentTime = start;
            }

            state.music = {
                type: 'file',
                element: audioElement,
                start: start
            };
            showMessage('Local audio file loaded.', 'success');
            hideLoading(elements.music.playerContainer);
        } else if (url && isValidMediaURL(url)) {
            const mediaInfo = extractMediaInfo(url);
            if (mediaInfo) {
                if (mediaInfo.platform === 'youtube') {
                    embedYouTubeIframe(mediaInfo.id, start, 'music');
                } else if (mediaInfo.platform === 'vimeo') {
                    embedVimeoPlayer(mediaInfo.id, start, 'music');
                }
                showMessage(`Loaded ${capitalize(mediaInfo.platform)} audio.`, 'success');
                hideLoading(elements.music.playerContainer);
            } else {
                showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
                hideLoading(elements.music.playerContainer);
            }
        } else {
            showMessage('Please enter a URL or select an audio file.', 'error');
            hideLoading(elements.music.playerContainer);
        }

        checkReadyToPlay();
        saveSettings();
    }

    // Load Video Handler
    function handleLoadVideo() {
        const url = elements.video.urlInput.value.trim();
        const file = elements.video.fileInput.files[0];
        const start = parseInt(elements.video.startInput.value) || 0;

        // Show loading indicator
        showLoading(elements.video.playerContainer);

        // Unload existing video if any
        if (state.video) {
            unloadMedia('video');
        }

        if (file) {
            if (file.size > 50 * 1024 * 1024) { // 50MB limit
                showMessage('Video file size exceeds 50MB limit.', 'error');
                hideLoading(elements.video.playerContainer);
                return;
            }

            // Handle local video file
            const fileUrl = URL.createObjectURL(file);
            const videoElement = document.createElement('video');
            videoElement.controls = true;
            videoElement.src = fileUrl;
            videoElement.id = 'loaded-video';
            videoElement.setAttribute('aria-label', 'Loaded Video Player');
            videoElement.style.width = '100%';
            videoElement.style.height = 'auto';
            elements.video.playerContainer.innerHTML = '';
            elements.video.playerContainer.appendChild(videoElement);

            // Set start time if applicable
            if (start > 0) {
                videoElement.currentTime = start;
            }

            state.video = {
                type: 'file',
                element: videoElement,
                start: start
            };
            showMessage('Local video file loaded.', 'success');
            hideLoading(elements.video.playerContainer);
        } else if (url && isValidMediaURL(url)) {
            const mediaInfo = extractMediaInfo(url);
            if (mediaInfo) {
                if (mediaInfo.platform === 'youtube') {
                    embedYouTubeIframe(mediaInfo.id, start, 'video');
                } else if (mediaInfo.platform === 'vimeo') {
                    embedVimeoPlayer(mediaInfo.id, start, 'video');
                }
                showMessage(`Loaded ${capitalize(mediaInfo.platform)} video.`, 'success');
                hideLoading(elements.video.playerContainer);
            } else {
                showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
                hideLoading(elements.video.playerContainer);
            }
        } else {
            showMessage('Please enter a URL or select a video file.', 'error');
            hideLoading(elements.video.playerContainer);
        }

        checkReadyToPlay();
        saveSettings();
    }

    // Play Handler
    function handlePlay() {
        // Play Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.music.element);
                }
            } else if (state.music.type === 'vimeo') {
                state.music.element.play().catch(error => {
                    console.error('Error playing Vimeo audio:', error);
                    showMessage('Failed to play Vimeo audio.', 'error');
                });
            }
            // YouTube control can be added similarly if integrated
        }

        // Play Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.video.element);
                }
            } else if (state.video.type === 'vimeo') {
                state.video.element.play().catch(error => {
                    console.error('Error playing Vimeo video:', error);
                    showMessage('Failed to play Vimeo video.', 'error');
                });
            }
            // YouTube control can be added similarly if integrated
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback started!', 'success');
    }

    // Pause/Resume Handler
    function handlePauseResume() {
        if (state.isPaused) {
            resumeMedia();
        } else {
            pauseMedia();
        }
    }

    // Pause Media
    function pauseMedia() {
        // Pause Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.pause();
            } else if (state.music.type === 'vimeo') {
                state.music.element.pause().catch(error => {
                    console.error('Error pausing Vimeo audio:', error);
                    showMessage('Failed to pause Vimeo audio.', 'error');
                });
            }
        }

        // Pause Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.pause();
            } else if (state.video.type === 'vimeo') {
                state.video.element.pause().catch(error => {
                    console.error('Error pausing Vimeo video:', error);
                    showMessage('Failed to pause Vimeo video.', 'error');
                });
            }
        }

        state.isPaused = true;
        elements.controls.pauseResumeButton.textContent = 'Resume';
        showMessage('Playback paused.', 'info');
    }

    // Resume Media
    function resumeMedia() {
        // Resume Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.play();
            } else if (state.music.type === 'vimeo') {
                state.music.element.play().catch(error => {
                    console.error('Error resuming Vimeo audio:', error);
                    showMessage('Failed to resume Vimeo audio.', 'error');
                });
            }
        }

        // Resume Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.play();
            } else if (state.video.type === 'vimeo') {
                state.video.element.play().catch(error => {
                    console.error('Error resuming Vimeo video:', error);
                    showMessage('Failed to resume Vimeo video.', 'error');
                });
            }
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback resumed.', 'success');
    }

    // Play From Start Handler
    function handlePlayFromStart() {
        // Play from Start Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.currentTime = state.music.start;
                state.music.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.music.element);
                }
            } else if (state.music.type === 'vimeo') {
                state.music.element.setCurrentTime(state.music.start).then(() => {
                    return state.music.element.play();
                }).catch(error => {
                    console.error('Error playing from start in Vimeo audio:', error);
                    showMessage('Failed to play from start in Vimeo audio.', 'error');
                });
            }
        }

        // Play from Start Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.currentTime = state.video.start;
                state.video.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.video.element);
                }
            } else if (state.video.type === 'vimeo') {
                state.video.element.setCurrentTime(state.video.start).then(() => {
                    return state.video.element.play();
                }).catch(error => {
                    console.error('Error playing from start in Vimeo video:', error);
                    showMessage('Failed to play from start in Vimeo video.', 'error');
                });
            }
        }

        state.isPaused = false;
        elements.controls.pauseResumeButton.textContent = 'Pause';
        showMessage('Playback restarted!', 'success');
    }

    // === Settings Modal Functions ===
    function openSettingsModal() {
        elements.settings.modal.removeAttribute('hidden');
        elements.settings.modal.setAttribute('aria-hidden', 'false');
        elements.settings.modal.querySelector('.close-button').focus();
        trapFocus(elements.settings.modal);
    }

    function closeSettingsModal() {
        elements.settings.modal.setAttribute('hidden', '');
        elements.settings.modal.setAttribute('aria-hidden', 'true');
        elements.settings.button.focus();
        removeTrapFocus();
    }

    // === Media Embedding Functions ===

    /**
     * Embeds a YouTube video into the specified container using an iframe.
     * Mutes the video and starts at the specified time without autoplay.
     * @param {string} videoId - The YouTube video ID.
     * @param {number} start - The start time in seconds.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function embedYouTubeIframe(videoId, start, mediaType) {
        const container = elements[mediaType].playerContainer;
        container.innerHTML = ''; // Clear previous content

        let src = `https://www.youtube.com/embed/${videoId}?mute=1&start=${start}&controls=1&rel=0`;
        // Note: autoplay=1 removed to prevent auto-play

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.width = '100%';
        iframe.height = '720'; // Increased height
        iframe.frameBorder = '0';
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';

        iframe.setAttribute('title', 'YouTube video player');

        container.appendChild(iframe);

        state[mediaType] = {
            type: 'youtube',
            element: iframe,
            start: start
        };
    }

    /**
     * Embeds a Vimeo video into the specified container using the Player API.
     * Mutes the video and starts at the specified time without autoplay.
     * @param {string} videoId - The Vimeo video ID.
     * @param {number} start - The start time in seconds.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function embedVimeoPlayer(videoId, start, mediaType) {
        const container = elements[mediaType].playerContainer;
        container.innerHTML = ''; // Clear previous content

        const iframe = document.createElement('iframe');
        const src = `https://player.vimeo.com/video/${videoId}?muted=1&autopause=0&background=0`;
        iframe.src = src;
        iframe.width = '100%';
        iframe.height = '720'; // Increased height
        iframe.frameBorder = '0';
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';

        iframe.setAttribute('title', 'Vimeo video player');

        container.appendChild(iframe);

        const player = new Vimeo.Player(iframe, {
            id: videoId,
            width: container.clientWidth,
            muted: true,
            autoplay: false,
            start: start
        });

        state[mediaType] = {
            type: 'vimeo',
            element: player,
            start: start
        };

        // Ensure buffering by loading the video without autoplay
        player.setVolume(0).catch(error => {
            console.error(`Error setting volume for Vimeo ${mediaType}:`, error);
        });
    }

    // === Settings Management ===

    /**
     * Loads settings from Chrome storage.
     */
    function loadSettings() {
        try {
            chrome.storage.local.get(['mediaSettings'], (result) => {
                if (chrome.runtime.lastError) {
                    throw new Error(chrome.runtime.lastError);
                }

                if (result.mediaSettings) {
                    const { music, video, fullscreenOnPlay: fsPlay } = result.mediaSettings;

                    if (music) {
                        if (music.type === 'youtube' 
                            || music.type === 'vimeo') {
                            const url = music.type === 'youtube' 
                                ? `https://www.youtube.com/watch?v=${music.id}` 
                                : `https://vimeo.com/${music.id}`;
                            elements.music.urlInput.value = url;
                            elements.music.startInput.value = music.start || 0;
                            // Optionally, auto-load the media by triggering the load button
                            // handleLoadMusic();
                        }
                        // Handle file-based music loading if necessary
                    }

                    if (video) {
                        if (video.type === 'youtube' 
                            || video.type === 'vimeo') {
                            const url = video.type === 'youtube' 
                                ? `https://www.youtube.com/watch?v=${video.id}` 
                                : `https://vimeo.com/${video.id}`;
                            elements.video.urlInput.value = url;
                            elements.video.startInput.value = video.start || 0;
                            // Optionally, auto-load the media by triggering the load button
                            // handleLoadVideo();
                        }
                        // Handle file-based video loading if necessary
                    }

                    if (typeof fsPlay === 'boolean') {
                        state.fullscreenOnPlay = fsPlay;
                        elements.settings.fullscreenToggle.checked = fsPlay;
                    }
                }
            });
        } catch (error) {
            console.error('Error loading settings:', error);
            showMessage('Failed to load settings.', 'error');
        }
    }

    /**
     * Saves settings to Chrome storage.
     */
    function saveSettings() {
        const settings = {
            music: state.music,
            video: state.video,
            fullscreenOnPlay: state.fullscreenOnPlay
        };
        try {
            chrome.storage.local.set({ mediaSettings: settings }, () => {
                if (chrome.runtime.lastError) {
                    throw new Error(chrome.runtime.lastError);
                }
                console.log('Settings saved.');
            });
        } catch (error) {
            console.error('Error saving settings:', error);
            showMessage('Error saving settings.', 'error');
        }
    }

    /**
     * Unloads media from the specified type.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function unloadMedia(mediaType) {
        if (state[mediaType]) {
            if (state[mediaType].type === 'file') {
                if (state[mediaType].element.src) {
                    URL.revokeObjectURL(state[mediaType].element.src);
                    state[mediaType].element.src = '';
                    state[mediaType].element.remove();
                }
            } else if (state[mediaType].type === 'youtube') {
                const iframe = state[mediaType].element;
                iframe.src = ''; // Reset iframe src to stop the media
            } else if (state[mediaType].type === 'vimeo') {
                const player = state[mediaType].element;
                player.unload().catch(error => {
                    console.error(`Error unloading Vimeo ${mediaType}:`, error);
                });
            }
            state[mediaType] = null;
        }
    }

    // === Playback Controls ===

    /**
     * Enables or disables playback controls based on media loading state.
     */
    function checkReadyToPlay() {
        // Enable Play button only when at least one of audio or video is loaded
        const readyAudio = state.music 
            && (state.music.type === 'file' 
                || state.music.type === 'youtube' 
                || state.music.type === 'vimeo');
        const readyVideo = state.video 
            && (state.video.type === 'file' 
                || state.video.type === 'youtube' 
                || state.video.type === 'vimeo');
        const ready = readyAudio || readyVideo;

        elements.controls.playButton.disabled = !ready;
        elements.controls.pauseResumeButton.disabled = !ready;
        elements.controls.playStartButton.disabled = !ready;
    }

    /**
     * Enters fullscreen mode for the specified element.
     * @param {HTMLElement} element - The element to enter fullscreen.
     */
    function enterFullscreen(element) {
        if (element && element.element && element.element.requestFullscreen) {
            element.element.requestFullscreen().then(() => {
                showMessage('Entered fullscreen mode.', 'success');
            }).catch(err => {
                console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
                showMessage('Failed to enter fullscreen mode.', 'error');
            });
        } else if (element && element.requestFullscreen) {
            element.requestFullscreen().then(() => {
                showMessage('Entered fullscreen mode.', 'success');
            }).catch(err => {
                console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
                showMessage('Failed to enter fullscreen mode.', 'error');
            });
        } else {
            showMessage('Fullscreen not supported on this element.', 'error');
        }
    }

    // === New Utility Functions ===

    /**
     * Validates whether the URL is a valid YouTube or Vimeo URL.
     * @param {string} url - The URL to validate.
     * @returns {boolean} True if valid, else false.
     */
    function isValidMediaURL(url) {
        try {
            const parsedUrl = new URL(url);
            const hostname = parsedUrl.hostname.toLowerCase();
            const pathname = parsedUrl.pathname;

            // YouTube RegEx Patterns
            const youtubeRegex = /^(?:\/watch\/?|\/embed\/|\/v\/)?([a-zA-Z0-9_-]{11})$/;
            // Vimeo RegEx Patterns
            const vimeoRegex = /^\/(?:video\/)?(\d+)$/;

            if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
                // Extract YouTube video ID
                let videoId = '';
                if (hostname === 'youtu.be') {
                    videoId = pathname.slice(1);
                } else {
                    videoId = parsedUrl.searchParams.get('v') || '';
                }
                return youtubeRegex.test(`/${videoId}`);
            } else if (hostname.includes('vimeo.com')) {
                // Extract Vimeo video ID
                const match = pathname.match(vimeoRegex);
                return match && match[1].length > 0;
            }

            return false;
        } catch (e) {
            return false;
        }
    }

    /**
     * Extracts media information from the URL.
     * @param {string} url - The media URL.
     * @returns {Object|null} An object with platform and id, or null if invalid.
     */
    function extractMediaInfo(url) {
        try {
            const parsedUrl = new URL(url);
            const hostname = parsedUrl.hostname.toLowerCase();
            const pathname = parsedUrl.pathname;

            // YouTube Patterns
            if (hostname.includes('youtube.com') 
                || hostname === 'youtu.be') {
                let videoId = '';
                if (hostname === 'youtu.be') {
                    videoId = pathname.slice(1);
                } else {
                    videoId = parsedUrl.searchParams.get('v') || '';
                }

                // Validate videoId length
                if (videoId.length === 11) {
                    return { platform: 'youtube', id: videoId };
                }
            }

            // Vimeo Patterns
            if (hostname.includes('vimeo.com')) {
                const vimeoMatch = pathname.match(/^\/(?:video\/)?(\d+)$/);
                if (vimeoMatch && vimeoMatch[1]) {
                    return { platform: 'vimeo', id: vimeoMatch[1] };
                }
            }

            return null;
        } catch (e) {
            return null;
        }
    }
});
E. styles.css
Key Changes:

Increased video and audio player sizes.
Enhanced responsiveness for various screen sizes.
Improved loader visibility with increased size.

/* General Styles */
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px;
    max-width: 1000px; /* Increased max-width for larger displays */
    margin: 0 auto;
}

.section {
    width: 100%;
    margin-bottom: 20px;
    background-color: #fff;
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* Header with Settings Button and Main Title */
.header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center; /* Center the content */
    margin-bottom: 20px;
    position: relative;
}

.settings-button {
    position: absolute;
    left: 0;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 5px;
    cursor: pointer;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

.settings-button:hover {
    background-color: #f0f0f0;
    border-color: #999;
}

.settings-icon {
    width: 20px;
    height: 20px;
}

.main-title {
    font-size: 2.5em; /* Increased font size for better visibility */
    font-weight: bold;
    margin: 0;
    opacity: 0;
    animation: fadeInShake 5s forwards;
}

@keyframes fadeInShake {
    0% {
        opacity: 0;
        transform: translateX(0);
        color: #FF0000; /* Red */
    }
    10% {
        opacity: 0.2;
        transform: translateX(-10px);
        color: #FF7F00; /* Orange */
    }
    20% {
        opacity: 0.4;
        transform: translateX(10px);
        color: #FFFF00; /* Yellow */
    }
    30% {
        opacity: 0.6;
        transform: translateX(-10px);
        color: #00FF00; /* Green */
    }
    40% {
        opacity: 0.7;
        transform: translateX(10px);
        color: #0000FF; /* Blue */
    }
    50% {
        opacity: 0.8;
        transform: translateX(-10px);
        color: #4B0082; /* Indigo */
    }
    60% {
        opacity: 0.85;
        transform: translateX(10px);
        color: #8B00FF; /* Violet */
    }
    70% {
        opacity: 0.9;
        transform: translateX(-10px);
        color: #FF00FF; /* Magenta */
    }
    80% {
        opacity: 0.95;
        transform: translateX(10px);
        color: #000000; /* Black */
    }
    100% {
        opacity: 1;
        transform: translateX(0);
        color: #000000; /* Black */
    }
}

/* Controls */
.controls {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.controls button {
    padding: 12px 24px; /* Increased padding for better accessibility */
    cursor: pointer;
    border: none;
    border-radius: 5px;
    background-color: #4285f4;
    color: #fff;
    transition: background-color 0.3s ease;
    font-size: 1em;
}

.controls button:disabled {
    background-color: #a0c3ff;
    cursor: not-allowed;
}

.controls button:hover:not(:disabled) {
    background-color: #357ae8;
}

/* Modal Styles */
.modal[hidden] {
    display: none;
}

.modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex; /* Visible when not hidden */
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.modal-content {
    background-color: #fff;
    padding: 20px 30px;
    border-radius: 8px;
    width: 90%;
    max-width: 500px; /* Increased max-width for better layout */
    position: relative;
}

.close-button {
    position: absolute;
    top: 10px;
    right: 15px;
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
}

.modal-content h2 {
    margin-top: 0;
}

/* Form Elements */
fieldset {
    border: none;
    padding: 0;
}

fieldset label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

fieldset input[type="text"],
fieldset input[type="number"],
fieldset input[type="file"] {
    width: 100%;
    padding: 10px; /* Increased padding for better usability */
    margin-bottom: 15px;
    box-sizing: border-box;
    border: 1px solid #ccc;
    border-radius: 4px;
}

fieldset .load-button {
    width: 100%;
    padding: 12px;
    background-color: #34a853;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease;
    font-size: 1em;
}

fieldset .load-button:hover {
    background-color: #2c8e46;
}

/* Player Containers */
.player-container {
    margin-top: 10px;
    width: 100%;
    max-width: 100%;
    min-height: 100px; /* Increased minimum height */
    box-sizing: border-box;
    overflow: hidden; /* Prevent overflow */
}

/* Responsive Video and Audio Elements */
.player-container video,
.player-container iframe {
    width: 100%;
    height: 720px; /* Fixed height for consistency */
    border-radius: 8px;
    /* Ensure the iframe fills the container */
    display: block;
}

/* Messages */
.message-container {
    margin-top: 20px;
    width: 100%;
}

.message {
    padding: 12px;
    border-radius: 5px;
    margin-bottom: 10px;
    color: #fff;
    font-size: 1em;
}

.message.success {
    background-color: #4caf50;
}

.message.error {
    background-color: #f44336;
}

.message.info {
    background-color: #2196f3;
}

/* Loader */
.loader {
    border: 8px solid #f3f3f3; /* Light grey */
    border-top: 8px solid #4285f4; /* Blue */
    border-radius: 50%;
    width: 60px; /* Increased size for better visibility */
    height: 60px; /* Increased size for better visibility */
    animation: spin 1s linear infinite;
    margin: 0 auto;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Responsive Design */
@media (max-width: 800px) {
    .container {
        padding: 15px;
    }

    .modal-content {
        padding: 15px 20px;
    }

    .controls {
        flex-direction: column;
        width: 100%;
    }

    .controls button {
        width: 100%;
    }

    .settings-button {
        width: 35px;
        height: 35px;
    }

    .settings-icon {
        width: 18px;
        height: 18px;
    }

    .main-title {
        font-size: 2em;
    }

    .player-container video,
    .player-container iframe {
        height: 480px; /* Adjusted height for smaller screens */
    }

    .loader {
        width: 50px; /* Adjusted size for smaller screens */
        height: 50px; /* Adjusted size for smaller screens */
    }
}

@media (max-width: 500px) {
    .container {
        padding: 10px;
    }

    .controls button {
        padding: 10px;
        font-size: 0.9em;
    }

    .modal-content {
        padding: 10px 15px;
    }

    .main-title {
        font-size: 1.8em;
    }

    .player-container video,
    .player-container iframe {
        height: 360px; /* Further adjusted height for very small screens */
    }

    .loader {
        width: 40px; /* Further adjusted size for very small screens */
        height: 40px; /* Further adjusted size for very small screens */
    }
}
4. Including Vimeo's Player API Locally
Since Chrome extensions cannot load external scripts due to CSP restrictions, you need to download the Vimeo Player API and include it within your extension.

Steps to Include Vimeo Player API Locally:

Download player.js:
Visit the Vimeo Player.js GitHub Repository or directly download it from Vimeo's official source.
Save the player.js file.
Add player.js to Your Extension:
Create a lib directory inside your extension folder: myext/lib/.
Place the downloaded player.js inside the lib directory: myext/lib/player.js.
Ensure Correct Pathing in dashboard.html:
The script reference should point to the local player.js:

<script src="lib/player.js"></script>
**📌 Note:
Ensure that the player.js file is correctly placed in the lib directory as referenced in dashboard.html. The web_accessible_resources in manifest.json allows necessary access if needed.

5. Final Steps:
Verify Directory Structure: Ensure your extension's directory (myext) has the following structure:

myext/
├── background.js
├── dashboard.html
├── dashboard.js
├── styles.css
├── lib/
│   └── player.js
├── icons/
│   ├── icon16.png
│   ├── icon48.png
│   ├── icon128.png
│   └── settings.svg
└── manifest.json
Reload the Extension:
Open Chrome and navigate to chrome://extensions/.
Enable Developer mode if it's not already enabled (toggle in the top-right corner).
Click on "Load unpacked" and select your myext directory.
Ensure there are no errors. If errors persist, check the Chrome Extension Documentation for more details.
Test Functionality:
Loading Videos:
Enter a valid Vimeo URL in the Video URL field or select a local video file.
Click the "Load" button.
The video should appear in the player container with increased size and be ready to play (buffered).
Playback Controls:
Click "Play" to start playback.
Use "Pause" to pause and "Resume" to continue.
Use "Play from Start" to rewind to the specified start time and play.
Settings:
Click the Settings button (gear icon) to toggle "Full Screen on Play".
When enabled, clicking "Play" should trigger fullscreen mode for the media.
Troubleshooting:
CSP Errors:
Ensure no external scripts are being loaded. All scripts should be referenced locally.
Player Controls Not Working:
Confirm that player.js is correctly loaded and that Vimeo URLs are valid.
Video Not Buffering:
Ensure that the Vimeo URLs are correct and that the player is initialized without autoplay.
Developer Console:
Open Chrome's Developer Console (Ctrl+Shift+I or Cmd+Option+I on Mac) to check for any runtime errors and debug accordingly.
6. Additional Recommendations:
YouTube Integration:
Similar to Vimeo, if you wish to integrate YouTube's Player API for enhanced controls, download the YouTube IFrame Player API and include it locally. Update your code to interface with it accordingly.
Accessibility:
Ensure all interactive elements are accessible via keyboard and screen readers. Use appropriate aria labels and roles as you've already started.
Error Handling:
Enhance error messages and handle edge cases, such as unsupported file formats or network issues.
Performance Optimization:
Lazy-load players or optimize media handling to ensure smooth performance, especially with larger video files.
By following the above steps and using the provided updated files, your Chrome extension should function correctly without CSP violations, display larger Vimeo videos, and have fully functional playback controls. If you encounter further issues or need additional assistance, feel free to ask!


Here are some key points to consider:
1. **Content Security Policy (CSP)**: - Chrome extensions have a default CSP that disallows inline scripts and external scripts. - You can modify the CSP in your `manifest.json` file, but there are limitations.
2. **Manifest File**: - Your `manifest.json` file will need to specify permissions and CSP settings. - Example of a relaxed CSP in `manifest.json`: ```json { name: Your Extension, version: 1.0, manifest_version: 3, permissions: [ activeTab ], content_security_policy: { extension_pages: script-src 'self' https://player.vimeo.com; object-src 'self' } } ``` - Note: Manifest V3 has stricter policies compared to V2, and you should check the latest documentation for any updates.
3. **Using External Scripts**: - Instead of directly including external scripts, consider fetching the script content and injecting it into your extension's context. - Example of fetching and injecting a script: ```javascript fetch('https://player.vimeo.com/api/player.js') .then(response => response.text()) .then(scriptText => { const script = document.createElement('script'); script.textContent = scriptText; document.head.appendChild(script); }) .catch(error => console.error('Error loading Vimeo player.js:', error)); ```
4. **Permissions**: - Ensure you have the necessary permissions in your `manifest.json` file to access the Vimeo domain. - Example: ```json { permissions: [ https://player.vimeo.com/ ] } ```
5. **Security Considerations**: - Be cautious when relaxing CSP or injecting external scripts as it can introduce security risks. - Always validate and sanitize any data or scripts fetched from external sources.
6. **Alternative Approaches**: - If possible, use APIs or libraries that do not require loading external scripts directly. - Consider using iframe embeds if they meet your requirements.
In summary, while it is possible to run `player.js` from Vimeo in a Chrome extension, you need to carefully manage permissions and CSP settings in your `manifest.json` file. Always prioritize security and follow best practices to avoid introducing vulnerabilities into your extension.   so can we make vimeo urls load as wide as the load video button or bigger and start buffering but not start playing when the load video button is pressed while following csp.