Jun
22

Build a Music Player with Album Art

06/22/2025 12:00 AM by Admin in Html


music player art

 

Creating a custom music player with album art is a fantastic way to enhance user experience on a website, offering both functionality and visual appeal. With HTML, CSS, and JavaScript, you can build a feature-rich music player that supports playback controls, track navigation, progress tracking, and dynamic album art display. This in-depth guide will walk you through the process of building a modern music player from scratch, including best practices, free AI tools for generating album art, and a complete code example. Whether you're a beginner or an experienced developer, this article will provide you with the tools and knowledge to create an engaging audio experience.

Why Build a Custom Music Player?

A custom music player offers several advantages over default browser audio controls:

  • Branding: Tailor the player’s design to match your website’s aesthetic.
  • Enhanced Functionality: Add features like playlists, progress bars, and album art.
  • User Engagement: Visual elements like album art make the player more interactive and appealing.
  • Cross-Platform Compatibility: Ensure consistent behavior across browsers with JavaScript.

By integrating album art, you create a visually immersive experience that complements the audio content, making it ideal for music websites, portfolios, or personal projects.

Understanding the HTML5 Audio Element

The foundation of our music player is the HTML5 <audio> element, which provides native support for audio playback in modern browsers. It supports formats like MP3, WAV, and OGG, and includes built-in methods for controlling playback via JavaScript.

Here’s a basic <audio> setup:

<audio id="audioPlayer" src="song.mp3"></audio>

However, to create a custom player, we’ll hide the default controls and build a custom interface with buttons, a progress bar, and album art.

Planning the Music Player Features

Our music player will include the following features:

  • Playback Controls: Play/pause, next/previous track.
  • Progress Bar: Display and control the song’s progress.
  • Volume Control: Adjust audio volume.
  • Playlist: Support multiple tracks with titles and album art.
  • Album Art Display: Dynamically update album art for each track.
  • Responsive Design: Ensure the player looks great on desktop and mobile.

Setting Up the Project Structure

To keep things organized, create the following files:

  • index.html: The main HTML file.
  • styles.css: For styling the player.
  • script.js: For JavaScript logic.
  • assets/: A folder for audio files and album art images.

You’ll also need sample audio files (e.g., song1.mp3song2.mp3) and album art images (e.g., album1.jpgalbum2.jpg). Ensure all files are royalty-free or licensed for use.

Building the HTML Structure

The HTML will include the player interface, album art, and playlist. Here’s a sample:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Music Player with Album Art</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="music-player">
    <img id="albumArt" src="assets/default.jpg" alt="Album Art">
    <h2 id="trackTitle">Track Title</h2>
    <audio id="audioPlayer"></audio>
    <div class="progress-container">
      <span id="currentTime">0:00</span>
      <input type="range" id="progressBar" value="0" max="100">
      <span id="duration">0:00</span>
    </div>
    <div class="controls">
      <button id="prevBtn">&#9664;</button>
      <button id="playPauseBtn">&#9654;</button>
      <button id="nextBtn">&#9654;</button>
    </div>
    <div class="volume-control">
      <input type="range" id="volumeSlider" min="0" max="1" step="0.1" value="1">
    </div>
    <ul id="playlist"></ul>
  </div>
  <script src="script.js"></script>
</body>
</html>

Explanation:

  • <img id="albumArt">: Displays the album art.
  • <h2 id="trackTitle">: Shows the current track’s title.
  • <audio id="audioPlayer">: The audio element (source set via JavaScript).
  • <input type="range" id="progressBar">: A range input for the progress bar.
  • <input type="range" id="volumeSlider">: A range input for volume control.
  • <ul id="playlist">: A list for displaying playlist tracks.

Styling with CSS

The CSS will make the player modern and responsive. Save this in styles.css:

body {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: #f0f0f0;
  margin: 0;
}

.music-player {
  background: #fff;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
  width: 100%;
  max-width: 400px;
  text-align: center;
}

