WEBLEB
Inicio
Editora de código
Iniciar sesión
Pro
Español
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Clon de Spotify: reproductor de música web
61
TheDoc
Abrir en el editor
Publica tu código
Recomendado
2 June 2025
Un código de abfomap
4 December 2024
¡Feliz árbol de Navidad!
18 May 2024
Página principal del portafolio
HTML
Copy
Spotify Clone
Start
Suche
Bibliothek
Neue Playlist
Playlists
Meine Lieblingssongs
Chill Vibes
Workout
←
→
TheDoc
Top Hits 2024
Die besten Songs des Jahres – regelmäßig aktualisiert. Perfekt für jede Stimmung!
Entdecke Musik
Shape of You
Ed Sheeran
Blinding Lights
The Weeknd
Levitating
Dua Lipa
Believer
Imagine Dragons
bad guy
Billie Eilish
Uptown Funk
Mark Ronson ft. Bruno Mars
Poker Face
Lady Gaga
Bohemian Rhapsody
Queen
Hello
Adele
Despacito
Luis Fonsi ft. Daddy Yankee
CSS
Copy
body { background: #181818; color: #fff; font-family: 'Segoe UI', Arial, sans-serif; margin: 0; min-height: 100vh; } .container { display: flex; min-height: 100vh; } .sidebar { background: #000; color: #b3b3b3; width: 260px; display: flex; flex-direction: column; justify-content: space-between; padding: 0; min-height: 100vh; } .sidebar-header { padding: 32px 24px 16px 24px; } .spotify-logo { width: 120px; margin-bottom: 10px; } .sidebar-nav { list-style: none; padding: 0 0 0 24px; margin: 0; } .sidebar-nav li { padding: 12px 0; font-size: 1.1em; cursor: pointer; display: flex; align-items: center; gap: 12px; transition: color 0.2s; } .sidebar-nav li.active, .sidebar-nav li:hover { color: #1db954; } .icon { font-size: 1.2em; display: inline-flex; align-items: center; justify-content: center; } .new-playlist-btn { margin: 18px 24px 0 24px; background: #1db954; color: #fff; border: none; border-radius: 20px; padding: 10px 18px; font-size: 1em; font-weight: bold; cursor: pointer; display: flex; align-items: center; gap: 8px; transition: background 0.2s; } .new-playlist-btn:hover { background: #1ed760; } .playlist-section { padding: 24px; } .playlist-section h3 { color: #fff; font-size: 1em; margin-bottom: 10px; } .playlist-section ul { list-style: none; padding: 0; margin: 0; } .playlist-section ul li { font-size: 0.98em; color: #b3b3b3; padding: 6px 0; cursor: pointer; display: flex; align-items: center; gap: 8px; transition: color 0.2s; } .playlist-section ul li:hover { color: #fff; } .sidebar-footer { display: flex; align-items: center; gap: 12px; padding: 24px; border-top: 1px solid #282828; margin-top: auto; } .user-avatar { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; } .username { color: #fff; font-size: 1em; flex: 1; } .settings-icon { cursor: pointer; margin-left: auto; } .main-content { flex: 1; display: flex; flex-direction: column; min-width: 0; background: linear-gradient(180deg, #222 0%, #181818 100%); } header { background: transparent; padding: 24px 32px 12px 32px; display: flex; align-items: center; justify-content: space-between; } .header-left { display: flex; gap: 8px; } .nav-arrow { background: #181818; border: none; color: #b3b3b3; border-radius: 50%; width: 32px; height: 32px; font-size: 1.2em; cursor: pointer; margin-right: 4px; transition: background 0.2s, color 0.2s; } .nav-arrow:hover { background: #282828; color: #fff; } #search { background: #282828; border: none; border-radius: 20px; color: #fff; padding: 10px 18px; font-size: 1em; width: 260px; outline: none; margin: 0 16px; } .header-right { display: flex; align-items: center; gap: 12px; } .header-avatar { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; } .playlist-banner { display: flex; align-items: center; gap: 28px; background: linear-gradient(90deg, #1db954 0%, #181818 100%); border-radius: 18px; margin: 18px 0 32px 0; padding: 24px 32px; box-shadow: 0 2px 16px #1db95422; } .playlist-cover { width: 110px; height: 110px; border-radius: 12px; object-fit: cover; box-shadow: 0 2px 12px #0008; } .playlist-info h2 { margin: 0 0 8px 0; font-size: 2em; color: #fff; } .playlist-info p { margin: 0; color: #e0e0e0; font-size: 1.1em; } main { padding: 10px 32px 120px 32px; } .song-list ul { list-style: none; padding: 0; margin: 0; } .song-list li { display: flex; align-items: center; gap: 18px; padding: 14px 0; border-bottom: 1px solid #282828; cursor: pointer; transition: background 0.2s; position: relative; } .song-list li:hover { background: #232323; } .song-list li.playing { background: #282828; border-left: 4px solid #1db954; } .song-play-btn { background: #1db954; border: none; border-radius: 50%; width: 38px; height: 38px; display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.2s; position: absolute; left: -48px; top: 50%; transform: translateY(-50%); z-index: 2; cursor: pointer; box-shadow: 0 2px 8px #1db95444; } .song-list li:hover .song-play-btn { opacity: 1; } .cover { width: 56px; height: 56px; border-radius: 8px; object-fit: cover; box-shadow: 0 2px 8px #0008; } .song-info { display: flex; flex-direction: column; gap: 2px; } .song-info strong { color: #fff; font-size: 1.1em; } .song-info span { color: #b3b3b3; font-size: 0.95em; } footer { position: fixed; left: 260px; right: 0; bottom: 0; background: #181818; z-index: 10; box-shadow: 0 -2px 12px #000a; padding: 0; } #player-bar { display: flex; justify-content: space-between; align-items: center; height: 100px; padding: 0 24px; gap: 12px; background: #181818; border-top: 1px solid #232323; } .player-section { display: flex; align-items: center; min-width: 0; } .player-left { flex: 1.5; min-width: 0; gap: 16px; } .player-songinfo { display: flex; flex-direction: column; min-width: 0; max-width: 180px; } #player-title { font-weight: bold; color: #fff; font-size: 1.1em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } #player-artist { color: #b3b3b3; font-size: 0.98em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } #like-btn { background: none; border: none; margin-left: 8px; cursor: pointer; transition: transform 0.2s; padding: 6px; } #like-btn.liked svg path { stroke: #1db954; fill: #1db954; transition: fill 0.2s, stroke 0.2s; } #like-btn:active { transform: scale(1.2); } .player-center { flex: 2.5; flex-direction: column; align-items: center; justify-content: center; min-width: 0; } .player-controls { display: flex; align-items: center; justify-content: center; gap: 18px; } .main-play-btn { background: #fff; color: #181818; border-radius: 50%; width: 56px; height: 56px; display: flex; align-items: center; justify-content: center; font-size: 1.5em; box-shadow: 0 2px 8px #1db95444; border: none; transition: background 0.2s, color 0.2s; } .main-play-btn:hover { background: #1db954; color: #fff; } .player-controls button { background: none; border: none; color: #b3b3b3; font-size: 1.3em; cursor: pointer; padding: 0 6px; transition: color 0.2s; } .player-controls button.active, .player-controls button:hover { color: #1db954; } .player-progress { display: flex; align-items: center; gap: 10px; margin-top: 6px; width: 100%; max-width: 480px; } .progress-container { position: relative; flex: 1; display: flex; align-items: center; height: 18px; } #progress { width: 100%; accent-color: #1db954; background: transparent; z-index: 2; cursor: pointer; height: 4px; } #progress-bar { position: absolute; left: 0; top: 7px; height: 4px; background: #1db954; border-radius: 2px; z-index: 1; pointer-events: none; width: 0%; transition: width 0.1s linear; } .player-right { flex: 1.5; justify-content: flex-end; gap: 10px; min-width: 0; } .player-volume { display: flex; align-items: center; gap: 6px; min-width: 80px; max-width: 120px; } #volume { width: 70px; accent-color: #1db954; } #mute-btn { background: none; border: none; cursor: pointer; padding: 0 4px; display: flex; align-items: center; } .footer-links { display: flex; justify-content: flex-end; gap: 24px; padding: 0 32px 12px 0; font-size: 0.95em; } .footer-links a { color: #b3b3b3; text-decoration: none; transition: color 0.2s; } .footer-links a:hover { color: #1db954; } @media (max-width: 900px) { footer { left: 0; } #player-bar { flex-direction: column; height: auto; gap: 8px; padding: 8px 4px; } .player-section { width: 100%; justify-content: center; } .player-left, .player-right { justify-content: center; } .player-center .player-progress #progress { width: 120px; } } @media (max-width: 600px) { #player-bar { flex-direction: column; gap: 6px; padding: 4px 2px; } .player-section { flex-direction: row; gap: 6px; } .player-songinfo { max-width: 90px; } .player-center .player-progress #progress { width: 60px; } }
JS
Copy
import React, { useState, useEffect } from 'react'; import SongList from './SongList'; import Player from './Player'; // Sample songs (use royalty-free audio URLs) const songs = [ { title: 'Sample Song 1', artist: 'Artist 1', url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3' }, { title: 'Sample Song 2', artist: 'Artist 2', url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3' } ]; function App() { const [currentSong, setCurrentSong] = useState(songs[0]); const [isPlaying, setIsPlaying] = useState(false); const [currentIndex, setCurrentIndex] = useState(0); const [searchTerm, setSearchTerm] = useState(''); const [isShuffle, setIsShuffle] = useState(false); const [isRepeat, setIsRepeat] = useState(false); useEffect(() => { const audio = document.getElementById('audio'); audio.src = currentSong.url; const playPauseBtn = document.getElementById('play-pause'); playPauseBtn.innerHTML = isPlaying ? '❙❙' : '▶'; // Pause or Play symbol const currentSongSpan = document.getElementById('current-song'); currentSongSpan.textContent = `${currentSong.title} – ${currentSong.artist}`; const playerCover = document.getElementById('player-cover'); playerCover.src = currentSong.cover; const songsList = document.querySelectorAll('#songs li'); highlightSong(songsList, currentIndex); const audioEndedHandler = () => { playPauseBtn.innerHTML = '▶'; setIsPlaying(false); if (currentIndex < songs.length - 1) { loadSong(currentIndex + 1); } }; const audioPlayHandler = () => { setIsPlaying(true); playPauseBtn.innerHTML = '❙❙'; }; const audioPauseHandler = () => { setIsPlaying(false); playPauseBtn.innerHTML = '▶'; }; const audioTimeUpdateHandler = () => { if (audio.duration) { const progress = document.getElementById('progress'); progress.value = (audio.currentTime / audio.duration) * 100; const currentTimeSpan = document.getElementById('current-time'); const durationSpan = document.getElementById('duration'); currentTimeSpan.textContent = formatTime(audio.currentTime); durationSpan.textContent = formatTime(audio.duration); } }; audio.addEventListener('ended', audioEndedHandler); audio.addEventListener('play', audioPlayHandler); audio.addEventListener('pause', audioPauseHandler); audio.addEventListener('timeupdate', audioTimeUpdateHandler); return () => { audio.removeEventListener('ended', audioEndedHandler); audio.removeEventListener('play', audioPlayHandler); audio.removeEventListener('pause', audioPauseHandler); audio.removeEventListener('timeupdate', audioTimeUpdateHandler); }; }, [currentSong, isPlaying, currentIndex]); document.querySelectorAll('.username').forEach(el => { if (el.textContent === 'Max Mustermann') { el.title = 'TheDoc'; } }); // Player/Spotify-UI-Logik const songs = document.querySelectorAll('#songs li'); const audio = document.getElementById('audio'); const playPauseBtn = document.getElementById('play-pause'); const prevBtn = document.getElementById('prev-btn'); const nextBtn = document.getElementById('next-btn'); const shuffleBtn = document.getElementById('shuffle-btn'); const repeatBtn = document.getElementById('repeat-btn'); const currentSongSpan = document.getElementById('current-song'); const playerCover = document.getElementById('player-cover'); const playerTitle = document.getElementById('player-title'); const playerArtist = document.getElementById('player-artist'); const likeBtn = document.getElementById('like-btn'); const likeHeart = document.getElementById('like-heart'); const muteBtn = document.getElementById('mute-btn'); const volumeOn = document.getElementById('volume-on'); const volumeOff = document.getElementById('volume-off'); const progress = document.getElementById('progress'); const progressBar = document.getElementById('progress-bar'); const currentTimeSpan = document.getElementById('current-time'); const durationSpan = document.getElementById('duration'); const volumeSlider = document.getElementById('volume'); const playIcon = document.getElementById('play-icon'); const pauseIcon = document.getElementById('pause-icon'); const songPlayBtns = document.querySelectorAll('.song-play-btn'); let currentSrc = ''; let isPlaying = false; let currentIndex = -1; let isShuffle = false; let isRepeat = false; // Easter Egg: Zeige "TheDoc" im Tooltip, wenn User-Avatar geklickt wird document.querySelectorAll('.user-avatar').forEach(el => { el.addEventListener('click', () => { el.title = 'TheDoc'; setTimeout(() => { el.title = ''; }, 2000); }); }); function loadSong(index, autoPlay = true) { const li = songs[index]; if (!li) return; currentSrc = li.getAttribute('data-src'); audio.pause(); audio.currentTime = 0; audio.src = currentSrc; audio.volume = volumeSlider.value; const title = li.querySelector('strong').textContent; const artist = li.querySelector('span').textContent; currentSongSpan.textContent = title + ' – ' + artist; playerTitle.textContent = title; playerArtist.textContent = artist; playerCover.src = li.querySelector('img').src; currentIndex = index; highlightSong(index); playIcon.style.display = 'none'; pauseIcon.style.display = ''; if (autoPlay) { audio.load(); audio.play().catch(() => { playIcon.style.display = ''; pauseIcon.style.display = 'none'; }); } } function highlightSong(index) { songs.forEach((li, i) => { li.classList.toggle('playing', i === index); }); } songs.forEach((li, idx) => { li.addEventListener('click', (e) => { if (e.target.closest('.song-play-btn')) return; loadSong(idx, true); }); }); songPlayBtns.forEach((btn, idx) => { btn.addEventListener('click', (e) => { e.stopPropagation(); loadSong(idx, true); }); }); playPauseBtn.addEventListener('click', () => { if (currentIndex === -1) { loadSong(0, true); return; } if (audio.paused) { audio.play().catch(() => {}); } else { audio.pause(); } }); audio.addEventListener('play', () => { isPlaying = true; playIcon.style.display = 'none'; pauseIcon.style.display = ''; }); audio.addEventListener('pause', () => { isPlaying = false; playIcon.style.display = ''; pauseIcon.style.display = 'none'; }); prevBtn.addEventListener('click', () => { if (isShuffle) { playRandomSong(); } else if (currentIndex > 0) { loadSong(currentIndex - 1, true); } }); nextBtn.addEventListener('click', () => { if (isShuffle) { playRandomSong(); } else if (currentIndex < songs.length - 1) { loadSong(currentIndex + 1, true); } else if (isRepeat) { loadSong(0, true); } }); shuffleBtn.addEventListener('click', () => { isShuffle = !isShuffle; shuffleBtn.classList.toggle('active', isShuffle); }); repeatBtn.addEventListener('click', () => { isRepeat = !isRepeat; repeatBtn.classList.toggle('active', isRepeat); }); audio.addEventListener('ended', () => { if (isRepeat) { audio.currentTime = 0; audio.play(); } else if (isShuffle) { playRandomSong(); } else if (currentIndex < songs.length - 1) { loadSong(currentIndex + 1, true); } else { audio.pause(); audio.currentTime = 0; } }); audio.addEventListener('timeupdate', () => { if (audio.duration) { progress.value = (audio.currentTime / audio.duration) * 100; currentTimeSpan.textContent = formatTime(audio.currentTime); durationSpan.textContent = formatTime(audio.duration); progressBar.style.width = `${progress.value}%`; } }); progress.addEventListener('input', () => { if (audio.duration) { audio.currentTime = (progress.value / 100) * audio.duration; progressBar.style.width = `${progress.value}%`; } }); // Like-Button Animation likeBtn.addEventListener('click', () => { likeBtn.classList.toggle('liked'); }); // Lautstärke/Mute muteBtn.addEventListener('click', () => { if (audio.muted) { audio.muted = false; volumeOn.style.display = ''; volumeOff.style.display = 'none'; } else { audio.muted = true; volumeOn.style.display = 'none'; volumeOff.style.display = ''; } }); volumeSlider.addEventListener('input', () => { audio.volume = volumeSlider.value; if (audio.volume == 0) { audio.muted = true; volumeOn.style.display = 'none'; volumeOff.style.display = ''; } else { audio.muted = false; volumeOn.style.display = ''; volumeOff.style.display = 'none'; } }); // Suche: Filtert Songs nach Titel oder Künstler const searchInput = document.getElementById('search'); searchInput.addEventListener('input', (e) => { const term = e.target.value.toLowerCase(); songs.forEach(li => { const title = li.getAttribute('data-title').toLowerCase(); const artist = li.getAttribute('data-artist').toLowerCase(); if (title.includes(term) || artist.includes(term)) { li.style.display = ''; } else { li.style.display = 'none'; } }); }); function playRandomSong() { let next; do { next = Math.floor(Math.random() * songs.length); } while (next === currentIndex && songs.length > 1); loadSong(next, true); } function formatTime(sec) { sec = Math.floor(sec); const min = Math.floor(sec / 60); const s = sec % 60; return min + ':' + (s < 10 ? '0' : '') + s; } return ( <div style={{ background: '#181818', color: '#fff', minHeight: '100vh', fontFamily: 'sans-serif' }}> <h1 style={{ padding: 20 }}>Spotify Clone</h1> <input id="search" type="text" placeholder="Search for songs or artists..." value={searchTerm} onChange={handleSearchChange} style={{ margin: '20px', padding: '10px', borderRadius: '5px', border: 'none' }} /> <SongList songs={songs} setCurrentSong={setCurrentSong} /> <Player song={currentSong} isPlaying={isPlaying} setIsPlaying={setIsPlaying} onPlayPause={handlePlayPause} onPrev={handlePrev} onNext={handleNext} onProgressChange={handleProgressChange} onVolumeChange={handleVolumeChange} /> <audio id="audio" /> </div> ); } export default App;