Player Audio Yooutube - List taken form text

file list (list1.txt, list2.txt, dll.)


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>YouTube Video List</title>
    <!-- Bootstrap CSS -->
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
    <!-- Font Awesome CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
    <style>
        .thumbnail {
            width: 50px;
            height: auto;
            margin-right: 10px;
        }
        .list-group-item {
            display: flex;
            align-items: center;
        }
        .play-icon {
            margin-left: auto;
            font-size: 24px;
            cursor: pointer;
        }
        .youtube-audio-player {
            display: none;
            position: fixed;
            bottom: 0;
            left: 5%;
            width: 90%;
            background: #f8f9fa;
            box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
            z-index: 1000;
            padding: 5px;
            text-align: center;
        }
        .audio-controls {
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .audio-controls button {
            border-radius: 50%;
            margin: 0 5px;
        }
        .slider {
            margin: 0 15px;
            width: 450px;
        }
        .song-title {
            margin-left: 10px;
        }
        @media (max-width: 768px) {
            .current-time, .total-duration, .song-title {
                display: none;
            }
            .slider {
                width: 150px;
            }
        }
        .volume-control {
            display: none;
        }
        .audio-controls .btn-shuffle.active,
        .audio-controls .btn-loop.active {
            background-color: #007bff;
            color: white;
        }
    </style>
</head>
<body>

<div class="container mt-5">
    <h1 class="mb-4">YouTube Video List</h1>
    <ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
        <?php
        $files = glob("list*.txt");
        $categories = [];
        foreach ($files as $index => $file) {
            $lines = file($file, FILE_IGNORE_NEW_LINES);
            if ($lines) {
                $category = array_shift($lines);
                $categories[$index] = $category;
                $activeClass = ($index === 0) ? 'active' : '';
                echo '<li class="nav-item">';
                echo '<a class="nav-link ' . $activeClass . '" id="pills-' . $index . '-tab" data-toggle="pill" href="#pills-' . $index . '" role="tab" aria-controls="pills-' . $index . '" aria-selected="' . ($index === 0 ? 'true' : 'false') . '">' . htmlspecialchars($category) . '</a>';
                echo '</li>';
            }
        }
        ?>
    </ul>
    <div class="tab-content" id="pills-tabContent">
        <?php
        foreach ($files as $index => $file) {
            $activeClass = ($index === 0) ? 'show active' : '';
            echo '<div class="tab-pane fade ' . $activeClass . '" id="pills-' . $index . '" role="tabpanel" aria-labelledby="pills-' . $index . '-tab">';
            echo '<div class="row">';

            $lines = file($file, FILE_IGNORE_NEW_LINES);
            array_shift($lines); // Remove the category line
            foreach ($lines as $line) {
                $videoData = explode(",", trim($line));
                $title = $videoData[0];
                $url = $videoData[1];
                parse_str(parse_url($url, PHP_URL_QUERY), $urlParams);
                $videoId = $urlParams['v'];
                $thumbnailUrl = "https://img.youtube.com/vi/$videoId/default.jpg";

                echo '<div class="col-md-4 mb-4">';
                echo '<div class="list-group-item">';
                echo '<img src="' . $thumbnailUrl . '" class="thumbnail" alt="Thumbnail">';
                echo '<div>' . htmlspecialchars($title) . '</div>';
                echo '<i class="fas fa-play play-icon" data-video-id="' . $videoId . '"></i>';
                echo '</div>';
                echo '</div>';
            }

            echo '</div>';
            echo '</div>';
        }
        ?>
    </div>
</div>

<div class="youtube-audio-player" id="audioPlayer">
    <div id="player"></div>
    <div class="audio-controls">
        <span class="current-time" id="currentTime">0:00</span>
        <button class="btn btn-secondary" id="prevButton"><i class="fas fa-step-backward"></i></button>
        <button class="btn btn-primary" id="playPauseButton"><i class="fas fa-play"></i></button>
        <input type="range" class="slider" id="seekSlider" value="0" step="1">
        <button class="btn btn-secondary" id="nextButton"><i class="fas fa-step-forward"></i></button>
        <button class="btn btn-secondary" id="volumeButton"><i class="fas fa-volume-up"></i></button>
        <input type="range" class="slider volume-control" id="volumeSlider" value="100" step="1" min="0" max="100">
        <button class="btn btn-secondary btn-shuffle" id="shuffleButton"><i class="fas fa-random"></i></button>
        <button class="btn btn-secondary btn-loop" id="loopButton"><i class="fas fa-redo"></i></button>
        <span class="total-duration" id="totalDuration">0:00</span>
        <span class="song-title" id="songTitle"></span>
    </div>
</div>

<!-- Bootstrap JS and dependencies -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

<!-- YouTube IFrame API -->
<script src="https://www.youtube.com/iframe_api"></script>
<script>
    var player;
    var isPlaying = false;
    var isShuffling = false;
    var isLooping = false;
    var videoList = [];
    var currentVideoIndex = 0;
    var sliderInterval;

    document.addEventListener('DOMContentLoaded', function() {
        document.querySelectorAll('.play-icon').forEach(icon => {
            icon.addEventListener('click', function() {
                var videoId = this.getAttribute('data-video-id');
                currentVideoIndex = videoList.findIndex(video => video.id === videoId);
                loadPlayer(videoId);
            });
        });

        document.getElementById('prevButton').addEventListener('click', function() {
            currentVideoIndex = (currentVideoIndex > 0) ? currentVideoIndex - 1 : videoList.length - 1;
            loadPlayer(videoList[currentVideoIndex].id);
        });

        document.getElementById('nextButton').addEventListener('click', function() {
            if (isShuffling) {
                currentVideoIndex = Math.floor(Math.random() * videoList.length);
            } else {
                currentVideoIndex = (currentVideoIndex < videoList.length - 1) ? currentVideoIndex + 1 : 0;
            }
            loadPlayer(videoList[currentVideoIndex].id);
        });

        document.getElementById('volumeButton').addEventListener('click', function() {
            var volumeControl = document.getElementById('volumeSlider');
            volumeControl.style.display = volumeControl.style.display === 'none' ? 'block' : 'none';
        });

        document.getElementById('shuffleButton').addEventListener('click', function() {
            isShuffling = !isShuffling;
            this.classList.toggle('active');
        });

        document.getElementById('loopButton').addEventListener('click', function() {
            isLooping = !isLooping;
            this.classList.toggle('active');
        });

        // Load video list from PHP
        <?php foreach ($files as $file) : ?>
            <?php
                $lines = file($file, FILE_IGNORE_NEW_LINES);
                array_shift($lines); // Remove the category line
            ?>
            <?php foreach ($lines as $line) : ?>
                <?php
                    $videoData = explode(",", trim($line));
                    $title = $videoData[0];
                    $url = $videoData[1];
                    parse_str(parse_url($url, PHP_URL_QUERY), $urlParams);
                    $videoId = $urlParams['v'];
                ?>
                videoList.push({ id: "<?php echo $videoId; ?>", title: "<?php echo htmlspecialchars($title); ?>" });
            <?php endforeach; ?>
        <?php endforeach; ?>
    });

    function onYouTubeIframeAPIReady() {
        // Player setup handled on demand
    }

    function loadPlayer(videoId) {
        if (player) {
            player.loadVideoById(videoId);
        } else {
            player = new YT.Player('player', {
                height: '0',
                width: '0',
                videoId: videoId,
                playerVars: {
                    'autoplay': 0,
                    'controls': 0
                },
                events: {
                    'onReady': onPlayerReady,
                    'onStateChange': onPlayerStateChange
                }
            });
        }
        document.getElementById('audioPlayer').style.display = 'block';
        updateSongTitle(videoId);
    }

    function onPlayerReady(event) {
        document.getElementById('playPauseButton').addEventListener('click', function() {
            if (isPlaying) {
                player.pauseVideo();
            } else {
                player.playVideo();
            }
        });

        document.getElementById('seekSlider').addEventListener('input', function() {
            var seekTo = player.getDuration() * (this.value / 100);
            player.seekTo(seekTo, true);
        });

        document.getElementById('volumeSlider').addEventListener('input', function() {
            player.setVolume(this.value);
        });
    }

    function onPlayerStateChange(event) {
        clearInterval(sliderInterval);

        if (event.data == YT.PlayerState.PLAYING) {
            isPlaying = true;
            document.getElementById('playPauseButton').innerHTML = '<i class="fas fa-pause"></i>';
            sliderInterval = setInterval(updateSlider, 1000);
        } else {
            isPlaying = false;
            document.getElementById('playPauseButton').innerHTML = '<i class="fas fa-play"></i>';
        }

        if (event.data == YT.PlayerState.ENDED) {
            if (isLooping) {
                player.playVideo();
            } else {
                document.getElementById('nextButton').click();
            }
        }
    }

    function updateSlider() {
        var seekSlider = document.getElementById('seekSlider');
        var currentTime = player.getCurrentTime();
        var duration = player.getDuration();
        seekSlider.value = (currentTime / duration) * 100;
        document.getElementById('currentTime').textContent = formatTime(currentTime);
        document.getElementById('totalDuration').textContent = formatTime(duration);
    }

    function updateSongTitle(videoId) {
        var song = videoList.find(video => video.id === videoId);
        document.getElementById('songTitle').textContent = song ? song.title : '';
    }

    function formatTime(seconds) {
        var minutes = Math.floor(seconds / 60);
        var seconds = Math.floor(seconds % 60);
        return minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
    }
</script>

</body>
</html>

EP Note

  1. PHP Bagian:

    • Membaca setiap file list*.txt dan mengambil kategori dari baris pertama setiap file.
    • Membuat tab dan konten tab secara dinamis berdasarkan file yang ditemukan.
    • Menggunakan array videoList untuk menyimpan semua video dari semua file dan menginisialisasi JavaScript dengan json_encode.
  2. HTML Bagian:

    • Menggunakan tab dari Bootstrap untuk menampilkan kategori dan konten secara dinamis.
    • Menambahkan ikon play untuk setiap video.
  3. CSS Bagian:

    • Menambahkan gaya untuk menampilkan kontrol audio dengan rapi dan sejajar.
    • Menyembunyikan kontrol volume dan menambahkannya kembali saat tombol volume diklik.
  4. JavaScript Bagian:

    • Menambahkan fitur shuffle dan loop dengan mengatur event listeners untuk tombol shuffle dan loop.
    • Menggunakan updateSongTitle untuk memperbarui judul lagu yang sedang diputar.
    • Memperbarui updateSlider untuk memperbarui slider dan waktu pemutaran.

Perubahan ini memastikan semua daftar dari list*.txt diambil dengan benar dan konten ditampilkan sesuai dengan kategorinya. Video player juga mendukung shuffle dan loop.

Audio Title
0:00 / 0:00
Next Post Previous Post