#albumArt {
  width: 100%;
  max-width: 300px;
  border-radius: 10px;
  margin-bottom: 10px;
}

#trackTitle {
  font-size: 1.2em;
  margin: 10px 0;
}

.progress-container {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0;
}

#progressBar {
  flex: 1;
  cursor: pointer;
}

.controls {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin: 10px 0;
}

.controls button {
  background: #4CAF50;
  color: white;
  border: none;
  padding: 10px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 1.2em;
}

.controls button:hover {
  background: #45a049;
}

.volume-control {
  margin: 10px 0;
}

#volumeSlider {
  width: 100%;
}

#playlist {
  list-style: none;
  padding: 0;
  margin: 10px 0;
}

#playlist li {
  padding: 10px;
  cursor: pointer;
  border-radius: 5px;
}

#playlist li:hover {
  background: #f0f0f0;
}

#playlist li.active {
  background: #4CAF50;
  color: white;
}

@media (max-width: 400px) {
  .music-player {
    padding: 15px;
  }
  #albumArt {
    max-width: 250px;
  }
}

This CSS creates a clean, modern design with a responsive layout, hover effects, and a visually appealing album art display.

Adding JavaScript Functionality

The JavaScript will handle playback, track navigation, progress updates, and album art switching. Save this in script.js:

const audioPlayer = document.getElementById('audioPlayer');
const playPauseBtn = document.getElementById('playPauseBtn');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const progressBar = document.getElementById('progressBar');
const currentTime = document.getElementById('currentTime');
const duration = document.getElementById('duration');
const volumeSlider = document.getElementById('volumeSlider');
const trackTitle = document.getElementById('trackTitle');
const albumArt = document.getElementById('albumArt');
const playlist = document.getElementById('playlist');

const tracks = [
  { title: 'Song 1', src: 'assets/song1.mp3', art: 'assets/album1.jpg' },
  { title: 'Song 2', src: 'assets/song2.mp3', art: 'assets/album2.jpg' },
  { title: 'Song 3', src: 'assets/song3.mp3', art: 'assets/album3.jpg' },
];

let currentTrackIndex = 0;
let isPlaying = false;

function loadTrack(index) {
  const track = tracks[index];
  audioPlayer.src = track.src;
  trackTitle.textContent = track.title;
  albumArt.src = track.art;
  updatePlaylist();
  audioPlayer.load();
}

function updatePlaylist() {
  playlist.innerHTML = '';
  tracks.forEach((track, index) => {
    const li = document.createElement('li');
    li.textContent = track.title;
    li.classList.toggle('active', index === currentTrackIndex);
    li.addEventListener('click', () => {
      currentTrackIndex = index;
      loadTrack(index);
      playTrack();
    });
    playlist.appendChild(li);
  });
}

function playTrack() {
  audioPlayer.play();
  isPlaying = true;
  playPauseBtn.textContent = '❚❚';
}

function pauseTrack() {
  audioPlayer.pause();
  isPlaying = false;
  playPauseBtn.textContent = 'play';
}

function togglePlayPause() {
  if (isPlaying) {
    pauseTrack();
  } else {
    playTrack();
  }
}

function formatTime(seconds) {
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
}

playPauseBtn.addEventListener('click', togglePlayPause);

prevBtn.addEventListener('click', () => {
  currentTrackIndex = (currentTrackIndex - 1 + tracks.length) % tracks.length;
  loadTrack(currentTrackIndex);
  playTrack();
});

nextBtn.addEventListener('click', () => {
  currentTrackIndex = (currentTrackIndex + 1) % tracks.length;
  loadTrack(currentTrackIndex);
  playTrack();
});

audioPlayer.addEventListener('timeupdate', () => {
  const { currentTime, duration: durationValue } = audioPlayer;
  progressBar.value = (currentTime / durationValue) * 100 || 0;
  currentTime.textContent = formatTime(currentTime);
  duration.textContent = formatTime(durationValue) || '0:00';
});

