MusicEmbedAPI is a lightweight, modular, client-side audio embed player built with Vanilla JavaScript (ES6).
It provides a modern music-player experience with a UI inspired by the overall experience of services such as Spotify, while remaining a standalone browser component that does not require React, Vue, or another frontend framework.
The library supports:
- Full-featured music player UI
- Compact track card UI
- Dedicated synchronized lyrics UI
- LRC lyric parsing and time synchronization
- Dark and light modes
- Album/cover artwork
- Artist information
- Credits and license information
- Web Share API with clipboard fallback
- Configurable playback controls
- Responsive styling
- Multiple player instances on the same page
Design note: MusicEmbedAPI is inspired by modern music-streaming interfaces, with Spotify being the primary visual and UX reference. It is an independent project and is not affiliated with, endorsed by, or sponsored by Spotify.
Live Demo:
https://jproject-1.github.io/musicembedapi/
Repository:
https://github.com/JPROJECT-1/musicembedapi
MusicEmbedAPI provides three display modes:
| Type | Description |
|---|---|
full |
Complete player with artwork, playback controls, progress bar, lyrics, artist information, credits, and sharing |
track |
Compact music-card style component focused on the cover, title, artist, and play interaction |
lyrics |
Large synchronized lyrics-focused component with cover, title, artist, and active-line highlighting |
The default type is full.
The player uses the browser's native HTMLAudioElement.
Supported audio sources can be any browser-compatible audio URL, such as:
- MP3
- WAV
- Other formats supported by the target browser
MusicEmbedAPI does not host or distribute audio files. You provide the audio URL through the src option.
Lyrics can be supplied as a string in LRC format.
Example:
[00:05.20]First line of the song
[00:10.50]Second line of the song
[00:15.90]Third line of the song
The player parses the timestamps and automatically highlights the current lyric line as the audio plays.
Lyrics can also automatically scroll to keep the active line visible.
The player supports:
darklight
Dark mode is the default.
The compact track and lyrics cards can also use a custom themeColor.
The full player can optionally display an artist section with:
- Artist banner
- Artist name
- Verification indicator
- Artist statistics
- Artist description
You can show production credits and a license label directly inside the full player.
This is useful when distributing music or other media with attribution requirements.
The full player includes sharing support through the browser's Web Share API.
When Web Share is unavailable, MusicEmbedAPI falls back to copying the configured share URL to the clipboard.
You can disable selected controls without modifying the source code:
- Scrubbing
- Duration text
- Skip buttons
- Share button
MusicEmbedAPI is intended for modern browsers that support:
- ES6 JavaScript
HTMLAudioElement- DOM APIs
- CSS
- Optional: Web Share API
- Optional: Clipboard API
No frontend framework is required.
No build step is required for normal browser usage.
MusicEmbedAPI is a browser-side JavaScript library.
Place the JavaScript file in your project and load it with a normal <script> tag.
<script src="./musicembed.js"></script>Then create a container for the player:
<div id="player-root"></div>Finally, initialize the player:
<script>
const player = new MusicEmbed({
container: "#player-root",
type: "full",
src: "./music/song.mp3",
cover: "./images/cover.jpg",
title: "My Song",
author: "My Artist"
});
</script><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MusicEmbedAPI Example</title>
</head>
<body>
<div id="music-player"></div>
<script src="./musicembed.js"></script>
<script>
const player = new MusicEmbed({
type: "full",
container: "#music-player",
width: "360px",
height: "700px",
src: "./music/song.mp3",
cover: "./images/cover.jpg",
title: "My Song",
author: "My Artist",
mode: "dark"
});
</script>
</body>
</html>The constructor accepts an optional configuration object:
const player = new MusicEmbed({
// configuration here
});| Option | Type | Default | Description |
|---|---|---|---|
type |
"full" | "track" | "lyrics" |
"full" |
Selects the player layout |
container |
string |
"body" |
CSS selector for the element where the player is rendered |
width |
string |
"300px" |
Player width |
height |
string |
"400px" |
Player height |
overflow |
string |
"hidden" |
Vertical overflow behavior |
themeColor |
string |
"#2b4015" |
Background color used by compact layouts |
mode |
"dark" | "light" |
"dark" |
Visual theme |
src |
string |
"" |
Audio file URL |
cover |
string |
"" |
Cover image URL |
title |
string |
"" |
Track title |
author |
string |
"" |
Artist or creator name |
license |
string |
"" |
License text shown in the credits section |
const player = new MusicEmbed({
type: "full",
container: "#player",
width: "420px",
height: "760px",
overflow: "auto",
themeColor: "#2b4015",
src: "https://example.com/audio/song.mp3",
cover: "https://example.com/images/cover.jpg",
title: "Night Drive",
author: "JPROJECT-1",
mode: "dark",
license: "CC BY 4.0"
});MusicEmbedAPI allows specific controls to be disabled.
| Option | Type | Default | Effect |
|---|---|---|---|
disableScrubbing |
boolean |
false |
Disables manual seeking with the progress bar |
disableDurationText |
boolean |
false |
Hides current-time and duration text |
disableSkip |
boolean |
false |
Hides the previous/next seek buttons |
disableShare |
boolean |
false |
Hides the share button |
Example:
const player = new MusicEmbed({
container: "#player",
src: "./song.mp3",
title: "Locked Playback",
author: "Artist",
disableScrubbing: true,
disableDurationText: true,
disableSkip: true,
disableShare: true
});The previous/next buttons are not playlist navigation controls.
They seek approximately:
- Previous:
-5 seconds - Next:
+5 seconds
For example:
Current position: 01:30
Previous button: 01:25
Next button: 01:35
Use the lyrics option to provide LRC-formatted lyrics.
const player = new MusicEmbed({
container: "#player",
src: "./song.mp3",
cover: "./cover.jpg",
title: "Example Song",
author: "Example Artist",
lyrics: `
[00:02.00]Welcome to the song
[00:06.50]This line appears next
[00:11.20]Now the third line is active
`
});Each lyric line should contain a timestamp:
[mm:ss.xx]Lyric text
Example:
[00:12.40]Hello world
[00:18.25]This is another line
[01:02.10]The song continues
The parser accepts timestamps with one to three decimal places.
Blank or missing lyric text is displayed as:
♪
Lyrics are sorted automatically by timestamp.
Automatic scrolling is enabled by default.
autoScrollLyrics: trueDisable it with:
autoScrollLyrics: falseThe lyrics layout supports a custom font size.
Default:
lyricFontSize: "auto"When set to "auto", the default size used by the lyrics card is 32px.
You may also provide a number:
lyricFontSize: 28This becomes:
28pxOr use a CSS size string:
lyricFontSize: "2rem"Example:
const player = new MusicEmbed({
type: "lyrics",
container: "#lyrics-player",
src: "./song.mp3",
cover: "./cover.jpg",
title: "Ocean",
author: "Artist",
lyrics: `
[00:03.00]A lyric line
[00:07.00]Another lyric line
[00:11.50]The song continues
`,
autoScrollLyrics: true,
lyricFontSize: "30px"
});Artist information is disabled by default.
Enable it with:
artistInformation: {
active: true,
banner: "./artist-banner.jpg",
name: "Artist Name",
verified: true,
stats: "12.4M monthly listeners",
description: "Artist biography or additional information."
}| Option | Type | Default | Description |
|---|---|---|---|
active |
boolean |
false |
Enables the artist information card |
banner |
string |
"" |
Artist banner image URL |
name |
string |
"" |
Artist name |
verified |
boolean |
false |
Displays the verification icon when an artist name is available |
stats |
string |
"" |
Optional artist statistics |
description |
string |
"" |
Artist description |
Credits are also optional.
credits: {
active: true,
list: [
{
role: "Artist",
name: "Example Artist"
},
{
role: "Composer",
name: "Example Composer"
},
{
role: "Producer",
name: "Example Producer"
}
]
}Each credit entry contains:
| Property | Type | Description |
|---|---|---|
role |
string |
Credit role |
name |
string |
Person or organization name |
Example:
const player = new MusicEmbed({
container: "#player",
src: "./song.mp3",
title: "Example Song",
author: "Example Artist",
credits: {
active: true,
list: [
{ role: "Artist", name: "Example Artist" },
{ role: "Composer", name: "Example Composer" },
{ role: "Producer", name: "Example Producer" }
]
},
license: "CC BY 4.0"
});The license text is displayed together with the credits section when provided.
Configure the share information with:
share: {
title: "My Song",
description: "Check out this audio track",
url: "https://example.com/song"
}Options:
| Option | Type | Default |
|---|---|---|
title |
string |
Track title or "Shared Audio" |
description |
string |
"Check out this audio track" |
url |
string |
window.location.href |
Example:
const player = new MusicEmbed({
container: "#player",
src: "./song.mp3",
title: "My Song",
author: "My Artist",
share: {
title: "Listen to My Song",
description: "A track from my project",
url: "https://example.com/music/my-song"
}
});When navigator.share is available, the player uses the Web Share API.
When it is not available, the configured URL is copied to the clipboard and the user receives a browser alert confirming that the link was copied.
const player = new MusicEmbed({
type: "full",
container: "#player",
src: "./song.mp3",
cover: "./cover.jpg",
title: "Song Title",
author: "Artist Name",
lyrics: "[00:05.00]Hello world"
});The full layout can include:
- Now Playing header
- Cover artwork
- Blurred cover background
- Song title
- Artist name
- Progress bar
- Current time
- Duration
- Play/pause
- ±5 second seek buttons
- Share button
- Synchronized lyrics
- Artist information
- Credits
- License
- MusicEmbedAPI footer
const player = new MusicEmbed({
type: "track",
container: "#track",
width: "320px",
height: "400px",
themeColor: "#2b4015",
cover: "./cover.jpg",
title: "Song Title",
author: "Artist Name",
src: "./song.mp3"
});The track card is intentionally compact and focuses on:
- Cover art
- Song title
- Artist
- Play/pause interaction
Clicking the card toggles playback.
const player = new MusicEmbed({
type: "lyrics",
container: "#lyrics",
width: "360px",
height: "520px",
themeColor: "#2b4015",
cover: "./cover.jpg",
title: "Song Title",
author: "Artist Name",
lyrics: `
[00:02.00]First line
[00:05.00]Second line
[00:09.00]Third line
`
});The lyrics card displays:
- Mini cover
- Track title
- Artist name
- Large lyrics
- Active lyric highlighting
- Optional automatic scrolling
Clicking the card toggles playback.
You can create multiple MusicEmbed instances on the same page.
Each instance receives its own generated internal ID.
Example:
<div id="player-one"></div>
<div id="player-two"></div>const playerOne = new MusicEmbed({
container: "#player-one",
src: "./song-one.mp3",
cover: "./cover-one.jpg",
title: "Song One",
author: "Artist One"
});
const playerTwo = new MusicEmbed({
container: "#player-two",
type: "track",
src: "./song-two.mp3",
cover: "./cover-two.jpg",
title: "Song Two",
author: "Artist Two",
themeColor: "#243b53"
});Each player renders into its configured container.
Note: the keyboard shortcut described below is attached globally to the document. Pressing
Spacecan therefore affect the player instance handling that shortcut, so keyboard behavior should be considered when using multiple players.
Press:
Space
to toggle play/pause.
The shortcut is ignored when the user is typing inside an:
<input><textarea>
MusicEmbedAPI currently exposes the following class methods that are useful when working with the player internally or extending the library.
Parses an LRC lyric string.
const lyrics = player.parseLrc(`
[00:05.00]Hello
[00:10.50]World
`);
console.log(lyrics);Returns an array similar to:
[
{ time: 5, text: "Hello" },
{ time: 10.5, text: "World" }
]The returned list is sorted by timestamp.
Converts seconds into minutes:seconds.
player.formatTime(185);Result:
3:05
Invalid or infinite values return:
0:00
The class also contains rendering/setup methods such as:
init()
injectCSS()
renderFull()
renderTrack()
renderLyrics()
cacheDOM()
attachEvents()These methods are primarily used by the library itself.
Changing them is intended for developers who want to customize or fork MusicEmbedAPI.
A player can be initialized without an audio source.
const player = new MusicEmbed({
container: "#player",
title: "Loading...",
author: "Artist"
});When src is empty, the UI can still be rendered, but playback controls are disabled because there is no media source.
Missing cover, title, and artist values can also display built-in loading/skeleton placeholders.
MusicEmbedAPI injects its base CSS into the document automatically.
The source also imports:
- Inter from Google Fonts
- Font Awesome 6.4.0 from cdnjs
Therefore, the final appearance can depend on network access to those external resources.
The main UI is generated dynamically, so you do not need to manually copy the component CSS into your HTML.
A simple project can look like this:
my-project/
├── index.html
├── musicembed.js
├── music/
│ └── song.mp3
└── images/
└── cover.jpg
Example index.html:
<div id="player"></div>
<script src="./musicembed.js"></script>
<script>
new MusicEmbed({
container: "#player",
type: "full",
width: "360px",
height: "720px",
src: "./music/song.mp3",
cover: "./images/cover.jpg",
title: "My Song",
author: "My Artist"
});
</script>MusicEmbedAPI is provided as a player component. You are responsible for the content you load into it.
When using MusicEmbedAPI, follow these rules:
You must have appropriate permission, ownership, or a valid license for:
- Audio files
- Album/cover artwork
- Artist images
- Lyrics
- Other third-party media
Do not use MusicEmbedAPI as a way to distribute copyrighted music without authorization.
When media requires attribution, include the appropriate information in the player or your project.
For example:
license: "CC BY 4.0"and:
credits: {
active: true,
list: [
{ role: "Artist", name: "Creator Name" },
{ role: "Source", name: "Original Creator" }
]
}MusicEmbedAPI may be inspired by Spotify's general design language, but your project should not falsely claim to be Spotify or an official Spotify product.
Do not use Spotify trademarks, branding, logos, or copyrighted assets as though they belong to MusicEmbedAPI.
When loading audio, images, or lyrics from external servers, make sure your usage complies with the provider's:
- Terms of service
- Hotlinking policy
- Copyright rules
- API rules
- Bandwidth restrictions
For production websites, HTTPS URLs are recommended.
Be careful when accepting URLs from untrusted users. Validate and sanitize any user-provided data before inserting it into your own application.
Avoid autoplaying audio unexpectedly.
Provide clear controls and make it obvious when media is playing.
The library is a UI/player component. It does not grant rights to redistribute copyrighted music, lyrics, artwork, or other media.
MusicEmbedAPI injects configuration values into generated HTML.
For projects that accept configuration from untrusted users, do not pass raw untrusted HTML or arbitrary user input directly into fields such as:
title
author
lyrics
credits
licenseTreat these values as application data and validate or sanitize them in the surrounding application when necessary.
Similarly, only load media URLs that your application trusts.
MusicEmbedAPI relies on the browser's normal media loading rules.
If your audio file is hosted on another domain, the browser may require that server to allow the request appropriately.
For best results, host your audio and related assets on infrastructure configured for your website, or use a media host that explicitly permits your intended usage.
const player = new MusicEmbed({
type: "full",
container: "#music-player",
width: "380px",
height: "760px",
overflow: "auto",
themeColor: "#2b4015",
src: "https://example.com/audio/song.mp3",
cover: "https://example.com/images/song-cover.jpg",
title: "Example Song",
author: "Example Artist",
mode: "dark",
disableScrubbing: false,
disableDurationText: false,
disableSkip: false,
disableShare: false,
lyrics: `
[00:03.00]Welcome to the song
[00:07.50]This is the second line
[00:12.30]The music continues
`,
autoScrollLyrics: true,
lyricFontSize: "auto",
artistInformation: {
active: true,
banner: "https://example.com/images/artist-banner.jpg",
name: "Example Artist",
verified: true,
stats: "1.2M listeners",
description: "An example artist description."
},
credits: {
active: true,
list: [
{ role: "Artist", name: "Example Artist" },
{ role: "Composer", name: "Example Composer" },
{ role: "Producer", name: "Example Producer" }
]
},
license: "CC BY 4.0",
share: {
title: "Example Song",
description: "Listen to Example Song",
url: "https://example.com/music/example-song"
}
});MusicEmbed
│
├── General
│ ├── type
│ ├── container
│ ├── width
│ ├── height
│ ├── overflow
│ └── themeColor
│
├── Track
│ ├── src
│ ├── cover
│ ├── title
│ ├── author
│ └── mode
│
├── Controls
│ ├── disableScrubbing
│ ├── disableDurationText
│ ├── disableSkip
│ └── disableShare
│
├── Lyrics
│ ├── lyrics
│ ├── autoScrollLyrics
│ └── lyricFontSize
│
├── Artist
│ └── artistInformation
│ ├── active
│ ├── banner
│ ├── name
│ ├── verified
│ ├── stats
│ └── description
│
├── Credits
│ └── credits
│ ├── active
│ └── list
│
├── License
│ └── license
│
└── Sharing
└── share
├── title
├── description
└── url
MusicEmbedAPI is not:
- A music streaming service
- A music database
- A Spotify API wrapper
- A music hosting platform
- A copyright/license provider
- A backend audio-processing service
- A playlist or recommendation service
It is a client-side JavaScript player component.
You provide the media and metadata; MusicEmbedAPI provides the player interface and playback experience.
MusicEmbedAPI takes inspiration from modern streaming-player patterns, especially Spotify's general approach to:
- Music-focused layouts
- Album artwork presentation
- Now-playing interfaces
- Lyrics presentation
- Artist information
- Minimal playback controls
- Dark-themed music UI
However:
MusicEmbedAPI is an independent project and is not affiliated with Spotify.
Spotify and related trademarks belong to their respective owners.
Do not present MusicEmbedAPI as an official Spotify product or official Spotify integration.
Contributions are welcome.
You can contribute by:
- Reporting bugs
- Suggesting improvements
- Improving documentation
- Improving accessibility
- Adding tests
- Improving browser compatibility
- Improving the player UI
- Adding new optional features
Before submitting a major change, it is recommended to explain the purpose of the change and how it affects the current API.
Copyright (c) 2026 JPROJECT-1
MusicEmbedAPI is licensed under the MIT License.
The MIT License permits use, modification, distribution, and private or commercial use, provided that the copyright notice and license notice are retained.
MIT License
Copyright (c) 2026 JPROJECT-1
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
MusicEmbedAPI
Created by JPROJECT-1
Inspired by modern music-player experiences, with Spotify as a primary reference.
Live Demo:
https://jproject-1.github.io/musicembedapi/
Repository:
https://github.com/JPROJECT-1/musicembedapi
MusicEmbedAPI is designed to make it easy to embed a polished music player into ordinary web pages using only JavaScript.
You can start with a simple configuration:
new MusicEmbed({
container: "#player",
src: "./song.mp3",
cover: "./cover.jpg",
title: "My Song",
author: "My Artist"
});Then progressively add synchronized lyrics, artist information, credits, sharing, themes, and control options as your project grows.