RANDOM_SOUND_TRACK_PLAYER_WITH_STATS


The single web page application featured in this tutorial is an MP3 audio file player which randomly selects exactly one of some finite number, N, of such files to play per for the duration of that audio recording and then immediately repeating that process with the next randomly selected audio file for an indefinitely long time.

(Theoretically, each of the N sound track files has the same probability of being selected by this audio player application. That idealized probality is the quantity 1/N * 100% (in terms of percentage of certainty about the respective file being selected)).

Note that a live version of the RANDOM_SOUND_TRACK_PLAYER_WITH_STATS application is available to try using immediately from your current web browser at the following web address: https://karlinarayberinger.github.io/KARBYTES_BLOG_APPS_github_hosted_website/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/random_sound_track_player_with_stats.html

To view hidden text inside of the preformatted text boxes below, scroll horizontally.


RANDOM_SOUND_TRACK_PLAYER_WITH_STATS Software Application Components


Hyper-Text-Markup-Language_file: https://raw.githubusercontent.com/karlinarayberinger/KARLINA_OBJECT_extension_pack_60/main/random_sound_track_player_with_stats.html

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/empty_audio_10_seconds.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/empty_audio_30_seconds.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/empty_audio_45_seconds.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_05june2025.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_13july2024.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_14april2025.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_14june2025.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_20august2024.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_24february2026_p0.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_25january2026_p0.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_29january2025.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/guitar_karbytes_30july2024.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/karbytes_guitar_07_june_2023.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/karbytes_guitar_13_may_2023.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/karbytes_guitar_16_october_2023.mp3

MP3_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_BLOG_APPS_github_hosted_website/main/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/karbytes_guitar_castro_valley_california_12_december_2022.mp3


RANDOM_SOUND_TRACK_PLAYER_WITH_STATS Hyper-Text-Markup-Language Code


The following Hyper-Text-Markup-Language (HTML) code defines the user interface component of the FRANDOM_SOUND_TRACK_PLAYER_WITH_STATS web page application.

Copy the HTML code from the source code file which is linked below into a text editor and save that file as random_sound_track_player_with_stats.html. Use a web browser such as Firefox to open that HTML file.

(Note that angle brackets which resemble HTML tags (i.e. an “is less than” symbol (i.e. ‘<‘) followed by an “is greater than” symbol (i.e. ‘>’)) displayed on this web page have been replaced (at the source code level of this web page) with the Unicode symbols U+003C (which is rendered by the web browser as ‘<‘) and U+003E (which is rendered by the web browser as ‘>’). That is because the WordPress web page editor or web browser interprets a plain-text version of an “is less than” symbol followed by an “is greater than” symbol as being an opening HTML tag (which means that the WordPress web page editor or web browser deletes or fails to display those (plain-text) inequality symbols and the content between those (plain-text) inequality symbols)).

If copy-pasting the following HTML code from the preformatted text box below into a text editor, remove the zero-width space Unicode character (&​#8203;) which is located between the ‘s’ and the ‘r’ in the script tag(s) which each link to a JavaScript file.

Hyper-Text-Markup-Language_file: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_SOFTWARE_ENGINEERING_PORTFOLIO/main/random_sound_track_player_with_stats.html


<!--
  /**
   * file: random_sound_track_player_with_stats.html
   * type: Hyper-Text-Markup-Language
   * date: 29_MARCH_2026
   * author: karbytes
   * license: PUBLIC_DOMAIN
   */
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>RANDOM_SOUND_TRACK_PLAYER_WITH_STATS</title>
  <!-- Inline Cascading-Style-Sheet (CSS) code to control appearance of web page elements -->
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 2rem;
      background: #111;
      color: #eee;
    }
    button {
      font-size: 1rem;
      padding: 0.75rem 1rem;
      margin-right: 0.5rem;
      cursor: pointer;
    }
    #status, #stats {
      margin-top: 1rem;
      padding: 1rem;
      background: #222;
      border-radius: 8px;
    }
    table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 1rem;
    }
    th, td {
      padding: 0.5rem;
      border-bottom: 1px solid #444;
      text-align: left;
    }
  </style>