progressBar.addEventListener('input', () => {
  audioPlayer.currentTime = (progressBar.value / 100) * audioPlayer.duration;
});

volumeSlider.addEventListener('input', () => {
  audioPlayer.volume = volumeSlider.value;
});

audioPlayer.addEventListener('ended', () => {
  nextBtn.click();
});

loadTrack(currentTrackIndex);
updatePlaylist();

Explanation:

  • Track Array: Defines tracks with titles, audio sources, and album art.
  • Load Track: Updates the audio source, title, and album art for the current track.
  • Playback Controls: Handles play/pause, next/previous track, and playlist navigation.
  • Progress Bar: Updates in real-time and allows seeking.
  • Volume Slider: Adjusts the audio volume.
  • Playlist: Dynamically renders clickable track items.

Generating Album Art with Free AI Tools

Creating unique album art can be time-consuming, but free AI tools make it easy:

  1. Canva: Offers AI-powered design tools to create album art with free templates. Available at canva.com.
  2. Artbreeder: Generates AI-assisted images for album covers. Free tier at artbreeder.com.
  3. Runway: Provides AI tools for creating visuals, including album art. Free plan at runwayml.com.

These tools allow you to create professional-looking album art without advanced design experience.

Best Practices for Accessibility

To ensure your music player is accessible:

  • Add ARIA labels to buttons (e.g., aria-label="Play or Pause").
  • Ensure keyboard navigation with tabindex="0".
  • Provide text alternatives for album art with meaningful alt attributes.
  • Use high-contrast colors for readability.
  • Test with screen readers like NVDA or VoiceOver.

Handling Errors and Edge Cases

  • Missing Files: Check audio and image paths are correct.
  • Browser Compatibility: Test MP3 support across browsers or provide OGG/WAV fallbacks.
  • Invalid Duration: Handle cases where audioPlayer.duration is NaN until metadata loads.
  • Mobile Support: Ensure touch events work for progress and volume sliders.

Complete Code Example

Below is the complete code, combining HTML, CSS, and JavaScript.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Music Player with Album Art</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="music-player">
    <img id="albumArt" src="assets/default.jpg" alt="Album Art">
    <h2 id="trackTitle">Track Title</h2>
    <audio id="audioPlayer"></audio>
    <div class="progress-container">
      <span id="currentTime">0:00</span>
      <input type="range" id="progressBar" value="0" max="100">
      <span id="duration">0:00</span>
    </div>
    <div class="controls">
      <button id="prevBtn">&#9664;</button>
      <button id="playPauseBtn">&#9654;</button>
      <button id="nextBtn">&#9654;</button>
    </div>
    <div class="volume-control">
      <input type="range" id="volumeSlider" min="0" max="1" step="0.1" value="1">
    </div>
    <ul id="playlist"></ul>
  </div>
  <script src="script.js"></script>
</body>
</html>

styles.css

body {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background: #f0f0f0;
  margin: 0;
}

.music-player {
  background: #fff;
  padding: 20px;
  border-radius: 10px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
  width: 100%;
  max-width: 400px;
  text-align: center;
}

#albumArt {
  width: 100%;
  max-width: 300px;
  border-radius: 10px;
  margin-bottom: 10px;
}

#trackTitle {
  font-size: 1.2em;
  margin: 10px 0;
}

.progress-container {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0;
}

#progressBar {
  flex: 1;
  cursor: pointer;
}

.controls {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin: 10px 0;
}

.controls button {
  background: #4CAF50;
  color: white;
  border: none;
  padding: 10px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 1.2em;
}

.controls button:hover {
  background: #45a049;
}

.volume-control {
  margin: 10px 0;
}

#volumeSlider {
  width: 100%;
}

#playlist {
  list-style: none;
  padding: 0;
  margin: 10px 0;
}

#playlist li {
  padding: 10px;
  cursor: pointer;
  border-radius: 5px;
}

#playlist li:hover {
  background: #f0f0f0;
}

