{
  "manifest_version": 3,
  "name": "Sync Waves",
  "version": "1.1",
  "description": "Sync audio and video from YouTube or local files.",
  "permissions": [
    "tabs"
  ],
  "action": {
    "default_title": "Sync Waves",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  }
}

// background.js

chrome.action.onClicked.addListener((tab) => {
  // Get the extension's URL for newtab.html
  const newTabURL = chrome.runtime.getURL("newtab.html");

  // Create a new tab with newtab.html
  chrome.tabs.create({ url: newTabURL });
});

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sync Waves</title>
  <link rel="stylesheet" href="newtab.css">
</head>
<body>
  <div class="container">
    <h1>Sync Waves</h1>
    
    <!-- Audio Section -->
    <div class="section" id="audio-section">
      <h2>Audio</h2>
      <input type="url" id="audio-youtube-url" placeholder="YouTube URL">
      <input type="file" id="audio-file-input" accept="audio/*">
      <input type="number" id="audio-start-time" placeholder="Start Time (seconds)" min="0">
      <button class="load-button" id="audio-load-button">Load Audio</button>
      
      <!-- YouTube Embed for Audio Section -->
      <div class="media-container" id="audio-youtube-container">
        <div class="video-wrapper">
          <iframe id="audio-youtube-iframe" src="" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen style="display: none;"></iframe>
        </div>
      </div>
      
      <!-- Local Audio Player -->
      <div class="media-container" id="audio-local-container">
        <audio id="audio-local-player" controls style="display: none;"></audio>
      </div>
    </div>
    
    <!-- Video Section -->
    <div class="section" id="video-section">
      <h2>Video</h2>
      <input type="url" id="video-youtube-url" placeholder="YouTube URL">
      <input type="file" id="video-file-input" accept="video/*">
      <input type="number" id="video-start-time" placeholder="Start Time (seconds)" min="0">
      <button class="load-button" id="video-load-button">Load Video</button>
      
      <!-- YouTube Embed for Video Section -->
      <div class="media-container" id="video-youtube-container">
        <div class="video-wrapper">
          <iframe id="video-youtube-iframe" src="" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen style="display: none;"></iframe>
        </div>
      </div>
      
      <!-- Local Video Player -->
      <div class="media-container" id="video-local-container">
        <div class="video-wrapper">
          <video id="video-local-player" controls style="display: none;"></video>
        </div>
      </div>
    </div>
    
    <!-- Control Buttons -->
    <div class="controls">
      <button id="play-button">Play</button>
      <button id="pause-button">Pause</button>
      <button id="resume-button">Resume</button>
    </div>
  </div>
  
  <script src="newtab.js"></script>
</body>
</html>

/* newtab.css */

* {
  box-sizing: border-box;
}

body, html {
  height: 100%;
  margin: 0;
  font-family: Arial, sans-serif;
  overflow-x: hidden; /* Remove horizontal scrollbar */
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  background: linear-gradient(270deg, #ff0000, #ffa500, #ffff00, #008000, #0000ff, #4b0082, #ee82ee, #000000);
  background-size: 1600% 1600%;
  animation: gradientCycle 8s ease forwards;
}

.container {
  text-align: center;
  background: rgba(255, 255, 255, 0.85);
  padding: 20px;
  border-radius: 10px;
  width: 90%;
  max-width: 1200px;
  box-sizing: border-box;
  box-shadow: 0 4px 15px rgba(0,0,0,0.2);
  max-height: 100vh; /* Prevent clipping */
  overflow-y: auto;  /* Enable vertical scrolling */
}

/* Hide scrollbar for WebKit-based browsers */
.container::-webkit-scrollbar {
  display: none;
}

/* Central Header */
h1 {
  margin-bottom: 20px;
  font-size: 2em;
  color: #333;
}

.section {
  margin-bottom: 30px;
}

.section h2 {
  margin-bottom: 15px;
  font-size: 1.5em;
  color: #333;
}

/* Input Fields */
input[type="url"],
input[type="file"],
input[type="number"] {
  display: block;
  width: 80%;
  max-width: 400px;
  margin: 10px auto;
  padding: 8px;
  box-sizing: border-box;
  border: 1px solid rgba(204, 204, 204, 0.5); /* 50% transparent border */
  border-radius: 5px;
  background-color: rgba(255, 255, 255, 0.5); /* 50% transparent background */
}

/* Load Buttons */
.load-button {
  padding: 10px 20px;
  margin-top: 10px;
  cursor: pointer;
  background-color: rgba(0, 123, 255, 0.5); /* 50% transparent blue */
  color: white;
  border: none;
  border-radius: 5px;
  transition: background-color 0.3s;
}

.load-button:hover {
  background-color: rgba(0, 86, 179, 0.7); /* Less transparent on hover */
}

/* Control Buttons */
.controls {
  margin-top: 20px;
}

.controls button {
  padding: 10px 20px;
  margin: 5px;
  cursor: pointer;
  background-color: rgba(40, 167, 69, 0.5); /* 50% transparent green */
  color: white;
  border: none;
  border-radius: 5px;
  transition: background-color 0.3s;
}

.controls button:hover {
  background-color: rgba(30, 126, 44, 0.7); /* Less transparent on hover */
}

/* Media Containers */
.media-container {
  margin-top: 15px;
  display: flex; /* Center contents */
  justify-content: center;
}

/* Responsive Video Wrapper */
.video-wrapper {
  position: relative;
  width: 100%;
  max-width: 640px; /* Maintain consistent max width */
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.video-wrapper iframe,
.video-wrapper video {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 8px;
}

/* Local Audio Player Styling */
#audio-local-player {
  width: 80%;
  max-width: 400px;
  background-color: rgba(255, 255, 255, 0.5); /* 50% transparent */
  border: 1px solid rgba(204, 204, 204, 0.5); /* 50% transparent border */
  border-radius: 5px;
}

/* Responsive Adjustments */
@media (max-width: 800px) {
  .container {
    width: 95%;
  }
  
  .controls button {
    width: 100px;
    margin: 5px;
  }
  
  .video-wrapper {
    max-width: 100%;
  }

  #audio-local-player {
    width: 90%;
  }
}

