Proje Detayları

Adım Adım Geliştirme

Bu bölümde, müzik çalar uygulamasını adım adım nasıl geliştirebileceğinizi öğreneceksiniz. Her adımda, ilgili kod parçalarını ve açıklamalarını bulacaksınız.

Adım 1: Proje Yapısını Oluşturma

İlk olarak, projemiz için gerekli dosyaları oluşturalım:

  • index.html - Ana HTML dosyası
  • style.css - CSS stil dosyası
  • script.js - JavaScript kod dosyası
  • music - Müzik dosyalarını içeren klasör
  • images - Albüm kapaklarını içeren klasör

Not: Bu projede kullanacağımız müzik dosyaları ve albüm kapakları için telif hakkı sorunlarından kaçınmak adına, ücretsiz lisanslı müzikler kullanmanızı öneririz. Free Music Archive veya Bensound gibi sitelerden ücretsiz müzikler indirebilirsiniz.

index.html
<!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 rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
    <div class="music-player">
        <div class="player-header">
            <h2>JS Müzik Çalar</h2>
        </div>
        
        <div class="album-cover">
            <img src="images/default-cover.jpg" alt="Albüm Kapağı" id="albumCover">
        </div>
        
        <div class="song-info">
            <div class="song-title" id="songTitle">Şarkı Seçilmedi</div>
            <div class="song-artist" id="songArtist">Sanatçı</div>
        </div>
        
        <div class="progress-container" id="progressContainer">
            <div class="progress-bar" id="progressBar"></div>
        </div>
        
        <div class="time-info">
            <div class="current-time" id="currentTime">0:00</div>
            <div class="total-time" id="totalTime">0:00</div>
        </div>
        
        <div class="controls">
            <button class="control-btn" id="prevBtn"><i class="fas fa-step-backward"></i></button>
            <button class="control-btn" id="rewindBtn"><i class="fas fa-backward"></i></button>
            <button class="control-btn play-btn" id="playBtn"><i class="fas fa-play"></i></button>
            <button class="control-btn" id="forwardBtn"><i class="fas fa-forward"></i></button>
            <button class="control-btn" id="nextBtn"><i class="fas fa-step-forward"></i></button>
        </div>
        
        <div class="volume-container">
            <div class="volume-icon" id="volumeIcon"><i class="fas fa-volume-up"></i></div>
            <div class="volume-slider" id="volumeSlider">
                <div class="volume-bar" id="volumeBar"></div>
            </div>
        </div>
        
        <div class="playlist" id="playlist">
            <!-- Çalma listesi öğeleri buraya dinamik olarak eklenecek -->
        </div>
    </div>

    <!-- Audio elementi (gizli) -->
    <audio id="audioPlayer"></audio>

    <script src="script.js"></script>
</body>
</html>
style.css
/* Genel Stiller */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f0f2f5;
    color: #333;
    line-height: 1.6;
    padding: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

/* Müzik Çalar Stilleri */
.music-player {
    width: 350px;
    background-color: #222;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 10px 20px rgba(0,0,0,0.3);
}

.player-header {
    padding: 20px;
    background-color: #333;
    color: white;
    text-align: center;
}

.player-header h2 {
    margin: 0;
    font-size: 1.5rem;
}

.album-cover {
    width: 100%;
    height: 300px;
    background-color: #444;
    position: relative;
    overflow: hidden;
}

.album-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.3s ease;
}

.album-cover img:hover {
    transform: scale(1.05);
}

.song-info {
    padding: 20px;
    text-align: center;
    color: white;
}

.song-title {
    font-size: 1.2rem;
    font-weight: bold;
    margin-bottom: 5px;
}

.song-artist {
    font-size: 0.9rem;
    color: #aaa;
    margin-bottom: 15px;
}

.progress-container {
    height: 5px;
    background-color: #444;
    margin: 0 20px 15px;
    cursor: pointer;
    border-radius: 5px;
}

.progress-bar {
    height: 100%;
    background-color: #4caf50;
    width: 0;
    border-radius: 5px;
    transition: width 0.1s linear;
}

.time-info {
    display: flex;
    justify-content: space-between;
    padding: 0 20px;
    color: #aaa;
    font-size: 0.8rem;
    margin-bottom: 15px;
}

.controls {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0 20px 20px;
}

.control-btn {
    background: none;
    border: none;
    color: white;
    font-size: 1.5rem;
    cursor: pointer;
    margin: 0 10px;
    transition: color 0.2s, transform 0.1s;
}