</head>
<body>
  <!-- Static header text at the top of the web page -->
  <h1>RANDOM_SOUND_TRACK_PLAYER_WITH_STATS</h1>
  
  <!-- Click the button to initiate indefinitely-playing MP3 randomized selection (and silent audio MP3 looping to keep session active). -->
  <button id="startButton">Start Playing Songs</button>
  
  <!-- The "status" element displays error messages, the name of the non-silent MP3 being played, or the default text between the opening and closing DIV tags. -->
  <div id="status">Not playing.</div>

  <!-- A dynamically-updated "stats" table displaying all the available non-silent MP3 files and how many times they have each been played during the current session. -->
  <div id="stats">
    <strong>Total Playtime (seconds):</strong> <span id="totalTime">0</span>
    <table>
      <thead>
        <tr>
          <th>MP3 File</th>
          <th>Play Count</th>
        </tr>
      </thead>
      <tbody id="playlistStats"></tbody>
    </table>
  </div>

  <!-- The "audioPlayer" element maps to the non-silent MP3 files and allows them to be played via the web browser. -->
  <audio id="audioPlayer"></audio>

  <!-- The "silentAudioPlayer" element maps to the silent MP3 files and allows them to be played via the web browser. -->
  <audio id="silentAudioPlayer"></audio>
  