@keyframes gradientCycle {
  0% { background-position: 0% 50%; }
  100% { background-position: 100% 50%; }
}

// newtab.js

document.addEventListener('DOMContentLoaded', () => {
  // Audio Elements
  const audioYouTubeURLInput = document.getElementById('audio-youtube-url');
  const audioFileInput = document.getElementById('audio-file-input');
  const audioStartTimeInput = document.getElementById('audio-start-time');
  const audioLoadButton = document.getElementById('audio-load-button');
  const audioLocalPlayer = document.getElementById('audio-local-player');
  const audioYouTubeIframe = document.getElementById('audio-youtube-iframe');
  const audioYouTubeContainer = document.getElementById('audio-youtube-container');
  const audioLocalContainer = document.getElementById('audio-local-container');
  
  // Video Elements
  const videoYouTubeURLInput = document.getElementById('video-youtube-url');
  const videoFileInput = document.getElementById('video-file-input');
  const videoStartTimeInput = document.getElementById('video-start-time');
  const videoLoadButton = document.getElementById('video-load-button');
  const videoLocalPlayer = document.getElementById('video-local-player');
  const videoYouTubeIframe = document.getElementById('video-youtube-iframe');
  const videoYouTubeContainer = document.getElementById('video-youtube-container');
  const videoLocalContainer = document.getElementById('video-local-container');
  
  // Control Buttons
  const playButton = document.getElementById('play-button');
  const pauseButton = document.getElementById('pause-button');
  const resumeButton = document.getElementById('resume-button');
  
  // Helper function to extract YouTube Video ID
  const extractYouTubeID = (url) => {
    const regex = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|embed)\/|.*[?&]v=)|youtu\.be\/)([^"&?/\s]{11})/;
    const match = url.match(regex);
    return match ? match[1] : null;
  };
  
  // Helper function to load YouTube Media
  const loadYouTubeMedia = (url, mediaType, isAudio = false) => {
    const videoId = extractYouTubeID(url);
    if (videoId) {
      let embedUrl = `https://www.youtube.com/embed/${videoId}?enablejsapi=1&autoplay=0`;
      if (isAudio) {
        embedUrl += `&mute=1&controls=1&loop=1&playlist=${videoId}`;
        audioYouTubeIframe.src = embedUrl;
        audioYouTubeIframe.style.display = 'block';
      } else {
        embedUrl += `&controls=1`;
        videoYouTubeIframe.src = embedUrl;
        videoYouTubeIframe.style.display = 'block';
      }
    } else {
      alert('Invalid YouTube URL');
    }
  };
  
  // Load Audio Handler
  audioLoadButton.addEventListener('click', () => {
    const url = audioYouTubeURLInput.value.trim();
    const file = audioFileInput.files[0];
    const startTime = parseInt(audioStartTimeInput.value, 10) || 0;
    
    // Reset media containers
    audioYouTubeIframe.src = '';
    audioYouTubeIframe.style.display = 'none';
    audioLocalPlayer.src = '';
    audioLocalPlayer.style.display = 'none';
    
    if (url) {
      loadYouTubeMedia(url, 'audio', true);
      // Note: Controlling playback via YouTube IFrame API is not implemented.
      // Users can manually control playback via iframe controls.
    } else if (file) {
      const fileURL = URL.createObjectURL(file);
      audioLocalPlayer.src = fileURL;
      audioLocalPlayer.currentTime = startTime;
      audioLocalPlayer.style.display = 'block';
      audioLocalPlayer.play();
    } else {
      alert('Please provide a YouTube URL or select an audio file.');
    }
  });
  
  // Load Video Handler
  videoLoadButton.addEventListener('click', () => {
    const url = videoYouTubeURLInput.value.trim();
    const file = videoFileInput.files[0];
    const startTime = parseInt(videoStartTimeInput.value, 10) || 0;
    
    // Reset media containers
    videoYouTubeIframe.src = '';
    videoYouTubeIframe.style.display = 'none';
    videoLocalPlayer.src = '';
    videoLocalPlayer.style.display = 'none';
    
    if (url) {
      loadYouTubeMedia(url, 'video', false);
      // Note: Controlling playback via YouTube IFrame API is not implemented.
      // Users can manually control playback via iframe controls.
    } else if (file) {
      const fileURL = URL.createObjectURL(file);
      videoLocalPlayer.src = fileURL;
      videoLocalPlayer.currentTime = startTime;
      videoLocalPlayer.style.display = 'block';
      videoLocalPlayer.play();
    } else {
      alert('Please provide a YouTube URL or select a video file.');
    }
  });
  
  // Play Button Handler
  playButton.addEventListener('click', () => {
    // Play Local Audio
    if (audioLocalPlayer.src) {
      audioLocalPlayer.play();
    }
    // Play Local Video
    if (videoLocalPlayer.src) {
      videoLocalPlayer.play();
    }
    // Play YouTube Audio
    if (audioYouTubeIframe.src) {
      // Playing YouTube IFrame content requires YouTube IFrame API
      // Not implemented here
      // Users need to manually click play on the iframe
      alert('Please play the YouTube audio manually using the iframe controls.');
    }
    // Play YouTube Video
    if (videoYouTubeIframe.src) {
      // Playing YouTube IFrame content requires YouTube IFrame API
      // Not implemented here
      // Users need to manually click play on the iframe
      alert('Please play the YouTube video manually using the iframe controls.');
    }
  });
  
  // Pause Button Handler
  pauseButton.addEventListener('click', () => {
    // Pause Local Audio
    if (audioLocalPlayer.src) {
      audioLocalPlayer.pause();
    }
    // Pause Local Video
    if (videoLocalPlayer.src) {
      videoLocalPlayer.pause();
    }
    // Pause YouTube Audio
    if (audioYouTubeIframe.src) {
      // Pausing YouTube IFrame content requires YouTube IFrame API
      // Not implemented here
      alert('Please pause the YouTube audio manually using the iframe controls.');
    }
    // Pause YouTube Video
    if (videoYouTubeIframe.src) {
      // Pausing YouTube IFrame content requires YouTube IFrame API
      // Not implemented here
      alert('Please pause the YouTube video manually using the iframe controls.');
    }
  });
  
  // Resume Button Handler
  resumeButton.addEventListener('click', () => {
    // Resume Local Audio
    if (audioLocalPlayer.src) {
      audioLocalPlayer.play();
    }
    // Resume Local Video
    if (videoLocalPlayer.src) {
      videoLocalPlayer.play();
    }
    // Resume YouTube Audio
    if (audioYouTubeIframe.src) {
      // Resuming YouTube IFrame content requires YouTube IFrame API
      // Not implemented here
      alert('Please resume the YouTube audio manually using the iframe controls.');
    }
    // Resume YouTube Video
    if (videoYouTubeIframe.src) {
      // Resuming YouTube IFrame content requires YouTube IFrame API
      // Not implemented here
      alert('Please resume the YouTube video manually using the iframe controls.');
    }
  });
  
  // Prevent default behavior for drag-and-drop if needed
  window.addEventListener('dragover', (e) => e.preventDefault());
  window.addEventListener('drop', (e) => e.preventDefault());
});

i only want completed updated files. the videos are not 16:9 aspect ratio. center everything vertically.