.control-btn:hover {
    color: #4caf50;
}

.control-btn:active {
    transform: scale(0.95);
}

.play-btn {
    font-size: 2.5rem;
    color: #4caf50;
}

.volume-container {
    display: flex;
    align-items: center;
    padding: 0 20px 20px;
    color: white;
}

.volume-icon {
    margin-right: 10px;
    font-size: 1.2rem;
    cursor: pointer;
}

.volume-slider {
    flex: 1;
    height: 5px;
    background-color: #444;
    border-radius: 5px;
    position: relative;
    cursor: pointer;
}

.volume-bar {
    height: 100%;
    background-color: #4caf50;
    width: 70%;
    border-radius: 5px;
}

.playlist {
    background-color: #333;
    max-height: 200px;
    overflow-y: auto;
}

.playlist-item {
    display: flex;
    align-items: center;
    padding: 10px 20px;
    border-bottom: 1px solid #444;
    cursor: pointer;
    transition: background-color 0.2s;
}

.playlist-item:hover {
    background-color: #444;
}

.playlist-item.active {
    background-color: #4caf50;
}

.playlist-item-number {
    width: 30px;
    color: #aaa;
    font-size: 0.9rem;
}

.playlist-item-info {
    flex: 1;
}

.playlist-item-title {
    color: white;
    font-size: 0.9rem;
    margin-bottom: 3px;
}

.playlist-item-artist {
    color: #aaa;
    font-size: 0.8rem;
}

.playlist-item-duration {
    color: #aaa;
    font-size: 0.8rem;
    margin-left: 10px;
}

/* Kaydırma Çubuğu Stilleri */
.playlist::-webkit-scrollbar {
    width: 5px;
}

.playlist::-webkit-scrollbar-track {
    background: #333;
}

.playlist::-webkit-scrollbar-thumb {
    background: #555;
    border-radius: 5px;
}

.playlist::-webkit-scrollbar-thumb:hover {
    background: #666;
}

/* Animasyonlar */
@keyframes pulse {
    0% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.05);
    }
    100% {
        transform: scale(1);
    }
}

.playing .album-cover img {
    animation: pulse 2s infinite;
}

/* Responsive Tasarım */
@media (max-width: 480px) {
    .music-player {
        width: 100%;
    }
    
    .album-cover {
        height: 250px;
    }
    
    .control-btn {
        font-size: 1.2rem;
        margin: 0 8px;
    }
    
    .play-btn {
        font-size: 2rem;
    }
}

Adım 2: Şarkı Verilerini Oluşturma

Şimdi, müzik çalarda kullanılacak şarkı verilerini oluşturalım:

script.js (Şarkı Verileri)
// Şarkı verileri
const songs = [
    {
        title: "Acoustic Breeze",
        artist: "Benjamin Tissot",
        audioSrc: "music/acousticbreeze.mp3",
        coverSrc: "images/acoustic.jpg",
        duration: "2:37"
    },
    {
        title: "Creative Minds",
        artist: "Benjamin Tissot",
        audioSrc: "music/creativeminds.mp3",
        coverSrc: "images/creative.jpg",
        duration: "2:26"
    },
    {
        title: "Summer",
        artist: "Benjamin Tissot",
        audioSrc: "music/summer.mp3",
        coverSrc: "images/summer.jpg",
        duration: "3:50"
    },
    {
        title: "Jazzy Frenchy",
        artist: "Benjamin Tissot",
        audioSrc: "music/jazzyfrenchy.mp3",
        coverSrc: "images/jazzy.jpg",
        duration: "1:44"
    }
];

İpucu: Yukarıdaki şarkı verileri örnek olarak verilmiştir. Kendi projelerinizde, Bensound gibi sitelerden ücretsiz müzikler kullanabilir veya kendi müzik dosyalarınızı ekleyebilirsiniz. Dosya yollarını ve süreleri kendi dosyalarınıza göre güncellemeyi unutmayın.

Adım 3: JavaScript Kodunu Yazma

Şimdi, uygulamanın işlevselliğini sağlayacak JavaScript kodunu yazalım:

script.js (Ana Kod)
// DOM elementlerini seçme
const audioPlayer = document.getElementById('audioPlayer');
const albumCover = document.getElementById('albumCover');
const songTitle = document.getElementById('songTitle');
const songArtist = document.getElementById('songArtist');
const progressContainer = document.getElementById('progressContainer');
const progressBar = document.getElementById('progressBar');
const currentTime = document.getElementById('currentTime');
const totalTime = document.getElementById('totalTime');
const playBtn = document.getElementById('playBtn');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const rewindBtn = document.getElementById('rewindBtn');
const forwardBtn = document.getElementById('forwardBtn');
const volumeIcon = document.getElementById('volumeIcon');
const volumeSlider = document.getElementById('volumeSlider');
const volumeBar = document.getElementById('volumeBar');
const playlist = document.getElementById('playlist');
const musicPlayer = document.querySelector('.music-player');

// Değişkenler
let currentSongIndex = 0;
let isPlaying = false;

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // Çalma listesini oluştur
    createPlaylist();
    
    // İlk şarkıyı yükle
    loadSong(currentSongIndex);
    
    // Olay dinleyicileri
    playBtn.addEventListener('click', togglePlay);
    prevBtn.addEventListener('click', prevSong);
    nextBtn.addEventListener('click', nextSong);
    rewindBtn.addEventListener('click', () => seekTime(-10)); // 10 saniye geri
    forwardBtn.addEventListener('click', () => seekTime(10)); // 10 saniye ileri
    
    // İlerleme çubuğu olayları
    progressContainer.addEventListener('click', setProgress);
    
    // Ses kontrolü olayları
    volumeSlider.addEventListener('click', setVolume);
    volumeIcon.addEventListener('click', toggleMute);
    
    // Audio olayları
    audioPlayer.addEventListener('timeupdate', updateProgress);
    audioPlayer.addEventListener('ended', nextSong);
    audioPlayer.addEventListener('loadedmetadata', updateTotalTime);
    
    // Klavye kısayolları
    document.addEventListener('keydown', handleKeyboard);
});

// Çalma listesini oluşturma fonksiyonu
function createPlaylist() {
    playlist.innerHTML = '';
    
    songs.forEach((song, index) => {
        const playlistItem = document.createElement('div');
        playlistItem.className = `playlist-item${index === currentSongIndex ? ' active' : ''}`;
        playlistItem.dataset.index = index;
        
        playlistItem.innerHTML = `
            ${index + 1}
            
                ${song.title}
                ${song.artist}
            
            ${song.duration}
        `;
        
        playlistItem.addEventListener('click', () => {
            currentSongIndex = index;
            loadSong(currentSongIndex);
            playSong();
        });
        
        playlist.appendChild(playlistItem);
    });
}

// Şarkı yükleme fonksiyonu
function loadSong(index) {
    const song = songs[index];
    
    // Şarkı bilgilerini güncelle
    songTitle.textContent = song.title;
    songArtist.textContent = song.artist;
    albumCover.src = song.coverSrc;
    audioPlayer.src = song.audioSrc;
    
    // Aktif çalma listesi öğesini güncelle
    document.querySelectorAll('.playlist-item').forEach((item, i) => {
        if (i === index) {
            item.classList.add('active');
        } else {
            item.classList.remove('active');
        }
    });
    
    // İlerleme çubuğunu sıfırla
    progressBar.style.width = '0%';
    currentTime.textContent = '0:00';
}

// Çalma/duraklatma fonksiyonu
function togglePlay() {
    if (isPlaying) {
        pauseSong();
    } else {
        playSong();
    }
}

// Şarkıyı çalma fonksiyonu
function playSong() {
    musicPlayer.classList.add('playing');
    playBtn.innerHTML = '';
    audioPlayer.play();
    isPlaying = true;
}

// Şarkıyı duraklatma fonksiyonu
function pauseSong() {
    musicPlayer.classList.remove('playing');
    playBtn.innerHTML = '';
    audioPlayer.pause();
    isPlaying = false;
}

// Önceki şarkı fonksiyonu
function prevSong() {
    currentSongIndex--;
    if (currentSongIndex < 0) {
        currentSongIndex = songs.length - 1;
    }
    loadSong(currentSongIndex);
    playSong();
}

// Sonraki şarkı fonksiyonu
function nextSong() {
    currentSongIndex++;
    if (currentSongIndex > songs.length - 1) {
        currentSongIndex = 0;
    }
    loadSong(currentSongIndex);
    playSong();
}