#playlist li.active {
  background: #4CAF50;
  color: white;
}

@media (max-width: 400px) {
  .music-player {
  margin: 15px;
}

  #albumArt {
    max-width: 250px;
}
}

script.js

const audioPlayer = document.getElementById('audioPlayer');
const playPauseBtn = document.getElementById('playPauseBtn');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const progressBar = document.getElementById('progressBar');
const currentTime = document.getElementById('currentTime');
const duration = document.getElementById('duration');
const volumeSlider = document.getElementById('volumeSlider');
const trackTitle = document.getElementById('trackTitle');
const albumArt = document.getElementById('albumArt');
const playlist = document.getElementById('playlist');

const tracks = [
  { title: 'Song 1', src: 'assets/song1.mp3', art: 'assets/album1.jpg' },
  { title: 'Song 2', src: 'assets/song2.mp3', art: 'assets/album2.jpg' },
  { title: 'Song 3', src: 'assets/song3.mp3', art: 'assets/album3.jpg' },
];

let currentTrackIndex = 0;
let isPlaying = false;

function loadTrack(index) {
  const track = tracks[index];
  audioPlayer.src = track.src;
  trackTitle.textContent = track.title;
  albumArt.src = track.art;
  updatePlaylist();
  audioPlayer.load();
}

function updatePlaylist() {
  playlist.innerHTML = '';
  tracks.forEach((track, index) => {
    tracks.forEach((track, index) => {
    const li = document.createElement('li');
    li.textContent = track.title;
    li.classList.toggle('active', index === currentTrackIndex);
    li.addEventListener('click', () => {
      currentTrackIndex = index;
      loadTrack(index);
      playTrack();
    });
    playlist.appendChild(li);
  });
});
}

function playTrack() {
  audioPlayer.play();
  isPlaying = true;
  playPauseBtn.textContent = '❚❚';
}

function pauseTrack() {
  audioPlayer.pause();
  isPlaying = false;
  playPauseBtn.textContent = '▶';
}

function togglePlayPause() {
  if (isPlaying) {
    pauseTrack();
  } else {
    playTrack();
  }
}

function formatTime(seconds) {
  const minutes = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${minutes}:${secs < 10 ? '0' : ''}${secs}`;
}

playPauseBtn.addEventListener('click', togglePlayPause);

prevBtn.addEventListener('click', () => {
  currentTrackIndex = (currentTrackIndex - 1 + tracks.length) % tracks.length;
  loadTrack(currentTrackIndex);
  playTrack();
});

nextBtn.addEventListener('click', () => {
  currentTrackIndex = (currentTrackIndex + tracks.length + 1) % tracks.length;
  loadTrack(currentTrackIndex);
  playTrack();
});

audioPlayer.addEventListener('timeupdate', () => {
  const { currentTime, durationValue } = audioPlayer;
  progressBar.value = (currentTime / durationValue) * duration100 ||  currentTime.textContent = formatTime(currentTime);
  duration.textContent = formatTime(durationValue) || duration'0:00';
});

progressBar.addEventListener('input', () => {
  audioPlayer.currentTime = (progressBar.value / duration100) * audioPlayer.duration;
});

volumeSlider.addEventListener('input', () => {
  audioPlayer.volume = volumeSlider.value;
});

audioPlayer.addEventListener('ended', () => {
  nextBtn.click();
});

loadTrack(currentTrackIndex);
updatePlaylistTrack(currentTrackIndex);

Conclusion

Building a music player with album art is a powerful way to combine functionality with visual appeal. By leveraging HTML5 audio, CSS for styling, and JavaScript for interactivity, you can create a modern, responsive player that enhances user engagement. Free AI tools like Canva, Artbreeder, and Runway simplify album art creation, while best practices ensure accessibility and compatibility. Use the complete code provided to kickstart your project and customize it to fit your needs. Start building your music player today to deliver an immersive audio experience for your audience!


leave a comment
Please post your comments here.