// mix-player.js - Embeddable Podcast Player by Mix AI (function() { 'use strict'; const SCRIPT_VERSION = '1.2.0'; const API_BASE = 'https://api.yourdomain.com/v1'; // Default configuration let config = { podcastId: null, theme: 'dark', primaryColor: '#00ff9d', width: '100%', height: 'auto', showResearch: true, autoPlay: false }; // Extract configuration from script tag attributes function initConfig() { const scriptTag = document.currentScript || document.querySelector('script[src*="mix-player.js"]'); if (!scriptTag) return; config.podcastId = scriptTag.getAttribute('data-podcast-id'); config.theme = scriptTag.getAttribute('data-theme') || 'dark'; config.primaryColor = scriptTag.getAttribute('data-primary-color') || '#00ff9d'; config.showResearch = scriptTag.getAttribute('data-show-research') !== 'false'; } // Create and inject the player UI function createPlayer() { const container = document.getElementById('mix-player-container') || document.createElement('div'); container.innerHTML = `

Loading podcast...

AI Research • Powered by Mix
${config.showResearch ? `
View AI Research Summary
Loading research...
` : ''}
`; // Inject styles injectStyles(); // Attach event listeners attachEventListeners(); // Load episode data if (config.podcastId) { loadEpisode(config.podcastId); } } function injectStyles() { const style = document.createElement('style'); style.textContent = ` .mix-player { background: ${config.theme === 'dark' ? '#0f0f0f' : '#ffffff'}; color: ${config.theme === 'dark' ? '#e0e0e0' : '#1a1a1a'}; border-radius: 12px; padding: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); max-width: 620px; } .mix-player-header { margin-bottom: 16px; } .mix-title { margin: 0 0 4px 0; font-size: 1.25rem; font-weight: 600; } .mix-status { font-size: 0.85rem; opacity: 0.7; } .mix-player-controls { display: flex; align-items: center; gap: 12px; margin: 16px 0; } .mix-play-btn { width: 56px; height: 56px; background: ${config.primaryColor}; color: #000; border: none; border-radius: 50%; font-size: 1.8rem; cursor: pointer; } .mix-progress-container { flex: 1; height: 6px; background: #333; border-radius: 999px; } .mix-progress { height: 100%; width: 0%; background: ${config.primaryColor}; border-radius: 999px; } .mix-research { margin-top: 16px; font-size: 0.95rem; } .mix-research-content { margin-top: 8px; line-height: 1.6; } `; document.head.appendChild(style); } async function loadEpisode(podcastId) { try { const res = await fetch(`${API_BASE}/episodes/${podcastId}`); const data = await res.json(); document.getElementById('episode-title').textContent = data.title || 'AI Research Podcast'; document.getElementById('mix-audio').src = data.audioUrl; if (config.showResearch) { document.getElementById('mix-research-content').innerHTML = `

${data.researchSummary || 'No research summary available.'}

`; } } catch (err) { console.error('Mix Player: Failed to load episode', err); document.getElementById('episode-title').textContent = 'Failed to load podcast'; } } function attachEventListeners() { const audio = document.getElementById('mix-audio'); const playBtn = document.getElementById('mix-play-btn'); const progress = document.getElementById('mix-progress'); const speedSelect = document.getElementById('mix-speed'); // Play/Pause playBtn.addEventListener('click', () => { if (audio.paused) { audio.play(); playBtn.innerHTML = '❚❚'; } else { audio.pause(); playBtn.innerHTML = ''; } }); // Progress bar audio.addEventListener('timeupdate', () => { const percent = (audio.currentTime / audio.duration) * 100; progress.style.width = percent + '%'; }); // Speed control speedSelect.addEventListener('change', () => { audio.playbackRate = parseFloat(speedSelect.value); }); } // Auto-initialize when script loads function initialize() { initConfig(); createPlayer(); } // Initialize immediately initialize(); })();
top of page
Colorful Vertical Lines

Welcome to your Dev Site

Colorful Vertical Lines
bottom of page
// ============================================= // BODY END: Cleanup, Public API & Finalization // ============================================= // Expose a public API for advanced users const MixPlayer = { version: SCRIPT_VERSION, play: function() { const audio = document.getElementById('mix-audio'); if (audio) audio.play(); }, pause: function() { const audio = document.getElementById('mix-audio'); if (audio) audio.pause(); }, setSpeed: function(speed) { const audio = document.getElementById('mix-audio'); if (audio && speed >= 0.5 && speed <= 3.0) { audio.playbackRate = speed; const select = document.getElementById('mix-speed'); if (select) select.value = speed; } }, loadEpisode: function(podcastId) { config.podcastId = podcastId; loadEpisode(podcastId); }, destroy: function() { const player = document.getElementById('mix-player'); if (player) player.remove(); }, on: function(event, callback) { // Simple event system (expandable) if (event === 'ready') { // Trigger immediately for now setTimeout(() => callback(), 100); } } }; // Attach public API to window window.MixPlayer = MixPlayer; // Error handling wrapper function safeExecute(fn, errorMsg) { try { fn(); } catch (error) { console.error(`[MixPlayer] ${errorMsg}:`, error); } } // Graceful initialization with error boundary function safeInitialize() { try { initConfig(); createPlayer(); console.log(`%c🎙️ MixPlayer v${SCRIPT_VERSION} initialized successfully`, 'color: #00ff9d; font-weight: bold;'); } catch (error) { console.error('[MixPlayer] Failed to initialize:', error); // Fallback: Show minimal error message in container const container = document.getElementById('mix-player-container'); if (container) { container.innerHTML = `
⚠️ Mix Player failed to load. Please check console for details.
`; } } } // Final auto-initialization with protection if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', safeInitialize); } else { safeInitialize(); } // Handle dynamic script injection (for SPAs) window.addEventListener('mix-player-reload', safeInitialize); })();