// İlerleme çubuğunu güncelleme fonksiyonu
function updateProgress(e) {
    const { duration, currentTime: time } = e.target;
    if (duration) {
        // İlerleme çubuğunu güncelle
        const progressPercent = (time / duration) * 100;
        progressBar.style.width = `${progressPercent}%`;
        
        // Geçerli zamanı güncelle
        const minutes = Math.floor(time / 60);
        const seconds = Math.floor(time % 60);
        currentTime.textContent = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
    }
}

// Toplam süreyi güncelleme fonksiyonu
function updateTotalTime() {
    const duration = audioPlayer.duration;
    if (duration) {
        const minutes = Math.floor(duration / 60);
        const seconds = Math.floor(duration % 60);
        totalTime.textContent = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
    }
}

// İlerleme çubuğuna tıklama fonksiyonu
function setProgress(e) {
    const width = this.clientWidth;
    const clickX = e.offsetX;
    const duration = audioPlayer.duration;
    
    audioPlayer.currentTime = (clickX / width) * duration;
}

// Belirli bir süre ileri/geri sarma fonksiyonu
function seekTime(seconds) {
    audioPlayer.currentTime += seconds;
}

// Ses seviyesini ayarlama fonksiyonu
function setVolume(e) {
    const width = this.clientWidth;
    const clickX = e.offsetX;
    const volume = clickX / width;
    
    // Ses seviyesini 0-1 arasında ayarla
    audioPlayer.volume = volume;
    volumeBar.style.width = `${volume * 100}%`;
    
    // Ses ikonunu güncelle
    updateVolumeIcon(volume);
}

// Sesi kapatma/açma fonksiyonu
function toggleMute() {
    if (audioPlayer.volume > 0) {
        // Önceki ses seviyesini kaydet
        audioPlayer.dataset.prevVolume = audioPlayer.volume;
        audioPlayer.volume = 0;
        volumeBar.style.width = '0%';
        volumeIcon.innerHTML = '';
    } else {
        // Önceki ses seviyesine geri dön
        const prevVolume = audioPlayer.dataset.prevVolume || 0.7;
        audioPlayer.volume = prevVolume;
        volumeBar.style.width = `${prevVolume * 100}%`;
        updateVolumeIcon(prevVolume);
    }
}

// Ses ikonunu güncelleme fonksiyonu
function updateVolumeIcon(volume) {
    if (volume > 0.7) {
        volumeIcon.innerHTML = '';
    } else if (volume > 0.1) {
        volumeIcon.innerHTML = '';
    } else if (volume > 0) {
        volumeIcon.innerHTML = '';
    } else {
        volumeIcon.innerHTML = '';
    }
}

// Klavye kısayolları fonksiyonu
function handleKeyboard(e) {
    // Boşluk tuşu: Çal/Duraklat
    if (e.code === 'Space') {
        e.preventDefault();
        togglePlay();
    }
    
    // Sol ok tuşu: 5 saniye geri
    if (e.code === 'ArrowLeft') {
        seekTime(-5);
    }
    
    // Sağ ok tuşu: 5 saniye ileri
    if (e.code === 'ArrowRight') {
        seekTime(5);
    }
    
    // Yukarı ok tuşu: Ses seviyesini artır
    if (e.code === 'ArrowUp') {
        e.preventDefault();
        const newVolume = Math.min(audioPlayer.volume + 0.1, 1);
        audioPlayer.volume = newVolume;
        volumeBar.style.width = `${newVolume * 100}%`;
        updateVolumeIcon(newVolume);
    }
    
    // Aşağı ok tuşu: Ses seviyesini azalt
    if (e.code === 'ArrowDown') {
        e.preventDefault();
        const newVolume = Math.max(audioPlayer.volume - 0.1, 0);
        audioPlayer.volume = newVolume;
        volumeBar.style.width = `${newVolume * 100}%`;
        updateVolumeIcon(newVolume);
    }
}

Adım 4: Uygulamayı Test Etme

Şimdi uygulamanızı test etme zamanı! Aşağıdaki adımları izleyin:

  1. Tüm dosyaları (index.htmlstyle.cssscript.js) aynı klasöre kaydedin.
  2. music ve images klasörlerini oluşturun ve içlerine şarkı dosyalarını ve albüm kapaklarını ekleyin.
  3. HTML dosyasını bir web tarayıcısında açın.
  4. Çalma/duraklatma butonuna tıklayarak şarkıyı çalın ve duraklatın.
  5. İleri/geri butonlarını kullanarak şarkılar arasında geçiş yapın.
  6. İlerleme çubuğuna tıklayarak şarkının belirli bir kısmına atlayın.
  7. Ses seviyesi kaydırıcısını kullanarak ses seviyesini ayarlayın.
  8. Çalma listesindeki şarkılara tıklayarak doğrudan o şarkıya geçin.
  9. Klavye kısayollarını test edin (boşluk tuşu, ok tuşları).

