Sizlerle tamamen tarayıcı üzerinden çalışan, modern ve şık bir müzik çalar paylaşmak istiyorum. Bu müzik çalar, herhangi bir kurulum veya ek yazılıma ihtiyaç duymadan favori MP3 dosyalarınızı kolayca dinlemenize olanak tanır. İşte sunduğu özellikler:
Özellikler
- Kolay Kullanım: MP3 dosyalarınızı sürükleyip bırakarak çalma listesine ekleyebilirsiniz.
- Modern ve Şık Arayüz: Göze hitap eden, kullanıcı dostu bir tasarıma sahiptir.
- Çalma Listesi Yönetimi: Kendi çalma listenizi oluşturabilir, şarkıları ekleyip kaldırabilirsiniz.
- Temel Kontroller: Oynatma, duraklatma, sonraki ve önceki gibi temel müzik kontrol fonksiyonlarını içerir.
- Ses Kontrolü: Ses seviyesini ayarlayabilir veya tek tıklamayla sesi kapatabilirsiniz.
- Şarkı İçi Gezinme: Şarkının herhangi bir bölümüne saniyeler içinde atlama imkanı sağlar.
- Tekrar ve Rastgele Çalma: Şarkıları tekrar edebilir veya çalma listenizi rastgele sıralayabilirsiniz.
- Oynatma Hızı Ayarı: Şarkıları farklı hızlarda dinleyebilirsiniz (0.75x, 1x, 1.25x, 1.5x).
- Albüm Kapağı ve Bilgileri: Albüm kapaklarını ve ID3 etiketleri sayesinde şarkı bilgilerini görüntüleyebilirsiniz.
- İndirme Seçeneği: Çalma listenizdeki şarkıları tek tıklamayla indirebilirsiniz.
- Görselleştirici: Müziğin ritmine göre dinamik görselleştirici ile görsel efektler sağlar.
- Açılır/Kapanır Çalma Listesi: Çalma listesini gizleyebilir veya gösterebilirsiniz.
- Koyu/Açık Tema: İsteğinize göre tema seçimi yapabilirsiniz.
Klavye Kısayolları
- Boşluk: Oynat/Duraklat
- Sağ Ok: Sonraki Şarkı
- Sol Ok: Önceki Şarkı
- M: Sessiz/Sesi Aç
- R: Tekrar Modunu Değiştir
- S: Rastgele Çalmayı Değiştir
- + (Artı): Sesi Yükselt
- - (Eksi): Sesi Azalt
Yardım Menüsü
Nasıl kullanılacağına dair detaylı bilgiler ve kısayollar rehberi içerir.
Nasıl Kullanılır?
- Aşağıdaki kodu kopyalayın.
- Yeni bir konu açın veya mevcut bir mesajınızı düzenleyin.
- Düzenleyicide "Kaynak" moduna geçin.
- Kopyaladığınız kodu buraya yapıştırın.
- "Kaydet" butonuna tıklayın.

