Loading

WIDGETS

Music Player Widget
Click To Go Back To The Widgets Page

Preview


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.

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 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/VariableElement TypeDescription
--musicProgressFinishedColordefined in :rootColor variable of progress bar's finished part.
--musicProgressUnfinishedColordefined in :rootColor variable of progress bar's unfinished part.
#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 shows album cover of a specific song.
#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.
#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 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