İpucu: Tarayıcınızın geliştirici araçlarını (genellikle F12 tuşu ile açılır) kullanarak JavaScript hatalarını ayıklayabilirsiniz. Ayrıca, şarkı dosyalarının doğru yolda olduğundan emin olun.

Projeyi Geliştirme

Temel müzik çalar uygulamasını başarıyla oluşturduktan sonra, aşağıdaki özelliklerle projenizi geliştirebilirsiniz:

1. Tekrarlama ve Karıştırma Modları

Şarkıları tekrarlama (tek şarkı, tüm liste) ve karıştırma modları ekleyin:

repeat-shuffle.js
// HTML'e tekrarlama ve karıştırma butonları ekleyin
// <button class="control-btn" id="repeatBtn"><i class="fas fa-redo"></i></button>
// <button class="control-btn" id="shuffleBtn"><i class="fas fa-random"></i></button>

// DOM elementlerini seç
const repeatBtn = document.getElementById('repeatBtn');
const shuffleBtn = document.getElementById('shuffleBtn');

// Değişkenler
let repeatMode = 'none'; // 'none', 'one', 'all'
let isShuffleOn = false;
let originalPlaylist = [...songs]; // Orijinal çalma listesini kopyala

// Olay dinleyicileri
repeatBtn.addEventListener('click', toggleRepeat);
shuffleBtn.addEventListener('click', toggleShuffle);

// Tekrarlama modunu değiştirme fonksiyonu
function toggleRepeat() {
    if (repeatMode === 'none') {
        repeatMode = 'all';
        repeatBtn.innerHTML = '';
        repeatBtn.classList.add('active');
    } else if (repeatMode === 'all') {
        repeatMode = 'one';
        repeatBtn.innerHTML = '1';
    } else {
        repeatMode = 'none';
        repeatBtn.innerHTML = '';
        repeatBtn.classList.remove('active');
    }
}

// Karıştırma modunu değiştirme fonksiyonu
function toggleShuffle() {
    isShuffleOn = !isShuffleOn;
    
    if (isShuffleOn) {
        shuffleBtn.classList.add('active');
        shufflePlaylist();
    } else {
        shuffleBtn.classList.remove('active');
        // Orijinal çalma listesine geri dön
        songs = [...originalPlaylist];
        // Mevcut şarkının yeni indeksini bul
        const currentSong = originalPlaylist[currentSongIndex];
        currentSongIndex = songs.findIndex(song => song.title === currentSong.title);
        // Çalma listesini yeniden oluştur
        createPlaylist();
    }
}

// Çalma listesini karıştırma fonksiyonu
function shufflePlaylist() {
    // Mevcut şarkıyı kaydet
    const currentSong = songs[currentSongIndex];
    
    // Çalma listesini karıştır
    for (let i = songs.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [songs[i], songs[j]] = [songs[j], songs[i]];
    }
    
    // Mevcut şarkının yeni indeksini bul
    currentSongIndex = songs.findIndex(song => song.title === currentSong.title);
    
    // Çalma listesini yeniden oluştur
    createPlaylist();
}

// Şarkı bittiğinde çalışacak fonksiyonu güncelle
audioPlayer.addEventListener('ended', () => {
    if (repeatMode === 'one') {
        // Aynı şarkıyı tekrarla
        audioPlayer.currentTime = 0;
        playSong();
    } else if (repeatMode === 'all') {
        // Sonraki şarkıya geç, liste sonundaysa başa dön
        nextSong();
    } else if (isShuffleOn) {
        // Rastgele bir şarkıya geç
        const randomIndex = Math.floor(Math.random() * songs.length);
        currentSongIndex = randomIndex;
        loadSong(currentSongIndex);
        playSong();
    } else {
        // Normal davranış: sonraki şarkıya geç
        nextSong();
    }
});

2. Ekolayzer ve Ses Efektleri

Web Audio API kullanarak ekolayzer ve ses efektleri ekleyin:

