Skip to content

http://mp3.player.io #400

@enginbankan00-commits

Description

@enginbankan00-commits
<title>Gelişmiş Tam Ekran MP3 Oynatıcı</title> <style> /* Genel Stiller */ :root { --bg-dark: #1a1a2e; --player-dark: #2a2a4a; --primary-color: #0077b6; --accent-color: #28a745; --text-color: #fff; --inactive-color: #555; --bar-color: #b3cde0; }
    body {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        margin: 0;
        background-color: var(--bg-dark);
        color: var(--text-color);
        transition: background-color 0.5s;
    }
    
    /* Tam Ekran Modu */
    .fullscreen-active body {
        overflow: hidden; /* Tam ekranda kaydırmayı engelle */
    }

    .player-container {
        background-color: var(--player-dark);
        padding: 25px;
        border-radius: 15px;
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7);
        width: 380px;
        max-width: 90%;
        text-align: center;
        transition: all 0.5s ease;
    }

    /* Tam ekran stilini uygula */
    .player-container.is-fullscreen {
        position: fixed;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        max-width: none;
        border-radius: 0;
        padding: 50px;
        z-index: 9999;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    /* Dosya Seçim Alanı */
    .file-selection-area {
        display: flex;
        gap: 10px;
        justify-content: center;
        margin-bottom: 20px;
        flex-wrap: wrap;
    }

    #fileInputSingle, #fileInputMultiple, #directoryInput {
        display: none;
    }

    .file-label {
        display: inline-flex;
        align-items: center;
        background-color: var(--primary-color);
        color: var(--text-color);
        padding: 10px 15px;
        border-radius: 8px;
        cursor: pointer;
        font-weight: bold;
        font-size: 14px;
        transition: background-color 0.3s;
    }

    .file-label i {
        margin-right: 8px;
    }

    .file-label:hover {
        background-color: #0096c7;
    }
    
    /* Şarkı Bilgileri */
    #current-track-name {
        font-size: 1.5em;
        margin: 10px 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    
    .time-info {
        display: flex;
        justify-content: space-between;
        font-size: 0.8em;
        color: var(--bar-color);
        margin-bottom: 5px;
    }
    
    .progress-bar-container {
        height: 8px;
        background-color: #555577;
        border-radius: 4px;
        margin-bottom: 20px;
        cursor: pointer;
    }

    .progress-bar {
        height: 100%;
        width: 0%;
        background-color: var(--accent-color);
        border-radius: 4px;
        transition: width 0.1s linear;
    }
    
    /* Kontrol Butonları ve Oynatma Modları */
    .main-controls {
        display: flex;
        justify-content: center;
        align-items: center;
        gap: 20px;
        margin-bottom: 20px;
    }
    
    .mode-controls {
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        margin-bottom: 15px;
    }

    .control-btn, .mode-btn {
        background: none;
        border: none;
        color: var(--text-color);
        cursor: pointer;
        font-size: 1.2em;
        padding: 10px;
        transition: color 0.2s, transform 0.1s;
    }
    
    .control-btn:hover, .mode-btn:hover {
        color: var(--primary-color);
    }
    
    .control-btn:disabled, .mode-btn:disabled {
        color: var(--inactive-color);
        cursor: not-allowed;
    }

    .main-control-btn {
        font-size: 2.5em;
    }
    
    /* Aktif Mod Butonları */
    .mode-btn.active {
        color: var(--accent-color);
    }
    
    /* Görselleştirici (Işıklar) */
    .visualizer-container {
        width: 100%;
        display: flex;
        justify-content: space-between;
        align-items: flex-end;
        height: 80px;
        border-radius: 5px;
        overflow: hidden;
        background-color: #111;
        padding: 0 5px;
    }

    .bar {
        width: 6px;
        background-color: #ff0000;
        height: 2px;
        transition: all 0.05s ease-out;
        display: inline-block;
    }

