WIDGETS

Music Player Widget

Click To Go Back To The Widgets Page

About

This is a music player widget, which can play songs from a JSON playlist file. It has basic playback and volume control buttons, can also show the song's album cover image and open song's original source by clicking on the image.

Version: 1.2, File Size: 20.72KB

How To Add?

By hotlinking:

Put this script on your HTML document.

<script src="https://404city.neocities.org/widget/musicPlayer.js" data-finishmode="next" data-randomstart="false" data-playlist="YOUR_PLAYLIST_FILE_PATH_HERE"></script>
By uploading on your site (Recommended):

Click here to download script. Then, upload it on your site and put this line on your HTML document.

<script src="YOUR_SCRIPT_PATH_HERE" data-finishmode="next" data-randomstart="false" data-playlist="YOUR_PLAYLIST_FILE_PATH_HERE"></script>
  • Make sure the script is located after <body> but before </body>.
  • The music player will instantly pop-up where you put the script.

How To Add Songs?

  • To add songs, you have to create a JSON file on your site (For example, playlist.json). This will be your playlist file.
  • After adding your widget, set the data-playlist attribute of your script to your JSON playlist file's path.
    (Example => data-playlist="/assets/json/playlist.json").
  • You can add many songs as you want to using this structure:
[ { "songURL": "URL or File Path of Song1", "displayText": "The text that will displayed while Song1 is playing.", "coverImage": "The album cover image path of Song1", "originalSource": "The original source of Song1" }, { "songURL": "URL or File Path of Song2", "displayText": "The text that will displayed while Song2 is playing.", "coverImage": "The album cover image path of Song2", "originalSource": "The original source of Song2" }, { "songURL": "URL or File Path of Song3", "displayText": "The text that will displayed while Song3 is playing.", "coverImage": "The album cover image path of Song3", "originalSource": "The original source of Song3" } ]

You can also take a look at my demo playlist file here if you need an example.


Script Attributes:

Here are the script attributes of the music player widget.

AttributeConditions
data-finishmode next => sets the playback mode to "Next" when the music player is loaded.
random => sets the playback mode to "Random" when the music player is loaded.
loop => sets the playback mode to "Loop" when the music player is loaded.
data-randomstart false => starts from the first song of playlist when the music player is loaded.
true => starts from a random song of playlist when the music player is loaded.
data-playlist The place where you have to enter your playlist JSON's file path. (Example => /assets/json/playlist.json)

ID, Class and Variable Information:

Here are the ID, Class and Variable selectors of the music player's elements. You can use them on your own CSS file to customize your music player.

ID/Class/VariableElement TypeDescription
#musicPlayerdivMain body of music player.
#musicPlayerCoverLinkaThe anchor tag of music player's cover image. Opens the original source when clicked.
#musicPlayerCoverImageimgMusic player's cover image that displays the album cover of the current song. If no image is defined, a fallback image will be displayed using its background-image CSS property.
#musicPlayerPaneldivRight column of music player, which contains music player display, progress bar and playback buttons.
#musicPlayerDisplaydivThe bordered box that contains sliding text.
#musicPlayerDisplayTextspanThe sliding text that usually contains music name and artist name.
#musicPlayerProgressdivContains music's progress time, duration time and progress bar.
#musicPlayerProgressbardivThe progress bar itself. Where you can click and drag the handle to set song's current position.
#musicPlayerProgressbar::beforepseudo-elementThe handle of progress bar.
--musicProgressFinishedColordefined in #musicPlayerProgressbarColor variable of progress bar's finished part.
--musicProgressUnfinishedColordefined in #musicPlayerProgressbarColor variable of progress bar's unfinished part.
#musicPlayerStartspanDisplays music's progress time.
#musicPlayerFinishspanDisplays music's duration time.
#musicPlayerButtonsdivContains music player's buttons.
.musicPlayerButtonbuttonGeneral class for music player buttons.
#musicPlayerFinishNextbuttonSets playback mode to "Random" when clicked.
#musicPlayerFinishRandombuttonSets playback mode to "Loop" when clicked.
#musicPlayerFinishLoopbuttonSets playback mode to "Next" when clicked.
#musicPlayerPrevbuttonPlays the previous song when clicked.
#musicPlayerPlaybuttonPlays the current song when clicked
#musicPlayerPausebuttonPauses the current song when clicked.
#musicPlayerNextbuttonPlays the next song when clicked
#musicPlayerMutebuttonSets the volume to 100% when clicked.
#musicPlayerSoftbuttonMutes the audio when clicked.
#musicPlayerLoudbuttonSets the volume to 50% when clicked.

Default CSS Rules

These are the default CSS selectors that are automatically generated and applied by the script:

:where(#musicPlayer, #musicPlayer *) { box-sizing: border-box; margin: 0; padding: 0; } :where(#musicPlayer) { width: 300px; height: 100px; border: 1px solid #000; display: flex; align-items: center; justify-content: center; gap: 0.25rem; padding: 0.25rem; } :where(#musicPlayerCoverLink) { border: 1px solid #000; user-select: none; font-family: Arial, Helvetica, sans-serif; } :where(#musicPlayerCoverImage) { image-rendering: pixelated; background-image: url("data:image/png;base64,BASE64CODE"); background-size: cover; } :where(#musicPlayerCoverImage, #musicPlayerCoverLink) { aspect-ratio: 1 / 1; height: 100%; -webkit-user-drag: none; } :where(#musicPlayerPanel) { width: 100%; height: 100%; display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; } :where(#musicPlayerDisplay) { border: 1px solid #000; overflow: hidden; white-space: nowrap; width: 100%; padding: 0.25rem 0; } :where(#musicPlayerDisplayText) { display: inline-block; animation: musicPlayerTextScroll 4s linear infinite; white-space: nowrap; padding-left: 100%; font-family: Arial, Helvetica, sans-serif; user-select: none; font-size: 1rem; } @keyframes musicPlayerTextScroll { 0% {transform: translateX(0);} 100% {transform: translateX(-100%);} } :where(#musicPlayerProgress) { display: flex; align-items: center; gap: 0.25rem; padding: 0 0.25rem; } :where(#musicPlayerStart, #musicPlayerFinish) { white-space: nowrap; font-family: monospace; user-select: none; font-size: 0.875rem; } :where(#musicPlayerProgressbar) { --musicProgress: 0; --musicProgressFinishedColor: #00f; --musicProgressUnfinishedColor: #0000; padding: 0.125rem; margin: 0.25rem 0.375rem; border: 1px solid #000; background: linear-gradient(90deg, var(--musicProgressFinishedColor) var(--musicProgress), var(--musicProgressUnfinishedColor) var(--musicProgress)); position: relative; cursor: pointer; flex: 1; } :where(#musicPlayerProgressbar)::before { content: ""; display: block; width: 0.75rem; height: 0.75rem; top: 50%; left: var(--musicProgress); transform: translate(-50%, -50%); position: absolute; background: #000; pointer-events: none; } :where(#musicPlayerButtons) { display: flex; gap: 0.25rem; justify-content: center; width: 100%; flex: 1; } :where(.musicPlayerButton) { appearance: none; background-color: #0000; flex: 1; border: 1px solid #000; cursor: pointer; background-size: contain; background-position: center; background-repeat: no-repeat; image-rendering: pixelated; display: none; } :where(#musicPlayerPrev) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerPlay) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerPause) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerNext) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerMute) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerLoud) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerSoft) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerFinishNext) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerFinishRandom) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayerFinishLoop) {background-image: url("data:image/png;base64,BASE64CODE");} :where(#musicPlayer[data-songplaymode="play"] #musicPlayerPause, #musicPlayer[data-songplaymode="pause"] #musicPlayerPlay, #musicPlayer[data-songfinish="next"] #musicPlayerFinishNext, #musicPlayer[data-songfinish="random"] #musicPlayerFinishRandom, #musicPlayer[data-songfinish="loop"] #musicPlayerFinishLoop, #musicPlayer[data-songvoice="mute"] #musicPlayerMute, #musicPlayer[data-songvoice="loud"] #musicPlayerLoud, #musicPlayer[data-songvoice="soft"] #musicPlayerSoft, #musicPlayerPrev, #musicPlayerNext) {display: block;}

HTML Structure

The HTML code that is automatically generated by the script:

<div id="musicPlayer" data-songplaymode="pause" data-songfinish="next" data-songvoice="loud"> <audio id="musicPlayerAudio"></audio> <a href="#" target="_blank" rel="noopener noreferrer" id="musicPlayerCoverLink"> <img id="musicPlayerCoverImage" src="data:image/gif;base64,BASE64CODE"> </a> <div id="musicPlayerPanel"> <div id="musicPlayerDisplay"> <span id="musicPlayerDisplayText">Loading Song...</span> </div> <div id="musicPlayerProgress"> <span id="musicPlayerStart">--:--</span> <div id="musicPlayerProgressbar"></div> <span id="musicPlayerFinish">--:--</span> </div> <div id="musicPlayerButtons"> <button id="musicPlayerFinishNext" class="musicPlayerButton" title="Playback Mode: Next" aria-label="Playback Mode: Next"></button> <button id="musicPlayerFinishRandom" class="musicPlayerButton" title="Playback Mode: Random" aria-label="Playback Mode: Random"></button> <button id="musicPlayerFinishLoop" class="musicPlayerButton" title="Playback Mode: Loop" aria-label="Playback Mode: Loop"></button> <button id="musicPlayerPrev" class="musicPlayerButton" title="Previous Song" aria-label="Previous Song"></button> <button id="musicPlayerPlay" class="musicPlayerButton" title="Play" aria-label="Play"></button> <button id="musicPlayerPause" class="musicPlayerButton" title="Pause" aria-label="Pause"></button> <button id="musicPlayerNext" class="musicPlayerButton" title="Next Song" aria-label="Next Song"></button> <button id="musicPlayerMute" class="musicPlayerButton" title="Volume: Muted" aria-label="Volume: Muted"></button> <button id="musicPlayerSoft" class="musicPlayerButton" title="Volume: 50%" aria-label="Volume: 50%"></button> <button id="musicPlayerLoud" class="musicPlayerButton" title="Volume: 100%" aria-label="Volume: 100%"></button> </div> </div> </div>

Update Log

[v1.2] - 14 August 2026, Friday
  • Progress bar's color variables are moved to its own CSS selector from :root.
[v1.1] - 3 July 2026, Friday
  • Added Soft Volume (50%) option.
  • Changed playback and volume buttons' HTML element type to "button".
  • Added titles to buttons.
[v1.0] - 30 June 2026, Tuesday
  • Widget is ready to use!

Click To Go Back To The Widgets Page