tüm kod
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Müzik Çalar</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
<style>
:root {
--bg-color: #1a202c;
--container-bg: #2d3748;
--text-color: #e2e8f0;
--light-text: #cbd5e0;
--range-bg: #4a5568;
--thumb-color: #f7fafc;
--playlist-bg: #374151;
--border-color: #4a5568;
--drop-text: #94a3b8;
--accent-color: #63b3ed;
--help-bg: #4a5568; /* Help menu background */
}
body {
font-family: 'Arial', sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
overflow-x: hidden;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 1rem;
transition: background-color 0.3s ease, color 0.3s ease;
}
.main-container {
display: flex;
width: 100%;
max-width: 900px;
gap: 1.5rem;
}
#playlist-sidebar {
background-color: var(--playlist-bg);
border-radius: 0.75rem;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
overflow: hidden;
width: 300px;
flex-shrink: 0;
display: flex;
flex-direction: column;
transition: width 0.3s ease;
}
#playlist-sidebar.collapsed {
width: 0;
}
#playlist-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
border-bottom: 1px solid var(--border-color);
}
#playlist-toggle {
background: none;
border: none;
color: var(--light-text);
cursor: pointer;
font-size: 1.1rem;
opacity: 0.7;
transition: opacity 0.2s ease, color 0.2s ease;
}
#playlist-toggle:hover {
opacity: 1;
color: var(--accent-color);
}
#playlist-container {
max-height: 500px;
overflow-y: auto;
padding: 0.75rem;
}
#playlist li {
padding: 0.75rem;
cursor: pointer;
border-bottom: 1px solid var(--border-color);
transition: background-color 0.2s ease;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
justify-content: space-between;
align-items: center;
}
#playlist li:last-child {
border-bottom: none;
}
#playlist li:hover, #playlist li.active {
background-color: #4a5568;
animation: fadeIn 0.2s ease forwards;
}
@keyframes fadeIn {
from { opacity: 0.5; }
to { opacity: 1; }
}
.player-container {
background-image: linear-gradient(to bottom right, var(--container-bg), #3f485a);
border-radius: 1rem;
box-shadow: 0 6px 10px rgba(0, 0, 0, 0.4);
padding: 2rem;
width: 100%;
display: flex;
flex-direction: column;
gap: 1.5rem;
transition: background-image 0.3s ease;
}
.track-info {
text-align: center;
}
#album-cover {
width: 150px;
height: 150px;
border-radius: 0.75rem;
object-fit: cover;
margin: 0 auto 1rem;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
animation: pulse 5s infinite alternate;
}
@keyframes pulse {
0% { transform: scale(1); }
100% { transform: scale(1.03); }
}
.controls {
display: flex;
justify-content: space-around;
align-items: center;
}
.controls button {
background: none;
border: none;
color: var(--light-text);
font-size: 1.75rem;
cursor: pointer;
opacity: 0.8;
transition: opacity 0.2s ease, transform 0.1s ease-in-out, color 0.2s ease;
}
.controls button:hover {
opacity: 1;
transform: scale(1.1);
color: var(--accent-color);
}
.controls button:focus {
outline: none;
}
.controls button.active {
color: var(--accent-color);
}
.seek-control, .volume-control {
display: flex;
align-items: center;
gap: 0.75rem;
}
input[type="range"] {
-webkit-appearance: none;
appearance: none;
height: 8px;
background: var(--range-bg);
border-radius: 4px;
cursor: pointer;
width: 100%;
transition: background 0.3s ease;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 18px;
height: 18px;
background-color: var(--thumb-color);
border-radius: 50%;
cursor: pointer;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.6);
transition: background-color 0.3s ease;
}
input[type="range"]::-moz-range-thumb {
width: 18px;
height: 18px;
background-color: var(--thumb-color);
border-radius: 50%;
cursor: pointer;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.6);
transition: background-color 0.3s ease;
}
#drop-area {
border: 3px dashed #64748b;
border-radius: 0.75rem;
padding: 2rem;
text-align: center;
color: var(--drop-text);
cursor: pointer;
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
#drop-area.dragover {
background-color: #4a5568;
border-color: var(--accent-color);
color: var(--light-text);
}
.options {
display: flex;
justify-content: space-between;
align-items: center;
}
.options button {
background: none;
border: none;
color: var(--light-text);
font-size: 1.1rem;
cursor: pointer;
opacity: 0.7;
transition: opacity 0.2s ease, color 0.2s ease;
}
.options button:hover, .options button.active {
opacity: 1;
color: var(--accent-color);
}
#visualizer-container {
width: 100%;
height: 80px;
margin-top: 1rem;
border-radius: 0.5rem;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
#visualizer {
width: 100%;
height: 100%;
}
.time-display {
font-size: 0.9rem;
color: var(--light-text);
min-width: 40px;
text-align: center;
}
#help-menu {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: var(--help-bg);
color: var(--light-text);
padding: 2rem;
border-radius: 0.5rem;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
z-index: 10;
display: none;
}
#help-menu h3 {
font-size: 1.5rem;
margin-bottom: 1rem;
color: var(--text-color);
}
#help-menu p {
margin-bottom: 0.75rem;
line-height: 1.4;
}
#help-menu strong {
color: var(--accent-color);
}
#help-menu button#close-help {
background: none;
border: none;
color: var(--light-text);
float: right;
font-size: 1.2rem;
cursor: pointer;
}
#help-menu button#close-help:hover {
color: var(--text-color);
}
/* Responsive adjustments */
@media (max-width: 768px) {
.main-container {
flex-direction: column;
}
#playlist-sidebar {
width: 100%;
margin-bottom: 1rem;
}
.player-container {
padding: 1.5rem;
}
.controls button {
font-size: 1.5rem;
}
.seek-control, .volume-control {
flex-direction: column;
align-items: stretch;
gap: 0.5rem;
}
#playlist-sidebar.collapsed {
width: 0;
}
}
</style>
</head>
<body class="bg-gray-800">
<div class="main-container">
<div id="playlist-sidebar">
<div id="playlist-header">
<h3 class="font-semibold text-gray-100">Çalma Listesi</h3>
<button id="playlist-toggle" title="Çalma Listesini Gizle"><i class="fas fa-chevron-left"></i></button>
</div>
<div id="playlist-container">
<ul id="playlist">
<!-- Çalma listesi öğeleri buraya JavaScript ile eklenecek -->
</ul>
</div>
</div>
<div class="player-container animate__animated animate__fadeIn">
<div id="drop-area" title="MP3 Dosyalarını Sürükleyip Bırakın">
<p><i class="fas fa-upload mr-2"></i> MP3 Dosyalarını Buraya Sürükleyip Bırakın</p>
</div>
<div class="track-info animate__animated animate__fadeInDown">
<img id="album-cover" src="placeholder.png" alt="Albüm Kapağı">
<h2 id="track-name" class="text-xl font-semibold text-gray-100 animate__animated animate__fadeIn delay-1s">Parça Adı</h2>
<p id="artist-name" class="text-md text-gray-400 animate__animated animate__fadeIn delay-1s">Sanatçı Adı</p>
</div>
<div class="controls">
<button id="prev" title="Önceki Parça"><i class="fas fa-backward"></i></button>
<button id="play" class="text-2xl" title="Oynat / Duraklat"><i class="fas fa-play"></i></button>
<button id="next" title="Sonraki Parça"><i class="fas fa-forward"></i></button>
</div>
<div class="seek-control">
<span id="current-time" class="time-display">0:00</span>
<input type="range" id="seek-bar" value="0">
<span id="total-duration" class="time-display">0:00</span>
</div>
<div class="volume-control">
<button id="mute" title="Sessiz / Sesi Aç"><i id="volume-icon" class="fas fa-volume-up"></i></button>
<input type="range" id="volume-bar" value="1" min="0" max="1" step="0.01">
</div>
<div class="options">
<button id="repeat" title="Tekrar Modu"><i class="fas fa-sync"></i></button>
<button id="shuffle" title="Rastgele Çalma"><i class="fas fa-random"></i></button>
<a id="download" title="İndir" download class="transition-colors duration-200 hover:text-blue-300"><i class="fas fa-download"></i></a>
<button id="playback-speed" title="Oynatma Hızı">1x</button>
<button id="toggle-theme" title="Temayı Değiştir"><i class="fas fa-adjust"></i></button>
<button id="help" title="Yardım"><i class="fas fa-question-circle"></i></button>
</div>
<div id="visualizer-container">
<canvas id="visualizer"></canvas>
</div>
</div>
</div>
<div id="help-menu">
<button id="close-help" title="Yardımı Kapat">×</button>
<h3>Yardım</h3>
<p>Müzik Çalar'a hoş geldiniz! Bu basit ve şık arayüz ile müziklerinizi kolayca dinleyebilirsiniz.</p>
<p><strong>Nasıl Kullanılır:</strong></p>
<ul>
<li>MP3 dosyalarını doğrudan "MP3 Dosyalarını Buraya Sürükleyip Bırakın" alanına sürükleyip bırakarak çalma listesine ekleyebilirsiniz.</li>
<li>Çalma listesindeki bir şarkıya tıklayarak o şarkıyı çalabilirsiniz.</li>
<li><strong><i class="fas fa-play"></i> / <i class="fas fa-pause"></i> Oynat/Duraklat:</strong> Mevcut şarkıyı başlatır veya duraklatır.</li>
<li><strong><i class="fas fa-backward"></i> Önceki:</strong> Önceki şarkıya geçer.</li>
<li><strong><i class="fas fa-forward"></i> Sonraki:</strong> Sonraki şarkıya geçer.</li>
<li><strong><input type="range" style="width: 50px;" disabled>:</strong> Şarkının zaman çizelgesinde gezinmek için kaydırıcıyı kullanın.</li>
<li><strong><i class="fas fa-volume-up"></i> / <i class="fas fa-volume-mute"></i> Ses:</strong> Sesi açıp kapatmak için tıklayın, ses seviyesini ayarlamak için kaydırıcıyı kullanın.</li>
<li><strong><i class="fas fa-sync"></i> Tekrar Modu:</strong> Şarkıyı veya tüm çalma listesini tekrar etme modlarını değiştirir.</li>
<li><strong><i class="fas fa-random"></i> Rastgele Çalma:</strong> Çalma listesini rastgele sırayla çalar.</li>
<li><strong><i class="fas fa-download"></i> İndir:</strong> Mevcut şarkıyı indirme bağlantısı (tarayıcı destekliyorsa).</li>
<li><strong>Oynatma Hızı:</strong> Şarkının oynatma hızını değiştirir (1x, 1.25x, 1.5x, 0.75x).</li>
<li><strong><i class="fas fa-adjust"></i> Temayı Değiştir:</strong> Açık ve koyu tema arasında geçiş yapar.</li>
</ul>
<p><strong>Klavye Kısayolları:</strong></p>
<ul>
<li><strong>Boşluk:</strong> Oynat / Duraklat</li>
<li><strong>Sağ Ok:</strong> Sonraki Şarkı</li>
<li><strong>Sol Ok:</strong> Önceki Şarkı</li>
<li><strong>M:</strong> Sessiz / Sesi Aç</li>
<li><strong>R:</strong> Tekrar Modunu Değiştir</li>
<li><strong>S:</strong> Rastgele Çalmayı Değiştir</li>
<li><strong>+ (Artı):</strong> Sesi Yükselt</li>
<li><strong>- (Eksi):</strong> Sesi Azalt</li>
</ul>
</div>
<audio id="audio"></audio>
<script src="https://cdn.jsdelivr.net/npm/jsmediatags/dist/jsmediatags.min.js"></script>
<script>
const body = document.body;
const mainContainer = document.querySelector('.main-container');
const playerContainer = document.querySelector('.player-container');
const playlistSidebar = document.getElementById('playlist-sidebar');
const playlistToggleBtn = document.getElementById('playlist-toggle');
const audio = document.getElementById('audio');
const playBtn = document.getElementById('play');
const prevBtn = document.getElementById('prev');
const nextBtn = document.getElementById('next');
const trackName = document.getElementById('track-name');
const artistName = document.getElementById('artist-name');
const albumCover = document.getElementById('album-cover');
const seekBar = document.getElementById('seek-bar');
const currentTimeDisplay = document.getElementById('current-time');
const totalDurationDisplay = document.getElementById('total-duration');
const volumeBar = document.getElementById('volume-bar');
const volumeIcon = document.getElementById('volume-icon');
const muteBtn = document.getElementById('mute');
const playlistUl = document.getElementById('playlist');
const dropArea = document.getElementById('drop-area');
const repeatBtn = document.getElementById('repeat');
const shuffleBtn = document.getElementById('shuffle');
const downloadBtn = document.getElementById('download');
const playbackSpeedBtn = document.getElementById('playback-speed');
const toggleThemeBtn = document.getElementById('toggle-theme');
const visualizerCanvas = document.getElementById('visualizer');
const visualizerContainer = document.getElementById('visualizer-container');
const visualizerContext = visualizerCanvas.getContext('2d');
const helpBtn = document.getElementById('help');
const helpMenu = document.getElementById('help-menu');
const closeHelpBtn = document.getElementById('close-help');
let currentTrackIndex = 0;
let isPlaying = false;
let isMuted = false;
let repeatMode = 'off'; // 'off', 'track', 'playlist'
let shuffleMode = false;
let playlist = [];
let shuffledPlaylist = [];
let playbackSpeed = 1;
let audioContext;
let analyser;
let source;
let isAudioContextStarted = false;
let isDraggingSeekBar = false;
let isLightTheme = false;
let isPlaylistCollapsed = false;
function startAudioContext() {
if (audioContext && audioContext.state !== 'running') {
audioContext.resume().then(() => {
console.log('Audio context started successfully');
isAudioContextStarted = true;
}).catch(error => {
console.error('Error starting audio context:', error);
});
} else if (!audioContext) {
initializeAudioContext();
isAudioContextStarted = true;
}
}
function initializeAudioContext() {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
analyser = audioContext.createAnalyser();
source = audioContext.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(audioContext.destination);
visualizerCanvas.width = visualizerContainer.offsetWidth;
visualizerCanvas.height = visualizerContainer.offsetHeight;
}
function loadTrack(index) {
if (playlist.length === 0) return;
const track = shuffleMode ? shuffledPlaylist[index] : playlist[index];
audio.src = URL.createObjectURL(track.file);
trackName.textContent = track.name.replace(/\.[^/.]+$/, "");
artistName.textContent = 'Bilinmiyor';
albumCover.src = 'placeholder.png';
document.title = `Çalıyor: ${track.name.replace(/\.[^/.]+$/, "")} - Müzik Çalar`;
jsmediatags.read(track.file, {
onSuccess: function(tag) {
if (tag.tags.title) trackName.textContent = tag.tags.title;
if (tag.tags.artist) artistName.textContent = tag.tags.artist;
if (tag.tags.picture) {
try {
const base64String = btoa(String.fromCharCode.apply(null, tag.tags.picture.data));
albumCover.src = `data:${tag.tags.picture.format};base64,${base64String}`;
} catch (error) {
console.error("Albüm kapağı yüklenirken hata:", error);
}
}
},
onError: function(error) {
console.error('ID3 etiketleri okunurken hata:', error);
}
});
audio.load();
audio.onloadeddata = () => {
seekBar.max = audio.duration;
totalDurationDisplay.textContent = formatTime(audio.duration);
updateDownloadLink();
};
audio.onerror = (error) => {
console.error('Ses dosyası yüklenirken hata:', error);
alert('Ses dosyası yüklenirken bir hata oluştu.');
removeTrackFromPlaylist(playlist.findIndex(t => t.file === track.file));
};
updateDownloadLink();
renderPlaylist();
}
function playTrack() {
if (playlist.length === 0) return;
if (!audioContext || audioContext.state !== 'running') {
startAudioContext();
if (!isAudioContextStarted) {
console.warn("Audio context başlatılamadı, oynatma engellendi.");
return;
}
}
audio.playbackRate = playbackSpeed;
audio.play().then(() => {
isPlaying = true;
playBtn.innerHTML = '<i class="fas fa-pause animate__animated animate__pulse"></i>';
}).catch(error => {
console.error("Oynatma hatası:", error);
if (error.name === 'NotAllowedError') {
console.warn('Tarayıcı otomatik oynatmayı engelledi. Lütfen etkileşimde bulunun.');
} else {
alert('Oynatma sırasında bir hata oluştu: ' + error.message);
}
});
visualize();
updatePlayButtonState();
}
function pauseTrack() {
audio.pause();
isPlaying = false;
playBtn.innerHTML = '<i class="fas fa-play animate__animated animate__headShake"></i>';
if (analyser) visualizerContext.clearRect(0, 0, visualizerCanvas.width, visualizerCanvas.height);
updatePlayButtonState();
}
function updatePlayButtonState() {
playBtn.classList.toggle('active', isPlaying);
}
function nextTrack() {
if (playlist.length === 0) return;
if (repeatMode === 'track') {
audio.currentTime = 0;
playTrack();
return;
}
currentTrackIndex++;
if (currentTrackIndex >= playlist.length) {
currentTrackIndex = repeatMode === 'playlist' ? 0 : playlist.length - 1;
if (repeatMode !== 'playlist') {
pauseTrack();
return;
}
}
loadTrack(currentTrackIndex);
playTrack();
}
function prevTrack() {
if (playlist.length === 0) return;
if (repeatMode === 'track') {
audio.currentTime = 0;
playTrack();
return;
}
currentTrackIndex--;
if (currentTrackIndex < 0) {
currentTrackIndex = repeatMode === 'playlist' ? playlist.length - 1 : 0;
if (repeatMode !== 'playlist') {
pauseTrack();
return;
}
}
loadTrack(currentTrackIndex);
playTrack();
}
function formatTime(time) {
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60).toString().padStart(2, '0');
return `${minutes}:${seconds}`;
}
function updateSeekBar() {
if (isDraggingSeekBar) return;
seekBar.value = audio.currentTime;
currentTimeDisplay.textContent = formatTime(audio.currentTime);
const remainingTime = audio.duration - audio.currentTime;
totalDurationDisplay.textContent = `-${formatTime(remainingTime)}`;
}
function setSeek() {
audio.currentTime = seekBar.value;
}
function updateVolume() {
audio.volume = volumeBar.value;
updateMuteIcon();
}
function updateMuteIcon() {
isMuted = audio.volume === 0;
volumeIcon.className = isMuted ? 'fas fa-volume-mute' : 'fas fa-volume-up';
muteBtn.classList.toggle('active', isMuted);
}
function muteUnmute() {
if (!isMuted) {
volumeBar.dataset.previousVolume = volumeBar.value;
audio.volume = 0;
volumeBar.value = 0;
} else {
audio.volume = parseFloat(volumeBar.dataset.previousVolume || 1);
volumeBar.value = audio.volume;
}
updateMuteIcon();
}
function removeTrackFromPlaylist(index) {
if (index > -1) {
const removedTrack = playlist.splice(index, 1)[0];
if (shuffleMode) {
shuffledPlaylist = playlist.slice();
}
if (playlist.length === 0) {
pauseTrack();
audio.src = '';
document.title = 'Müzik Çalar';
trackName.textContent = 'Parça Adı';
artistName.textContent = 'Sanatçı Adı';
albumCover.src = 'placeholder.png';
currentTimeDisplay.textContent = '0:00';
totalDurationDisplay.textContent = '0:00';
seekBar.value = 0;
} else if (removedTrack === (shuffleMode ? shuffledPlaylist[currentTrackIndex] : playlist[currentTrackIndex])) {
if (playlist.length <= currentTrackIndex) {
currentTrackIndex = 0;
}
loadTrack(currentTrackIndex);
if (isPlaying) playTrack();
} else if (index < currentTrackIndex) {
currentTrackIndex = Math.max(0, currentTrackIndex - 1);
}
renderPlaylist();
}
}
function renderPlaylist() {
playlistUl.innerHTML = '';
const currentPlaylist = shuffleMode ? shuffledPlaylist : playlist;
currentPlaylist.forEach((track, index) => {
const listItem = document.createElement('li');
listItem.textContent = track.name.replace(/\.[^/.]+$/, "");
listItem.classList.add('cursor-pointer', 'hover:bg-gray-700', 'p-2', 'rounded', 'animate__animated', 'animate__fadeIn');
const actualTrackIndex = playlist.indexOf(track);
const isActive = (!shuffleMode && currentTrackIndex === actualTrackIndex) || (shuffleMode && shuffledPlaylist[currentTrackIndex] === track);
listItem.classList.toggle('bg-gray-600', isActive);
listItem.classList.toggle('active', isActive);
const removeButton = document.createElement('button');
removeButton.innerHTML = '<i class="fas fa-times text-red-500 hover:text-red-600"></i>';
removeButton.classList.add('ml-2', 'focus:outline-none', 'opacity-50', 'hover:opacity-100', 'transition-opacity');
removeButton.addEventListener('click', (event) => {
event.stopPropagation();
const indexToRemove = playlist.indexOf(track);
removeTrackFromPlaylist(indexToRemove);
});
listItem.appendChild(removeButton);
listItem.addEventListener('click', () => {
currentTrackIndex = shuffleMode ? shuffledPlaylist.indexOf(track) : playlist.indexOf(track);
loadTrack(currentTrackIndex);
playTrack();
});
playlistUl.appendChild(listItem);
});
}
function handleDrop(files) {
const newFiles = Array.from(files).filter(file => file.type === 'audio/mpeg');
if (newFiles.length > 0) {
newFiles.forEach(file => {
playlist.push({ name: file.name, file: file });
});
if (playlist.length > 0 && !isPlaying) {
loadTrack(currentTrackIndex);
}
if (shuffleMode) shuffleArray();
renderPlaylist();
}
}
function toggleRepeat() {
if (repeatMode === 'off') repeatMode = 'track';
else if (repeatMode === 'track') repeatMode = 'playlist';
else if (repeatMode === 'playlist') repeatMode = 'off';
updateRepeatButton();
}
function updateRepeatButton() {
const icon = repeatBtn.querySelector('i');
icon.classList.remove('fa-sync', 'fa-sync-alt');
repeatBtn.classList.remove('active');
if (repeatMode === 'track') {
icon.classList.add('fa-sync-alt');
repeatBtn.classList.add('active');
} else if (repeatMode === 'playlist') {
icon.classList.add('fa-sync');
repeatBtn.classList.add('active');
}
}
function toggleShuffle() {
shuffleMode = !shuffleMode;
updateShuffleButton();
if (shuffleMode) {
shuffledPlaylist = [...playlist];
shuffleArray(shuffledPlaylist);
}
renderPlaylist();
}
function updateShuffleButton() {
shuffleBtn.classList.toggle('active', shuffleMode);
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
function updateDownloadLink() {
if (playlist.length > 0) {
const track = shuffleMode ? shuffledPlaylist[currentTrackIndex] : playlist[currentTrackIndex];
downloadBtn.href = URL.createObjectURL(track.file);
downloadBtn.download = track.name;
}
}
function changePlaybackSpeed() {
playbackSpeed = playbackSpeed === 1 ? 1.25 : playbackSpeed === 1.25 ? 1.5 : playbackSpeed === 1.5 ? 0.75 : 1;
audio.playbackRate = playbackSpeed;
playbackSpeedBtn.textContent = playbackSpeed + 'x';
playbackSpeedBtn.classList.add('active');
setTimeout(() => playbackSpeedBtn.classList.remove('active'), 200);
}
function visualize() {
if (!isPlaying || !analyser) return;
analyser.fftSize = 256;
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
visualizerContext.clearRect(0, 0, visualizerCanvas.width, visualizerCanvas.height);
function draw() {
if (!isPlaying) return;
requestAnimationFrame(draw);
analyser.getByteFrequencyData(dataArray);
visualizerContext.fillStyle = 'rgba(74, 85, 104, 0.3)';
visualizerContext.fillRect(0, 0, visualizerCanvas.width, visualizerCanvas.height);
const barWidth = (visualizerCanvas.width / bufferLength) * 2;
let barHeight;
let x = 0;
for (let i = 0; i < bufferLength; i++) {
barHeight = dataArray[i];
const gradient = visualizerContext.createLinearGradient(0, visualizerCanvas.height - barHeight / 2, 0, visualizerCanvas.height);
gradient.addColorStop(0, '#f7fafc');
gradient.addColorStop(1, '#a0aec0');
visualizerContext.fillStyle = gradient;
visualizerContext.fillRect(x, visualizerCanvas.height - barHeight / 2, barWidth, barHeight / 2);
x += barWidth + 1;
}
}
draw();
}
function toggleTheme() {
isLightTheme = !isLightTheme;
body.style.backgroundColor = isLightTheme ? '#f7fafc' : '#1a202c';
body.style.color = isLightTheme ? '#1a202c' : '#e2e8f0';
playerContainer.style.backgroundImage = isLightTheme ? 'linear-gradient(to bottom right, #edf2f7, #e2e8f0)' : 'linear-gradient(to bottom right, #2d3748, #3f485a)';
const root = document.documentElement;
root.style.setProperty('--bg-color', isLightTheme ? '#f7fafc' : '#1a202c');
root.style.setProperty('--container-bg', isLightTheme ? '#edf2f7' : '#2d3748');
root.style.setProperty('--text-color', isLightTheme ? '#1a202c' : '#e2e8f0');
root.style.setProperty('--light-text', isLightTheme ? '#4a5568' : '#cbd5e0');
root.style.setProperty('--range-bg', isLightTheme ? '#cbd5e0' : '#4a5568');
root.style.setProperty('--thumb-color', isLightTheme ? '#4a5568' : '#f7fafc');
root.style.setProperty('--playlist-bg', isLightTheme ? '#e2e8f0' : '#374151');
root.style.setProperty('--border-color', isLightTheme ? '#cbd5e0' : '#4a5568');
root.style.setProperty('--drop-text', isLightTheme ? '#718096' : '#94a3b8');
root.style.setProperty('--accent-color', isLightTheme ? '#2b6cb0' : '#63b3ed');
toggleThemeBtn.classList.toggle('active', isLightTheme);
}
function togglePlaylist() {
isPlaylistCollapsed = !isPlaylistCollapsed;
playlistSidebar.classList.toggle('collapsed', isPlaylistCollapsed);
playlistToggleBtn.innerHTML = isPlaylistCollapsed ? '<i class="fas fa-chevron-right"></i>' : '<i class="fas fa-chevron-left"></i>';
playlistToggleBtn.title = isPlaylistCollapsed ? 'Çalma Listesini Göster' : 'Çalma Listesini Gizle';
}
function toggleHelp() {
helpMenu.style.display = helpMenu.style.display === 'none' ? 'block' : 'none';
}
// Olay Dinleyicileri
playBtn.addEventListener('click', () => {
if (playlist.length === 0) return;
isPlaying ? pauseTrack() : playTrack();
});
prevBtn.addEventListener('click', prevTrack);
nextBtn.addEventListener('click', nextTrack);
audio.addEventListener('timeupdate', updateSeekBar);
audio.addEventListener('ended', nextTrack);
seekBar.addEventListener('input', setSeek);
seekBar.addEventListener('mousedown', () => isDraggingSeekBar = true);
seekBar.addEventListener('mouseup', () => isDraggingSeekBar = false);
volumeBar.addEventListener('input', updateVolume);
muteBtn.addEventListener('click', muteUnmute);
repeatBtn.addEventListener('click', toggleRepeat);
shuffleBtn.addEventListener('click', toggleShuffle);
playbackSpeedBtn.addEventListener('click', changePlaybackSpeed);
toggleThemeBtn.addEventListener('click', toggleTheme);
playlistToggleBtn.addEventListener('click', togglePlaylist);
helpBtn.addEventListener('click', toggleHelp);
closeHelpBtn.addEventListener('click', toggleHelp);
// Sürükle bırak işlevselliği
dropArea.addEventListener('dragover', (e) => {
e.preventDefault();
dropArea.classList.add('dragover');
});
dropArea.addEventListener('dragleave', () => {
dropArea.classList.remove('dragover');
});
dropArea.addEventListener('drop', (e) => {
e.preventDefault();
dropArea.classList.remove('dragover');
handleDrop(e.dataTransfer.files);
});
playlistUl.addEventListener('click', (e) => {
const target = e.target.closest('li');
if (target) {
const index = Array.from(playlistUl.children).indexOf(target);
if (index > -1) {
currentTrackIndex = shuffleMode ? shuffledPlaylist.findIndex(track => playlist[index] === track) : index;
loadTrack(currentTrackIndex);
playTrack();
}
}
});
// Klavye kısayolları
document.addEventListener('keydown', (event) => {
if (event.target.tagName.toLowerCase() === 'input') return; // Input alanlarındayken kısayolları engelle
switch (event.key) {
case ' ': // Boşluk: Oynat/Duraklat
if (playlist.length > 0) {
event.preventDefault();
isPlaying ? pauseTrack() : playTrack();
}
break;
case 'ArrowRight': // Sağ ok: Sonraki
event.preventDefault();
nextTrack();
break;
case 'ArrowLeft': // Sol ok: Önceki
event.preventDefault();
prevTrack();
break;
case 'm': // M: Sessiz/Sesi Aç
case 'M':
muteUnmute();
break;
case 'r': // R: Tekrar Modu
case 'R':
toggleRepeat();
break;
case 's': // S: Rastgele Modu
case 'S':
toggleShuffle();
break;
case '+': // Artı: Sesi Yükselt
event.preventDefault();
volumeBar.value = Math.min(1, parseFloat(volumeBar.value) + 0.1);
updateVolume();
break;
case '-': // Eksi: Sesi Azalt
event.preventDefault();
volumeBar.value = Math.max(0, parseFloat(volumeBar.value) - 0.1);
updateVolume();
break;
}
});
// Başlangıç
if (playlist.length > 0) {
loadTrack(currentTrackIndex);
renderPlaylist();
}
// Görselleştirici Kurulumu ve AudioContext Başlatma
window.addEventListener('load', () => {
initializeAudioContext();
volumeBar.dataset.previousVolume = volumeBar.value;
renderPlaylist(); // Initial render to avoid empty playlist on load
});
</script>
</body>
</html>