Kode HTML/JavaScript Pemutar Musik untuk widget Blogger

 <!DOCTYPE html>

<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Widget Pemutar Musik</title>
    <!-- Load Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        /* Mengatur font global dan latar belakang gelap */
        body {
            font-family: 'Inter', sans-serif;
            background-color: #f1f5f9; /* Latar belakang cerah untuk blog */
            color: #1e293b; /* Teks abu-abu tua (slate-800) */
        }
        /* Style untuk kotak pesan kustom */
        #messageBox {
            animation: fadeInOut 3s forwards;
        }
        @keyframes fadeInOut {
            0% { opacity: 0; transform: translateY(-10px); }
            10% { opacity: 1; transform: translateY(0); }
            90% { opacity: 1; transform: translateY(0); }
            100% { opacity: 0; transform: translateY(-10px); }
        }
    </style>
    <!-- Font Awesome untuk ikon tombol -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body class="p-4">

    <!-- Kontainer utama yang mudah disematkan -->
    <div class="max-w-xl mx-auto my-8 bg-white p-6 rounded-2xl shadow-xl border border-gray-200">

        <h1 class="text-3xl font-extrabold text-center mb-6 text-gray-900">Pemutar Musik</h1>

        <div class="flex flex-col md:flex-row items-start justify-center gap-6">
       
            <!-- Kontainer pemutar musik -->
            <div class="bg-gray-50 p-6 rounded-xl shadow-lg w-full md:w-1/2 flex-shrink-0 flex flex-col items-center border border-gray-100">
                <!-- Informasi lagu -->
                <div id="playerContent" class="relative w-full pb-[100%] rounded-lg shadow-md mb-4 flex items-center justify-center overflow-hidden">
                    <!-- Gambar sampul default -->
                    <img id="albumArt" class="absolute inset-0 w-full h-full object-cover rounded-lg" src="https://placehold.co/400x400/1e293b/cbd5e1?text=Album+Art" alt="Album Art">
                    <!-- iframe untuk embed content -->
                    <iframe id="embedFrame" class="absolute inset-0 w-full h-full hidden rounded-lg" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
                    <!-- Elemen audio tersembunyi -->
                    <audio id="audioElement" class="hidden"></audio>
                </div>

                <h2 id="songTitle" class="text-xl font-bold text-center mb-1 text-gray-900">Judul Lagu</h2>
                <h3 id="artistName" class="text-gray-500 text-md text-center mb-4">Nama Artis</h3>
                <p id="embedInstruction" class="text-xs text-yellow-500 mb-2 hidden">
                    <i class="fas fa-info-circle mr-1"></i> Klik pemutar di dalam bingkai untuk memulai.
                </p>

                <!-- Bilah kemajuan (progress bar) dan kontrol waktu -->
                <div id="progressBarControls" class="w-full flex items-center justify-between space-x-2 text-sm text-gray-500">
                    <span id="currentTime">0:00</span>
                    <div class="flex-grow bg-gray-200 h-2 rounded-full cursor-pointer overflow-hidden" onclick="seek(event)">
                        <div id="progressBar" class="bg-blue-600 h-full w-0 rounded-full"></div>
                    </div>
                    <span id="duration">0:00</span>
                </div>

                <!-- Kontrol pemutar -->
                <div class="flex items-center justify-center space-x-4 mt-6">
                    <!-- Tombol Putar Acak -->
                    <button id="shuffleBtn" class="text-gray-400 hover:text-blue-600 transition-colors duration-200">
                        <i class="fas fa-random text-xl"></i>
                    </button>
                    <button id="prevBtn" class="text-gray-400 hover:text-blue-600 transition-colors duration-200">
                        <i class="fas fa-backward text-2xl"></i>
                    </button>
                    <button id="playPauseBtn" class="bg-blue-600 hover:bg-blue-700 text-white p-3 rounded-full shadow-lg transition-all duration-200 transform hover:scale-110">
                        <i id="playPauseIcon" class="fas fa-play text-xl"></i>
                    </button>
                    <button id="nextBtn" class="text-gray-400 hover:text-blue-600 transition-colors duration-200">
                        <i class="fas fa-forward text-2xl"></i>
                    </button>
                    <!-- Tombol Putar Semua -->
                    <button id="repeatAllBtn" class="text-gray-400 hover:text-blue-600 transition-colors duration-200">
                        <i class="fas fa-redo-alt text-xl"></i>
                    </button>
                    <!-- Tombol Rekomendasi Gemini API -->
                    <button id="recommendBtn" class="text-gray-400 hover:text-green-600 transition-colors duration-200">
                        <i class="fas fa-wand-magic text-xl"></i>
                    </button>
                </div>
            </div>

            <!-- Kolom untuk menambahkan musik dan menampilkan daftar lagu -->
            <div class="bg-gray-50 p-6 rounded-xl shadow-lg w-full md:w-1/2 flex-shrink-0 border border-gray-100">
                <h3 class="text-xl font-bold text-center mb-4 text-gray-900">Kelola Playlist</h3>
                <div class="space-y-4">
                    <!-- Input unggah file -->
                    <div>
                        <label for="mp3FileInput" class="block text-sm font-medium text-gray-500 mb-1">Upload file MP3</label>
                        <input type="file" id="mp3FileInput" accept=".mp3" class="w-full text-sm text-gray-600 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:font-semibold file:bg-blue-600 file:text-white hover:file:bg-blue-700">
                    </div>
                    <!-- Kolom tempelkan URL embed -->
                    <div class="pt-2">
                        <label for="newEmbedUrl" class="block text-sm font-medium text-gray-500 mb-1">Embed URL (YouTube, Spotify)</label>
                        <input type="url" id="newEmbedUrl" class="w-full p-2 rounded-md bg-white text-gray-900 border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm" placeholder="Contoh: https://www.youtube.com/watch?v=...">
                        <button id="addEmbedBtn" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-md shadow-lg transition-colors duration-200 mt-2 text-sm">
                            Tambahkan Embed
                        </button>
                    </div>
                </div>
               
                <!-- Daftar Lagu -->
                <div class="mt-8">
                    <h4 class="text-md font-bold mb-2 text-gray-900">Daftar Putar</h4>
                    <!-- Input pencarian -->
                    <input type="text" id="searchInput" placeholder="Cari lagu atau artis..." class="w-full p-2 rounded-md bg-white text-gray-900 border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 mb-4 text-sm">
                   
                    <ul id="playlist" class="space-y-2 text-gray-600 text-sm">
                        <!-- Daftar lagu akan diisi di sini oleh JavaScript -->
                    </ul>
                </div>

                <!-- Kotak pesan untuk konfirmasi/error -->
                <div id="messageBox" class="mt-4 p-3 bg-green-500 text-white rounded-md text-center text-sm hidden"></div>
            </div>

        </div>
    </div>

    <!-- Modal untuk rekomendasi lagu -->
    <div id="recommendationModal" class="fixed inset-0 bg-gray-900 bg-opacity-75 flex items-center justify-center p-4 hidden z-50">
        <div class="bg-white p-8 rounded-xl shadow-lg w-full max-w-md text-gray-900">
            <div class="flex justify-between items-center mb-4">
                <h4 class="text-xl font-bold">✨ Rekomendasi Lagu Ajaib</h4>
                <button id="closeModalBtn" class="text-gray-400 hover:text-gray-900">&times;</button>
            </div>
            <p id="recommendationMessage" class="mb-4 text-gray-600">Memuat rekomendasi...</p>
            <ul id="recommendationList" class="space-y-2 text-gray-700">
                <!-- Rekomendasi akan diisi di sini -->
            </ul>
        </div>
    </div>

    <script>
        // Mendapatkan elemen DOM
        const playPauseBtn = document.getElementById('playPauseBtn');
        const playPauseIcon = document.getElementById('playPauseIcon');
        const prevBtn = document.getElementById('prevBtn');
        const nextBtn = document.getElementById('nextBtn');
        const shuffleBtn = document.getElementById('shuffleBtn');
        const repeatAllBtn = document.getElementById('repeatAllBtn');
        const recommendBtn = document.getElementById('recommendBtn');
        const progressBarContainer = document.getElementById('progressBarControls');
        const progressBar = document.getElementById('progressBar');
        const songTitle = document.getElementById('songTitle');
        const artistName = document.getElementById('artistName');
        const albumArt = document.getElementById('albumArt');
        const embedFrame = document.getElementById('embedFrame');
        const audioElement = document.getElementById('audioElement');
        const currentTimeSpan = document.getElementById('currentTime');
        const durationSpan = document.getElementById('duration');
        const messageBox = document.getElementById('messageBox');
        const playlistElement = document.getElementById('playlist');
        const embedInstruction = document.getElementById('embedInstruction');

        // Elemen untuk menambahkan file MP3 dan URL baru
        const mp3FileInput = document.getElementById('mp3FileInput');
        const newEmbedUrlInput = document.getElementById('newEmbedUrl');
        const addEmbedBtn = document.getElementById('addEmbedBtn');
       
        // Elemen pencarian
        const searchInput = document.getElementById('searchInput');

        // Elemen Modal
        const recommendationModal = document.getElementById('recommendationModal');
        const closeModalBtn = document.getElementById('closeModalBtn');
        const recommendationMessage = document.getElementById('recommendationMessage');
        const recommendationList = document.getElementById('recommendationList');

        // Data daftar putar (sekarang kosong)
        const songs = [];

        let currentSongIndex = 0;
        let playingFromList = false;
        let isShuffleOn = false;
        let isRepeatAllOn = false;
       
        /**
         * @description Mengonversi waktu dari detik ke format m:dd.
         * @param {number} seconds - Waktu dalam detik.
         * @returns {string} - Waktu dalam format menit dan detik.
         */
        function formatTime(seconds) {
            const minutes = Math.floor(seconds / 60);
            const remainingSeconds = Math.floor(seconds % 60);
            return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
        }

        /**
         * @description Memperbarui UI pemutar musik berdasarkan lagu yang sedang diputar.
         */
        function updatePlayer() {
            if (songs.length === 0) {
                // Tangani kasus di mana tidak ada lagu
                songTitle.textContent = "Tidak ada lagu";
                artistName.textContent = "";
                albumArt.src = "https://placehold.co/400x400/f1f5f9/1e293b?text=No+Music";
                albumArt.classList.remove('hidden');
                embedFrame.classList.add('hidden');
                audioElement.src = "";
                progressBarContainer.classList.add('hidden');
                playPauseBtn.disabled = true;
                prevBtn.disabled = true;
                nextBtn.disabled = true;
                shuffleBtn.disabled = true;
                repeatAllBtn.disabled = true;
                recommendBtn.disabled = true;
                embedInstruction.classList.add('hidden');
                return;
            }
           
            const song = songs[currentSongIndex];
           
            // Aktifkan kontrol
            playPauseBtn.disabled = false;
            prevBtn.disabled = false;
            nextBtn.disabled = false;
            shuffleBtn.disabled = false;
            repeatAllBtn.disabled = false;
            recommendBtn.disabled = false;

            songTitle.textContent = song.title;
            artistName.textContent = song.artist;
            albumArt.src = song.image || "https://placehold.co/400x400/f1f5f9/1e293b?text=No+Art";

            if (song.embedUrl) {
                // Tampilkan iframe untuk konten embed
                albumArt.classList.add('hidden');
                embedFrame.classList.remove('hidden');
                embedFrame.src = song.embedUrl;
                // Sembunyikan kontrol khusus audio
                progressBarContainer.classList.add('hidden');
                audioElement.pause();
                playPauseIcon.classList.remove('fa-pause');
                playPauseIcon.classList.add('fa-play');
                // Tampilkan instruksi untuk embed
                embedInstruction.classList.remove('hidden');
                playPauseBtn.classList.add('opacity-50', 'cursor-not-allowed');
                playPauseBtn.disabled = true;
            } else if (song.audioUrl) {
                // Tampilkan gambar album dan kontrol untuk audio standar
                albumArt.classList.remove('hidden');
                embedFrame.classList.add('hidden');
                embedFrame.src = "";
                audioElement.src = song.audioUrl;
                progressBarContainer.classList.remove('hidden');
                audioElement.load();
               
                // Atur ikon putar/jeda dengan benar
                if (playingFromList || !audioElement.paused) {
                    playPauseIcon.classList.remove('fa-play');
                    playPauseIcon.classList.add('fa-pause');
                } else {
                    playPauseIcon.classList.remove('fa-pause');
                    playPauseIcon.classList.add('fa-play');
                }
                // Sembunyikan instruksi untuk embed
                embedInstruction.classList.add('hidden');
                playPauseBtn.classList.remove('opacity-50', 'cursor-not-allowed');
                playPauseBtn.disabled = false;
            }

            // Perbarui visual tombol shuffle dan repeat
            if (isShuffleOn) {
                shuffleBtn.classList.add('text-blue-600');
            } else {
                shuffleBtn.classList.remove('text-blue-600');
            }

            if (isRepeatAllOn) {
                repeatAllBtn.classList.add('text-blue-600');
            } else {
                repeatAllBtn.classList.remove('text-blue-600');
            }
        }

        /**
         * @description Memutar atau menjeda audio.
         */
        function togglePlayPause() {
            if (songs.length === 0 || songs[currentSongIndex].embedUrl) {
                return;
            }
           
            if (audioElement.paused) {
                audioElement.play();
                playPauseIcon.classList.remove('fa-play');
                playPauseIcon.classList.add('fa-pause');
            } else {
                audioElement.pause();
                playPauseIcon.classList.remove('fa-pause');
                playPauseIcon.classList.add('fa-play');
            }
        }

        /**
         * @description Menghapus lagu dari daftar putar.
         * @param {number} index - Indeks lagu yang akan dihapus.
         */
        function deleteSong(index) {
            const deletedSongTitle = songs[index].title;
            songs.splice(index, 1);
            showMessage(`Lagu "${deletedSongTitle}" dihapus.`, 'bg-red-500');

            if (index === currentSongIndex) {
                audioElement.pause();
                audioElement.src = '';
                currentSongIndex = 0;
                playingFromList = false;
            } else if (index < currentSongIndex) {
                currentSongIndex--;
            }

            updatePlayer();
            renderPlaylist();
        }

        /**
         * @description Memperbarui daftar putar di UI.
         * @param {array} songsToShow - Array lagu opsional untuk ditampilkan (digunakan untuk pencarian).
         */
        function renderPlaylist(songsToShow = songs) {
            playlistElement.innerHTML = '';
            songsToShow.forEach((song, index) => {
                const listItem = document.createElement('li');
                listItem.classList.add('flex', 'items-center', 'justify-between', 'p-2', 'rounded-md', 'hover:bg-gray-100', 'transition-colors');
               
                const songInfo = document.createElement('div');
                songInfo.classList.add('flex', 'items-center', 'flex-grow', 'cursor-pointer');

                const originalIndex = songs.findIndex(s => s === song);
                songInfo.onclick = () => playSongByIndex(originalIndex);

                const icon = document.createElement('i');
                if (song.embedUrl) {
                    icon.classList.add('fas', 'fa-link', 'text-blue-400', 'mr-2');
                } else {
                    icon.classList.add('fas', 'fa-music', 'text-blue-400', 'mr-2');
                }
               
                const songText = document.createElement('span');
                songText.textContent = `${originalIndex + 1}. ${song.title}`;
               
                songInfo.appendChild(icon);
                songInfo.appendChild(songText);
                listItem.appendChild(songInfo);

                const deleteBtn = document.createElement('button');
                deleteBtn.classList.add('text-gray-400', 'hover:text-red-500', 'transition-colors', 'ml-4');
                deleteBtn.innerHTML = '<i class="fas fa-trash-alt"></i>';
                deleteBtn.onclick = (e) => {
                    e.stopPropagation();
                    deleteSong(originalIndex);
                };
                listItem.appendChild(deleteBtn);

                if (originalIndex === currentSongIndex) {
                    listItem.classList.add('bg-blue-100', 'text-blue-800', 'font-semibold');
                }
               
                playlistElement.appendChild(listItem);
            });
        }
       
        /**
         * @description Memutar lagu berdasarkan indeks.
         * @param {number} index - Indeks lagu yang akan diputar.
         */
        function playSongByIndex(index) {
            if (index >= 0 && index < songs.length) {
                currentSongIndex = index;
                playingFromList = true;
                updatePlayer();
                if (!songs[index].embedUrl) {
                    audioElement.play();
                }
                renderPlaylist(getFilteredSongs());
            }
        }

        // Event listener untuk pembaruan waktu audio
        audioElement.addEventListener('timeupdate', () => {
            const duration = audioElement.duration;
            if (!isNaN(duration)) {
                const progressPercentage = (audioElement.currentTime / duration) * 100;
                progressBar.style.width = `${progressPercentage}%`;
                currentTimeSpan.textContent = formatTime(audioElement.currentTime);
                durationSpan.textContent = formatTime(duration);
            }
        });
       
        // Event listener untuk metadata audio yang dimuat
        audioElement.addEventListener('loadedmetadata', () => {
            if (!isNaN(audioElement.duration)) {
                durationSpan.textContent = formatTime(audioElement.duration);
            }
        });

        // Event listener untuk audio selesai
        audioElement.addEventListener('ended', () => {
            if (isShuffleOn) {
                playRandomSong();
            } else if (isRepeatAllOn) {
                nextSong();
            } else {
                if (currentSongIndex === songs.length - 1) {
                    audioElement.pause();
                    playPauseIcon.classList.remove('fa-pause');
                    playPauseIcon.classList.add('fa-play');
                } else {
                    nextSong();
                }
            }
        });

        // Mencari audio saat bilah kemajuan diklik
        function seek(e) {
            if (songs.length === 0 || songs[currentSongIndex].embedUrl) {
                return;
            }
            const seekTime = (e.offsetX / progressBarContainer.offsetWidth) * audioElement.duration;
            audioElement.currentTime = seekTime;
        }

        // Memutar lagu berikutnya
        function nextSong() {
            if (songs.length === 0) {
                return;
            }
            if (isShuffleOn) {
                playRandomSong();
            } else {
                const wasPlaying = !audioElement.paused;
                currentSongIndex = (currentSongIndex + 1) % songs.length;
                updatePlayer();
                if (wasPlaying && !songs[currentSongIndex].embedUrl) {
                    audioElement.play();
                }
                renderPlaylist(getFilteredSongs());
            }
        }

        // Memutar lagu sebelumnya
        function prevSong() {
            if (songs.length === 0) {
                return;
            }
            if (isShuffleOn) {
                playRandomSong();
            } else {
                const wasPlaying = !audioElement.paused;
                currentSongIndex = (currentSongIndex - 1 + songs.length) % songs.length;
                updatePlayer();
                if (wasPlaying && !songs[currentSongIndex].embedUrl) {
                    audioElement.play();
                }
                renderPlaylist(getFilteredSongs());
            }
        }

        // Memutar lagu secara acak
        function playRandomSong() {
            if (songs.length === 0) return;
            const wasPlaying = !audioElement.paused;
            let newIndex;
            do {
                newIndex = Math.floor(Math.random() * songs.length);
            } while (newIndex === currentSongIndex && songs.length > 1);

            currentSongIndex = newIndex;
            updatePlayer();
            if (wasPlaying && !songs[currentSongIndex].embedUrl) {
                audioElement.play();
            }
            renderPlaylist(getFilteredSongs());
        }

        // Mengganti status shuffle
        function toggleShuffle() {
            isShuffleOn = !isShuffleOn;
            updatePlayer();
        }
       
        // Mengganti status repeat all
        function toggleRepeatAll() {
            isRepeatAllOn = !isRepeatAllOn;
            updatePlayer();
        }

        // Menambahkan file MP3 baru dari input unggah
        function addMp3File() {
            const file = mp3FileInput.files[0];
           
            if (!file) {
                showMessage("Harap pilih file MP3.", 'bg-red-500');
                return;
            }

            const audioUrl = URL.createObjectURL(file);

            const newSong = {
                title: file.name,
                artist: "Dari perangkat lokal",
                audioUrl: audioUrl,
                image: "https://placehold.co/400x400/f1f5f9/1e293b?text=MP3",
                embedUrl: null,
            };
            songs.push(newSong);

            showMessage(`File "${file.name}" berhasil ditambahkan!`, 'bg-green-500');

            mp3FileInput.value = '';
           
            if (songs.length === 1) {
                currentSongIndex = 0;
                updatePlayer();
            }

            renderPlaylist();
        }

        // Mengekstrak ID video YouTube dari berbagai format URL
        function extractYouTubeVideoId(url) {
            const regex = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/;
            const match = url.match(regex);
            return (match && match[1]) ? match[1] : null;
        }

        /**
         * @description Menggunakan Gemini API untuk mengambil judul dan artis dari URL.
         * @param {string} url - URL lagu.
         * @returns {Promise<object>} - Objek berisi judul dan artis.
         */
        async function getSongInfoFromUrl(url) {
            const prompt = `Identifikasi judul lagu dan artis dari URL ini: ${url}. Jika informasi tersedia, berikan dalam format JSON seperti ini: {"title": "Judul Lagu", "artist": "Nama Artis"}. Jika tidak, berikan respons JSON {"title": "Lagu Embed", "artist": "Artis Tidak Dikenal"}.`;
            const chatHistory = [{ role: "user", parts: [{ text: prompt }] }];
            const payload = {
                contents: chatHistory,
                generationConfig: {
                    responseMimeType: "application/json",
                    responseSchema: {
                        type: "OBJECT",
                        properties: {
                            "title": { "type": "STRING" },
                            "artist": { "type": "STRING" }
                        },
                        "propertyOrdering": ["title", "artist"]
                    }
                }
            };
            const apiKey = "";
            const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`;

            try {
                const response = await fetch(apiUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(payload)
                });
                const result = await response.json();
                if (result.candidates && result.candidates.length > 0 && result.candidates[0].content) {
                    const jsonString = result.candidates[0].content.parts[0].text;
                    return JSON.parse(jsonString);
                }
            } catch (error) {
                console.error("Gagal mengambil info lagu dengan Gemini API:", error);
            }
            return { title: "Lagu Embed", artist: "Artis Tidak Dikenal" };
        }

        // Menambahkan lagu baru dari URL embed
        async function addEmbedSong() {
            let embedUrl = newEmbedUrlInput.value;
           
            if (!embedUrl) {
                showMessage("Harap isi URL Embed.", 'bg-red-500');
                return;
            }

            addEmbedBtn.textContent = "Memuat...";
            addEmbedBtn.disabled = true;
            newEmbedUrlInput.disabled = true;

            let finalEmbedUrl = embedUrl;

            // Mengonversi URL Spotify biasa menjadi URL embed
            if (finalEmbedUrl.includes('open.spotify.com/') && !finalEmbedUrl.includes('/embed/')) {
                const parts = finalEmbedUrl.split('open.spotify.com/');
                if (parts.length > 1) {
                    finalEmbedUrl = `https://open.spotify.com/embed/${parts[1]}`;
                }
            }

            // Mengambil judul dan artis menggunakan Gemini API
            const songInfo = await getSongInfoFromUrl(embedUrl);

            const newSong = {
                title: songInfo.title,
                artist: songInfo.artist,
                audioUrl: null,
                image: "https://placehold.co/400x400/f1f5f9/1e293b?text=Embed",
                embedUrl: finalEmbedUrl,
            };
            songs.push(newSong);

            showMessage(`URL Embed untuk "${newSong.title}" berhasil ditambahkan!`, 'bg-green-500');

            newEmbedUrlInput.value = '';
            addEmbedBtn.textContent = "Tambahkan Embed";
            addEmbedBtn.disabled = false;
            newEmbedUrlInput.disabled = false;
           
            if (songs.length === 1) {
                currentSongIndex = 0;
                updatePlayer();
            }
            renderPlaylist();
        }

        /**
         * @description Menampilkan kotak pesan sementara.
         * @param {string} message - Pesan yang akan ditampilkan.
         * @param {string} colorClass - Kelas warna Tailwind CSS untuk latar belakang.
         */
        function showMessage(message, colorClass) {
            messageBox.textContent = message;
            messageBox.className = `mt-4 p-3 ${colorClass} text-white rounded-md text-center text-sm`;
            setTimeout(() => {
                messageBox.classList.add('hidden');
            }, 3000);
            messageBox.classList.remove('hidden');
        }

        /**
         * @description Mengambil daftar lagu yang difilter berdasarkan input pencarian.
         * @returns {array} - Array lagu yang difilter.
         */
        function getFilteredSongs() {
            const searchTerm = searchInput.value.toLowerCase();
            if (!searchTerm) {
                return songs;
            }
            return songs.filter(song =>
                song.title.toLowerCase().includes(searchTerm) ||
                song.artist.toLowerCase().includes(searchTerm)
            );
        }

        /**
         * @description Menggunakan Gemini API untuk merekomendasikan lagu.
         */
        async function getRecommendations() {
            if (songs.length === 0) {
                showMessage("Harap tambahkan lagu terlebih dahulu untuk mendapatkan rekomendasi.", 'bg-red-500');
                return;
            }
           
            // Tampilkan modal loading
            recommendationModal.classList.remove('hidden');
            recommendationMessage.textContent = "Memuat rekomendasi...";
            recommendationList.innerHTML = '';
           
            const currentSong = songs[currentSongIndex];
            const prompt = `Berikan 3 rekomendasi lagu yang mirip dengan "${currentSong.title}" oleh "${currentSong.artist}". Berikan respons dalam format daftar berpoin yang hanya berisi judul lagu dan artis, seperti ini:\n- Judul Lagu oleh Nama Artis\n- Judul Lagu oleh Nama Artis\n- Judul Lagu oleh Nama Artis`;
           
            const chatHistory = [{ role: "user", parts: [{ text: prompt }] }];
            const payload = { contents: chatHistory };
            const apiKey = "";
            const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`;

            try {
                const response = await fetch(apiUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(payload)
                });
               
                const result = await response.json();
               
                if (result.candidates && result.candidates.length > 0 && result.candidates[0].content) {
                    const text = result.candidates[0].content.parts[0].text;
                    const recommendations = text.split('\n').filter(line => line.trim() !== '');

                    if (recommendations.length > 0) {
                        recommendationMessage.textContent = "Berikut adalah rekomendasi untuk Anda:";
                        recommendationList.innerHTML = ''; // Kosongkan daftar
                        recommendations.forEach(rec => {
                            const li = document.createElement('li');
                            li.textContent = rec.trim().replace(/^-/, ''); // Hapus bullet point
                            recommendationList.appendChild(li);
                        });
                    } else {
                        recommendationMessage.textContent = "Maaf, tidak dapat menemukan rekomendasi.";
                    }
                } else {
                    recommendationMessage.textContent = "Maaf, terjadi kesalahan saat memproses permintaan Anda.";
                }
            } catch (error) {
                console.error("Gagal mendapatkan rekomendasi:", error);
                recommendationMessage.textContent = "Maaf, terjadi kesalahan saat menghubungkan ke server.";
            }
        }


        // Event listener ke tombol dan input
        playPauseBtn.addEventListener('click', togglePlayPause);
        nextBtn.addEventListener('click', nextSong);
        prevBtn.addEventListener('click', prevSong);
        shuffleBtn.addEventListener('click', toggleShuffle);
        repeatAllBtn.addEventListener('click', toggleRepeatAll);
        recommendBtn.addEventListener('click', getRecommendations);
        mp3FileInput.addEventListener('change', addMp3File);
        addEmbedBtn.addEventListener('click', addEmbedSong);
        searchInput.addEventListener('input', () => {
            renderPlaylist(getFilteredSongs());
        });
       
        // Event listener untuk menutup modal
        closeModalBtn.addEventListener('click', () => {
            recommendationModal.classList.add('hidden');
        });
       
        // Menutup modal jika klik di luar kotak
        window.addEventListener('click', (e) => {
            if (e.target === recommendationModal) {
                recommendationModal.classList.add('hidden');
            }
        });
       
        // Pemuatan awal pemutar
        window.onload = () => {
            updatePlayer();
            renderPlaylist();
        };
    </script>
</body>
</html>

Posting Komentar

0 Komentar