A demo with 3 example chiptune songs.
WIDGETS
Music Player Widget
Click To Go Back To The Widgets PagePreview
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.
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:
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 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 Informations:
Here are the ID, Class and Variable definitions of music player's elements. You can use them on your own CSS file to customize your music player.
| ID/Class/Variable | Element Type | Description |
|---|---|---|
| --musicProgressFinishedColor | defined in :root | Color variable of progress bar's finished part. |
| --musicProgressUnfinishedColor | defined in :root | Color variable of progress bar's unfinished part. |
| #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 shows album cover of a specific song. |
| #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. |
| #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 Definements
Here are the default CSS properties of elements that already defined in your widget file. (You don't have to define them in your own CSS file for second time.)
:root {
--musicProgress: 0;
--musicProgressFinishedColor: #00f;
--musicProgressUnfinishedColor: #0000;
}
: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("https://404city.neocities.org/widget/musicPlayerImages/fallback.png");
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) {
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("https://404city.neocities.org/widget/musicPlayerImages/prev.png");}
:where(#musicPlayerPlay) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/play.png");}
:where(#musicPlayerPause) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/pause.png");}
:where(#musicPlayerNext) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/next.png");}
:where(#musicPlayerMute) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/mute.png");}
:where(#musicPlayerLoud) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/loud.png");}
:where(#musicPlayerSoft) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/soft.png");}
:where(#musicPlayerFinishNext) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/finishNext.png");}
:where(#musicPlayerFinishRandom) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/finishRandom.png");}
:where(#musicPlayerFinishLoop) {background-image: url("https://404city.neocities.org/widget/musicPlayerImages/finishLoop.png");}
: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;}
Update Log
3 July 2026, Friday
- Added Soft Volume (50%) option.
- Changed playback and volume buttons' HTML element type to "button".
- Added titles to buttons.
30 June 2026, Tuesday
- Widget is ready to use!
Click To Go Back To The Widgets Page