WIDGETS
Music Player Widget
Click To Go Back To The Widgets PagePreview
A demo with 3 example chiptune songs.
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.
| Attribute | Conditions |
|---|---|
| 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/Variable | Element Type | Description |
|---|---|---|
| #musicPlayer | div | Main body of music player. |
| #musicPlayerCoverLink | a | The anchor tag of music player's cover image. Opens the original source when clicked. |
| #musicPlayerCoverImage | img | Music 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. |
| #musicPlayerPanel | div | Right column of music player, which contains music player display, progress bar and playback buttons. |
| #musicPlayerDisplay | div | The bordered box that contains sliding text. |
| #musicPlayerDisplayText | span | The sliding text that usually contains music name and artist name. |
| #musicPlayerProgress | div | Contains music's progress time, duration time and progress bar. |
| #musicPlayerProgressbar | div | The progress bar itself. Where you can click and drag the handle to set song's current position. |
| #musicPlayerProgressbar::before | pseudo-element | The handle of progress bar. |
| --musicProgressFinishedColor | defined in #musicPlayerProgressbar | Color variable of progress bar's finished part. |
| --musicProgressUnfinishedColor | defined in #musicPlayerProgressbar | Color variable of progress bar's unfinished part. |
| #musicPlayerStart | span | Displays music's progress time. |
| #musicPlayerFinish | span | Displays music's duration time. |
| #musicPlayerButtons | div | Contains music player's buttons. |
| .musicPlayerButton | button | General class for music player buttons. |
| #musicPlayerFinishNext | button | Sets playback mode to "Random" when clicked. |
| #musicPlayerFinishRandom | button | Sets playback mode to "Loop" when clicked. |
| #musicPlayerFinishLoop | button | Sets playback mode to "Next" when clicked. |
| #musicPlayerPrev | button | Plays the previous song when clicked. |
| #musicPlayerPlay | button | Plays the current song when clicked |
| #musicPlayerPause | button | Pauses the current song when clicked. |
| #musicPlayerNext | button | Plays the next song when clicked |
| #musicPlayerMute | button | Sets the volume to 100% when clicked. |
| #musicPlayerSoft | button | Mutes the audio when clicked. |
| #musicPlayerLoud | button | Sets 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