equalizer.js
// HTML'e ekolayzer kontrollerini ekleyin
// <div class="equalizer-container">
//     <div class="equalizer-slider" data-frequency="60">
//         <div class="eq-label">60Hz</div>
//         <input type="range" min="-12" max="12" value="0" class="eq-control">
//     </div>
//     <div class="equalizer-slider" data-frequency="170">
//         <div class="eq-label">170Hz</div>
//         <input type="range" min="-12" max="12" value="0" class="eq-control">
//     </div>
//     <div class="equalizer-slider" data-frequency="350">
//         <div class="eq-label">350Hz</div>
//         <input type="range" min="-12" max="12" value="0" class="eq-control">
//     </div>
//     <div class="equalizer-slider" data-frequency="1000">
//         <div class="eq-label">1kHz</div>
//         <input type="range" min="-12" max="12" value="0" class="eq-control">
//     </div>
//     <div class="equalizer-slider" data-frequency="3500">
//         <div class="eq-label">3.5kHz</div>
//         <input type="range" min="-12" max="12" value="0" class="eq-control">
//     </div>
//     <div class="equalizer-slider" data-frequency="10000">
//         <div class="eq-label">10kHz</div>
//         <input type="range" min="-12" max="12" value="0" class="eq-control">
//     </div>
// </div>

// Web Audio API değişkenleri
let audioContext;
let source;
let gainNode;
let filters = [];

// Ekolayzer kurulumu
function setupEqualizer() {
    // AudioContext oluştur
    audioContext = new (window.AudioContext || window.webkitAudioContext)();
    
    // Ses kaynağını bağla
    source = audioContext.createMediaElementSource(audioPlayer);
    
    // Gain node oluştur (ana ses kontrolü için)
    gainNode = audioContext.createGain();
    
    // Frekans bantları için filtreler oluştur
    const frequencies = [60, 170, 350, 1000, 3500, 10000];
    
    frequencies.forEach(frequency => {
        const filter = audioContext.createBiquadFilter();
        filter.type = 'peaking'; // Zirve filtresi
        filter.frequency.value = frequency;
        filter.Q.value = 1; // Kalite faktörü
        filter.gain.value = 0; // Başlangıçta nötr
        filters.push(filter);
    });
    
    // Ses zincirini oluştur: source -> filters -> gainNode -> destination
    source.connect(filters[0]);
    for (let i = 0; i < filters.length - 1; i++) {
        filters[i].connect(filters[i + 1]);
    }
    filters[filters.length - 1].connect(gainNode);
    gainNode.connect(audioContext.destination);
    
    // Ekolayzer kontrollerini bağla
    document.querySelectorAll('.eq-control').forEach((control, index) => {
        control.addEventListener('input', function() {
            filters[index].gain.value = parseFloat(this.value);
        });
    });
}

// Çalma butonuna tıklandığında ekolayzeri başlat
playBtn.addEventListener('click', function() {
    // AudioContext ilk kullanıcı etkileşimiyle başlatılmalıdır
    if (!audioContext) {
        setupEqualizer();
    } else if (audioContext.state === 'suspended') {
        audioContext.resume();
    }
});

3. Şarkı Sözleri Gösterme

Şarkı çalarken sözlerini gösterme özelliği ekleyin:

lyrics.js
// HTML'e şarkı sözleri bölümü ekleyin
// <div class="lyrics-container" id="lyricsContainer">
//     <div class="lyrics-header">
//         <h3>Şarkı Sözleri</h3>
//         <button id="toggleLyricsBtn"><i class="fas fa-chevron-down"></i></button>
//     </div>
//     <div class="lyrics-content" id="lyricsContent"></div>
// </div>

// Şarkı sözleri verileri (örnek)
const lyrics = {
    "Acoustic Breeze": [
        { time: 0, text: "Bu şarkının sözleri yok." }
    ],
    "Creative Minds": [
        { time: 0, text: "Bu şarkının sözleri yok." }
    ],
    "Summer": [
        { time: 5, text: "Yaz güneşi parlıyor" },
        { time: 15, text: "Deniz dalgaları kıyıya vuruyor" },
        { time: 25, text: "Kumsalda yürüyorum" },
        { time: 35, text: "Rüzgar saçlarımı savuruyor" },
        { time: 45, text: "Yaz günleri ne güzel" },
        { time: 55, text: "Keşke hiç bitmese" }
    ],
    "Jazzy Frenchy": [
        { time: 0, text: "Bu şarkının sözleri yok." }
    ]
};