<!-- Inline JavaScript (JS) code to control web page behavior -->
<script>
  /**
   * On mobile devices such as an Android smartphone, only one browser tab and only one
   * non-OS software application can be actively featured in the user's "viewport" per
   * instant. By contrast, on more fully-featured machines such as a Ubuntu laptop computer,
   * multiple browser tabs and multiple non-OS software applications can be running simultaneously
   * inside of one "viewport" (i.e. user experience instant).
   * 
   * A "workaround" to prevent the randomized sound track player from stopping between songs on a
   * mobile device is to (continuously) play multiple silent audio files which have staggered playtimes 
   * so that there is always at least one of those silent audio files playing "in the background" (which 
   * keeps the web application browser tab active until the browser tab is closed).
   */

  // Create a list of silent audio file URLs.
  // const file_path_root = 'h‌ttp://qkbrwfubnh4knc6kkhx6uepccavpwezdf2al7w2quepe3qociegsi3yd.onion/KARBYTES_BLOG_APPS/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/';
  // const file_path_root = 'h‌ttps://karlinarayberinger.github.io/KARBYTES_BLOG_APPS_github_hosted_website/RANDOM_SOUND_TRACK_PLAYER_WITH_STATS/';
  const file_path_root = '';
  const silentSoundTracks = [
    file_path_root + 'empty_audio_10_seconds.mp3',
    file_path_root + 'empty_audio_30_seconds.mp3',
    file_path_root + 'empty_audio_45_seconds.mp3'
  ];

  // Create and configure silent audio elements.
  const silentAudioElements = silentSoundTracks.map(src => {
    const audio = new Audio(src);
    audio.loop = true;
    return audio;
  });

  function startPlayingSilentSoundTracks() {
    silentAudioElements.forEach(audio => {
      audio.play().catch(err => {
        console.warn("Failed to play track:", err);
      });
    });
  }
  // "wrapper" function
  function keep_session_active() {
    startPlayingSilentSoundTracks();
  }

  // Create a handle to the hard-coded "silentAudioPlayer" HTML element.
  const silentAudioPlayer = document.getElementById("silentAudioPlayer");

  /***************************************************************/

  // Define a list of non-silent audio files to play one-at-a-time in a randomized fashion after clicking the startButton.
  const mp3Files = [
      "guitar_karbytes_24february2026_p0.mp3",
      "karbytes_guitar_13_may_2023.mp3",
      "karbytes_guitar_07_june_2023.mp3",
      "karbytes_guitar_castro_valley_california_12_december_2022.mp3",
      "karbytes_guitar_16_october_2023.mp3",
      "guitar_karbytes_20august2024.mp3",
      "guitar_karbytes_14april2025.mp3",
      "guitar_karbytes_13july2024.mp3",
      "guitar_karbytes_25january2026_p0.mp3",
      "guitar_karbytes_14june2025.mp3",
      "guitar_karbytes_05june2025.mp3",
      "guitar_karbytes_29january2025.mp3",
      "guitar_karbytes_30july2024.mp3"
  ];

  // Create a handle to the hard-coded "audioPlayer" HTML element.
  const audioPlayer = document.getElementById("audioPlayer");

  // Create handles to statistics-related HTML elements.
  const statusBox = document.getElementById("status");
  const totalTimeDisplay = document.getElementById("totalTime");
  const playlistStatsBody = document.getElementById("playlistStats");

  // Initialize program variables.
  let isPlaying = false;
  let currentIndex = -1;
  let totalPlayTimeSeconds = 0;
  let playCounts = {};
  let lastTimeUpdate = 0;

  // Initialize the play counts for each non-silent MP3 file.
  mp3Files.forEach(file => {
      playCounts[file] = 0;
  });

  // Populate the statistics table with non-silent audio files information.
  function renderStats() {
      totalTimeDisplay.textContent = Math.floor(totalPlayTimeSeconds);
      playlistStatsBody.innerHTML = "";
      mp3Files.forEach(file => {
        const row = document.createElement("tr");
        const nameCell = document.createElement("td");
        nameCell.textContent = file;
        const countCell = document.createElement("td");
        countCell.textContent = playCounts[file];
        row.appendChild(nameCell);
        row.appendChild(countCell);
        playlistStatsBody.appendChild(row);
      });
  }

  // Generate a random nonnegative index number which represents one of the non-silent MP3 files listed in the table.
  function getRandomIndex() {
    if (mp3Files.length === 1) return 0;
    let nextIndex;
    do {
      nextIndex = Math.floor(Math.random() * mp3Files.length);
    } while (nextIndex === currentIndex);
    return nextIndex;
  }

  // Randomly select a non-silent MP3 file to play. Then update its count and start playing it via the audioPlayer.
  function playNextRandomSong() {
    if (!isPlaying) return;
    currentIndex = getRandomIndex();
    const file = mp3Files[currentIndex];
    playCounts[file] += 1;
    renderStats();
    audioPlayer.src = file;
    audioPlayer.play().then(() => {
      statusBox.textContent = "Now playing: " + file;
      lastTimeUpdate = audioPlayer.currentTime;
    }).catch(err => {
      statusBox.textContent = "Error: " + err.message;
    });
  }

  // Obtain the total playtime of the non-silent MP3 files.
  audioPlayer.addEventListener("timeupdate", () => {
    if (!isPlaying) return;
    const currentTime = audioPlayer.currentTime;
    const delta = currentTime - lastTimeUpdate;
    if (delta > 0 && delta < 1) {
      totalPlayTimeSeconds += delta;
    }
    lastTimeUpdate = currentTime;
    totalTimeDisplay.textContent = Math.floor(totalPlayTimeSeconds);
  });

  // Upon the "event" of one non-silent MP3 audio finishing, have the audioPlayer randomly select the next song to play.
  audioPlayer.addEventListener("ended", () => {
    playNextRandomSong();
  });

  // Create a handle to the hard-coded "startButton" HTML element.
  const startButton = document.getElementById("startButton");

  // Upon the "event" of the startButton being clicked, initiate the silent audio track loops (which have staggered play times to prevent the browser tab from becoming idle).
  startButton.addEventListener("click", () => {
    if (!isPlaying) {
      isPlaying = true;
      startButton.style.display = "none"; // hide start button for an indefinitely long time
      keep_session_active(); // keep at least one silent audio file playing "in the background" to prevent the non-silent audio files from ceasing to be played in succession.
      playNextRandomSong();
    }
  });

  // Populate the web page with current stats.
  renderStats();
</script>
</body>
</html>

RANDOM_SOUND_TRACK_PLAYER_WITH_STATS Interface (after loading the web page)


The screenshot image below depicts an instance of the RANDOM_SOUND_TRACK_PLAYER_WITH_STATS immediately after the app was loaded by the web browser (and before clicking the startButton).


image_link: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_SOFTWARE_ENGINEERING_PORTFOLIO/main/random_sound_track_player_with_stats_interface_screenshot_p0.png



RANDOM_SOUND_TRACK_PLAYER_WITH_STATS Interface Interface (after clicking startButton)


The screenshot image below depicts an instance of the RANDOM_SOUND_TRACK_PLAYER_WITH_STATS after the user clicked on the startButton (and waited for every MP3 file in the list to play at least once).


image_link: https://raw.githubusercontent.com/karlinarayberinger/KARBYTES_SOFTWARE_ENGINEERING_PORTFOLIO/main/random_sound_track_player_with_stats_interface_screenshot_p1.png



This web page was last updated on 29_MARCH_2026. The content displayed on this web page is licensed as PUBLIC_DOMAIN intellectual property.