</style>
<div class="player-container" id="player-container">
    
    <div class="file-selection-area">
        <input type="file" id="fileInputSingle" accept="audio/*">
        <label for="fileInputSingle" class="file-label"><i class="fas fa-file-audio"></i> Tek Şarkı Ekle</label>
        
        <input type="file" id="fileInputMultiple" accept="audio/*" multiple>
        <label for="fileInputMultiple" class="file-label"><i class="fas fa-list-ul"></i> Tümünü Seç & Ekle</label>

        <input type="file" id="directoryInput" webkitdirectory directory multiple accept="audio/*">
        <label for="directoryInput" class="file-label"><i class="fas fa-folder-open"></i> Tüm Klasörü Oku</label>
    </div>

    <div class="track-info">
        <h3 id="current-track-name">Lütfen Şarkı Seçiniz</h3>
        <p id="playlist-status">Oynatma listesi boş.</p>
    </div>
    
    <div class="time-info">
        <span id="currentTime">0:00</span>
        <span id="duration">0:00</span>
    </div>

    <div class="progress-bar-container" id="progress-container">
        <div class="progress-bar" id="progress-bar"></div>
    </div>
    
    <div class="mode-controls">
        <button id="shuffle-btn" class="mode-btn" title="Karıştır">
            <i class="fas fa-random"></i>
        </button>
        <button id="repeat-btn" class="mode-btn" data-mode="none" title="Tekrarlama Modu (Kapalı)">
            <i class="fas fa-redo"></i>
        </button>
        <button id="fullscreen-btn" class="mode-btn" title="Tam Ekran">
            <i class="fas fa-expand"></i>
        </button>
    </div>

    <div class="main-controls">
        <button id="prev-btn" class="control-btn" disabled title="Geri"><i class="fas fa-backward"></i></button>
        <button id="play-pause-btn" class="control-btn main-control-btn" disabled title="Oynat"><i class="fas fa-play"></i></button>
        <button id="next-btn" class="control-btn" disabled title="İleri"><i class="fas fa-forward"></i></button>
    </div>

    <div class="visualizer-container" id="visualizer-container">
        </div>

</div>