// DOM elementlerini seç
const lyricsContainer = document.getElementById('lyricsContainer');
const toggleLyricsBtn = document.getElementById('toggleLyricsBtn');
const lyricsContent = document.getElementById('lyricsContent');

// Değişkenler
let isLyricsVisible = false;
let currentLyrics = [];
let currentLyricIndex = 0;

// Olay dinleyicileri
toggleLyricsBtn.addEventListener('click', toggleLyrics);
audioPlayer.addEventListener('timeupdate', updateLyrics);

// Şarkı sözlerini göster/gizle
function toggleLyrics() {
    isLyricsVisible = !isLyricsVisible;
    
    if (isLyricsVisible) {
        lyricsContainer.classList.add('expanded');
        toggleLyricsBtn.innerHTML = '';
    } else {
        lyricsContainer.classList.remove('expanded');
        toggleLyricsBtn.innerHTML = '';
    }
}

// Şarkı yüklendiğinde sözleri hazırla
function loadLyrics(songTitle) {
    currentLyrics = lyrics[songTitle] || [];
    currentLyricIndex = 0;
    
    if (currentLyrics.length > 0) {
        lyricsContent.innerHTML = '' + currentLyrics[0].text + '';
    } else {
        lyricsContent.innerHTML = 'Şarkı sözleri bulunamadı.';
    }
}

// Şarkı çalarken sözleri güncelle
function updateLyrics() {
    if (currentLyrics.length <= 1) return;
    
    const currentTime = audioPlayer.currentTime;
    
    // Bir sonraki söz satırının zamanı geldiyse göster
    if (currentLyricIndex < currentLyrics.length - 1 && 
        currentTime >= currentLyrics[currentLyricIndex + 1].time) {
        currentLyricIndex++;
        lyricsContent.innerHTML = '' + currentLyrics[currentLyricIndex].text + '';
    }
}

// Şarkı yükleme fonksiyonunu güncelle
function loadSong(index) {
    // ... mevcut kod ...
    
    // Şarkı sözlerini yükle
    loadLyrics(songs[index].title);
}

Geliştirme Zorlukları

Müzik çalar uygulamanızı daha da geliştirmek için aşağıdaki zorlukları deneyebilirsiniz:

  1. Görselleştirme: Web Audio API'nin AnalyserNode'unu kullanarak müzik çalarken ses dalgalarını veya frekans spektrumunu görselleştirin.
  2. Çalma Listesi Yönetimi: Kullanıcıların kendi çalma listelerini oluşturabilmesini, düzenleyebilmesini ve kaydedebilmesini sağlayın.
  3. Tema Seçenekleri: Kullanıcıların farklı renk temaları arasında seçim yapabilmesini sağlayın.
  4. Uyku Zamanlayıcısı: Belirli bir süre sonra müziği otomatik olarak durduran bir zamanlayıcı ekleyin.
  5. Uzaktan Kontrol: Mobil cihazların müzik çaları uzaktan kontrol edebilmesini sağlayan bir özellik ekleyin (WebSocket veya WebRTC kullanarak).

Sonuç ve Öğrenilen Dersler

Bu projede, JavaScript kullanarak bir müzik çalar uygulaması geliştirdik. Bu süreçte şunları öğrendik:

  • HTML5 Audio API'sini kullanarak ses dosyalarını kontrol etmeyi
  • Çalma, duraklatma, ileri/geri sarma gibi medya kontrollerini uygulamayı
  • İlerleme çubuğu ve ses seviyesi kontrolü gibi etkileşimli öğeler oluşturmayı
  • Çalma listesi oluşturmayı ve yönetmeyi
  • CSS ile modern ve duyarlı bir kullanıcı arayüzü tasarlamayı
  • Animasyonlar ve geçişler ekleyerek kullanıcı deneyimini geliştirmeyi
  • Olay yönetimi ve zamanlayıcıları kullanmayı
  • Responsive tasarım ilkelerini uygulamayı

Bu proje, modern web geliştirme becerilerinizi geliştirmenize ve gerçek dünya uygulamaları oluşturmanıza yardımcı olacak temel bilgileri sağlamıştır. Öğrendiğiniz teknikleri ve kavramları kullanarak, daha karmaşık ve tam özellikli medya oynatıcıları geliştirebilirsiniz.