<script>
    // HTML Elementleri
    const playerContainer = document.getElementById('player-container');
    const fileInputSingle = document.getElementById('fileInputSingle');
    const fileInputMultiple = document.getElementById('fileInputMultiple');
    const directoryInput = document.getElementById('directoryInput'); // Yeni klasör seçme butonu
    const playPauseBtn = document.getElementById('play-pause-btn');
    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 fullscreenBtn = document.getElementById('fullscreen-btn');
    const currentTrackName = document.getElementById('current-track-name');
    const playlistStatus = document.getElementById('playlist-status');
    const progressBar = document.getElementById('progress-bar');
    const progressContainer = document.getElementById('progress-container');
    const currentTimeEl = document.getElementById('currentTime');
    const durationEl = document.getElementById('duration');
    const visualizerContainer = document.getElementById('visualizer-container');

    // Oynatıcı Durumu
    let playlist = []; // Ana oynatma listesi
    let playOrder = []; // Karıştırma için kullanılan sıra
    let currentTrackIndex = 0; // playOrder'daki mevcut indis
    let isPlaying = false;
    let shuffleMode = false;
    let repeatMode = 'none'; // 'none', 'one', 'all'
    
    // Ses ve Web Audio API
    const audio = new Audio();
    let audioContext = null;
    let analyser;
    const barCount = 40; 
    const bars = [];
    const frequencyData = new Uint8Array(barCount);

    // Görselleştirici Çubuklarını Oluştur
    for (let i = 0; i < barCount; i++) {
        const bar = document.createElement('div');
        bar.classList.add('bar');
        visualizerContainer.appendChild(bar);
        bars.push(bar);
    }

    // ---------- Olay Dinleyicileri ----------

    fileInputSingle.addEventListener('change', (event) => addFilesToPlaylist(event.target.files, false));
    fileInputMultiple.addEventListener('change', (event) => addFilesToPlaylist(event.target.files, true));
    directoryInput.addEventListener('change', (event) => addFilesToPlaylist(event.target.files, true));

    playPauseBtn.addEventListener('click', () => isPlaying ? pauseTrack() : playTrack());
    nextBtn.addEventListener('click', nextTrack);
    prevBtn.addEventListener('click', prevTrack);
    shuffleBtn.addEventListener('click', toggleShuffle);
    repeatBtn.addEventListener('click', toggleRepeat);
    fullscreenBtn.addEventListener('click', toggleFullscreen);
    
    audio.addEventListener('loadedmetadata', updateDuration);
    audio.addEventListener('ended', handleTrackEnded);
    audio.addEventListener('timeupdate', updateProgress);
    progressContainer.addEventListener('click', setProgress);

    // ---------- Oynatma Modu Kontrolleri ----------

    function toggleShuffle() {
        shuffleMode = !shuffleMode;
        shuffleBtn.classList.toggle('active', shuffleMode);
        shuffleBtn.title = shuffleMode ? "Karıştır (Açık)" : "Karıştır (Kapalı)";
        
        // Oynatma listesini yeniden oluştur
        updatePlayOrder();
        
        // Yeni sırada mevcut şarkının konumunu bul
        const currentTrackFile = playlist[playOrder[currentTrackIndex]];
        const newIndex = playOrder.findIndex(index => playlist[index] === currentTrackFile);
        
        if (newIndex !== -1) {
            currentTrackIndex = newIndex;
        }
        updateStatus();
    }

    function toggleRepeat() {
        const modes = ['none', 'one', 'all'];
        let nextIndex = (modes.indexOf(repeatMode) + 1) % modes.length;
        repeatMode = modes[nextIndex];
        
        repeatBtn.dataset.mode = repeatMode;
        repeatBtn.classList.toggle('active', repeatMode !== 'none');
        
        const icon = repeatBtn.querySelector('i');
        icon.className = 'fas';
        
        switch (repeatMode) {
            case 'none':
                icon.classList.add('fa-redo');
                repeatBtn.title = "Tekrarlama Modu (Kapalı)";
                break;
            case 'one':
                icon.classList.add('fa-redo-alt', 'fa-border'); // Tekrar simgesine özel stil
                repeatBtn.title = "Tekrarlama Modu (Tek Şarkı)";
                break;
            case 'all':
                icon.classList.add('fa-redo');
                repeatBtn.title = "Tekrarlama Modu (Tüm Liste)";
                break;
        }
        updateStatus();
    }

    function toggleFullscreen() {
        if (document.fullscreenElement) {
            document.exitFullscreen();
            playerContainer.classList.remove('is-fullscreen');
        } else {
            playerContainer.requestFullscreen().catch(err => {
                alert(`Tam ekran moduna geçilemedi: ${err.message}`);
            });
            playerContainer.classList.add('is-fullscreen');
        }
    }
    
    // ---------- Şarkı Yönetimi Fonksiyonları ----------

    function addFilesToPlaylist(fileList, shouldReplace) {
        const newFiles = Array.from(fileList).filter(file => file.type.startsWith('audio/'));
        
        if (newFiles.length === 0) return;

        if (shouldReplace) {
            playlist = newFiles;
            currentTrackIndex = 0;
        } else {
            playlist.push(...newFiles);
        }
        
        updatePlayOrder();

        if (playlist.length > 0) {
            if (!isPlaying && audio.src === "") {
                loadTrack(currentTrackIndex);
            }
            playPauseBtn.disabled = false;
        }
        
        // Inputları temizle
        fileInputSingle.value = null;
        fileInputMultiple.value = null;
        directoryInput.value = null;
        updateStatus();
    }

    function updatePlayOrder() {
        playOrder = Array.from({ length: playlist.length }, (_, i) => i);
        if (shuffleMode) {
            shuffleArray(playOrder);
        }
    }

    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 loadTrack(playListIndex) {
        const track = playlist[playOrder[playListIndex]];
        currentTrackName.textContent = track ? track.name : "Şarkı Yüklenemedi";
        audio.src = track ? URL.createObjectURL(track) : "";
        updateControls();
    }

    function playTrack() {
        if (playlist.length === 0) return;

        if (!audioContext) {
            initAudioVisualizer();
        }
        if (audioContext.state === 'suspended') {
            audioContext.resume();
        }
        
        audio.play().then(() => {
            isPlaying = true;
            playPauseBtn.innerHTML = '<i class="fas fa-pause"></i>'; 
            requestAnimationFrame(drawVisualizer);
        }).catch(error => {
             console.error("Oynatma hatası:", error);
             isPlaying = false;
             playPauseBtn.innerHTML = '<i class="fas fa-play"></i>';
        });
    }

    function pauseTrack() {
        audio.pause();
        isPlaying = false;
        playPauseBtn.innerHTML = '<i class="fas fa-play"></i>'; 
    }

    function nextTrack() {
        if (playlist.length <= 1) return;
        currentTrackIndex = (currentTrackIndex + 1) % playlist.length;
        loadTrack(currentTrackIndex);
        playTrack();
    }

    function prevTrack() {
        if (playlist.length <= 1) return;
        currentTrackIndex = (currentTrackIndex - 1 + playlist.length) % playlist.length;
        loadTrack(currentTrackIndex);
        playTrack();
    }

    function handleTrackEnded() {
        if (repeatMode === 'one') {
            loadTrack(currentTrackIndex);
            playTrack();
        } else if (repeatMode === 'all') {
            nextTrack();
        } else { // repeatMode === 'none'
            if (currentTrackIndex < playlist.length - 1) {
                nextTrack();
            } else {
                pauseTrack();
                currentTrackIndex = 0;
                updatePlayOrder(); // Bitince karıştırma sırasını yenile
                loadTrack(currentTrackIndex);
                updateControls();
            }
        }
    }
    
    // ---------- Süre ve İlerleme Fonksiyonları ----------

    function formatTime(seconds) {
        if (!isFinite(seconds) || seconds < 0) return "0:00";
        const minutes = Math.floor(seconds / 60);
        const secs = Math.floor(seconds % 60);
        return `${minutes}:${secs < 10 ? '0' : ''}${secs}`;
    }

    function updateDuration() {
        durationEl.textContent = formatTime(audio.duration);
    }

    function updateProgress() {
        if (!isFinite(audio.duration)) return;
        const progressPercent = (audio.currentTime / audio.duration) * 100;
        progressBar.style.width = `${progressPercent}%`;
        currentTimeEl.textContent = formatTime(audio.currentTime);
    }

    function setProgress(e) {
        const width = progressContainer.clientWidth;
        const clickX = e.offsetX;
        const duration = audio.duration;
        if (isFinite(duration) && duration > 0) {
            audio.currentTime = (clickX / width) * duration;
        }
    }
    
    function updateStatus() {
        playlistStatus.textContent = `Toplam ${playlist.length} şarkı. Şu an: ${currentTrackIndex + 1} / ${playlist.length}`;
        updateControls();
    }

    function updateControls() {
        const disable = playlist.length === 0;
        prevBtn.disabled = disable || playlist.length <= 1;
        nextBtn.disabled = disable || playlist.length <= 1;
        playPauseBtn.disabled = disable;
    }
    
    // ---------- Görselleştirici Fonksiyonları ----------
    
    function initAudioVisualizer() {
        audioContext = new (window.AudioContext || window.webkitAudioContext)();
        const source = audioContext.createMediaElementSource(audio);
        analyser = audioContext.createAnalyser();
        analyser.fftSize = 64; 
        analyser.smoothingTimeConstant = 0.8;
        
        source.connect(analyser);
        analyser.connect(audioContext.destination);
    }

    function drawVisualizer() {
        if (!isPlaying || !analyser) return;

        analyser.getByteFrequencyData(frequencyData);

        for (let i = 0; i < barCount; i++) {
            let value = frequencyData[i]; 
            const percent = value / 255;
            const height = percent * 75 + 2; 
            
            const bar = bars[i];
            bar.style.height = `${height}px`;
            
            // Ritim ve konuma göre renk değiştirme
            const hue = i * (360 / barCount) + percent * 100; 
            bar.style.backgroundColor = `hsl(${hue}, 100%, ${50 + percent * 30}%)`;
        }

        requestAnimationFrame(drawVisualizer);
    }
    
    // Başlangıçta kontrolleri güncelle
    updateControls();
</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions