DEV Community

Cover image for Low-Level Design of a Music Player Application
Abhishek Jaiswal
Abhishek Jaiswal

Posted on

Low-Level Design of a Music Player Application

Designing a music player application requires careful planning and structuring of components to ensure a seamless and efficient user experience.


Key Requirements of the Music Player

  1. Playback Functionality:

    • Play, pause, stop, and resume songs.
    • Ability to play songs in different formats (e.g., MP3, WAV, AAC).
  2. Playlist Management:

    • Create, update, and delete playlists.
    • Add and remove songs from playlists.
  3. Search:

    • Search songs by title, artist, or album.
  4. Media Controls:

    • Shuffle and repeat modes.
    • Adjust volume.
  5. Storage:

    • Store metadata about songs (e.g., title, artist, album, duration).
    • Read from local storage or integrate with online music services.

System Design Overview

The music player application can be broken down into the following components:

  1. Song: Represents a single music track.
  2. Playlist: Manages collections of songs.
  3. MusicPlayer: Core functionality for playback and media controls.
  4. SearchService: Enables searching of songs by metadata.
  5. StorageService: Handles the retrieval of songs from storage.

Let’s look at the low-level design and implementation of each component.


1. Song Class

The Song class represents a single music track with its metadata.

public class Song {
    private String id;
    private String title;
    private String artist;
    private String album;
    private double duration; // in seconds

    public Song(String id, String title, String artist, String album, double duration) {
        this.id = id;
        this.title = title;
        this.artist = artist;
        this.album = album;
        this.duration = duration;
    }

    // Getters and setters
    public String getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public String getArtist() {
        return artist;
    }

    public String getAlbum() {
        return album;
    }

    public double getDuration() {
        return duration;
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Playlist Class

The Playlist class manages a collection of songs. It allows adding, removing, and fetching songs.

import java.util.ArrayList;
import java.util.List;

public class Playlist {
    private String name;
    private List<Song> songs;

    public Playlist(String name) {
        this.name = name;
        this.songs = new ArrayList<>();
    }

    public void addSong(Song song) {
        songs.add(song);
    }

    public void removeSong(Song song) {
        songs.remove(song);
    }

    public List<Song> getSongs() {
        return songs;
    }

    public String getName() {
        return name;
    }
}
Enter fullscreen mode Exit fullscreen mode

3. MusicPlayer Class

The MusicPlayer class handles playback functionalities like play, pause, stop, and volume control.

public class MusicPlayer {
    private Song currentSong;
    private boolean isPlaying;

    public void play(Song song) {
        this.currentSong = song;
        this.isPlaying = true;
        System.out.println("Playing: " + song.getTitle() + " by " + song.getArtist());
    }

    public void pause() {
        if (isPlaying) {
            isPlaying = false;
            System.out.println("Paused: " + currentSong.getTitle());
        } else {
            System.out.println("No song is currently playing.");
        }
    }

    public void stop() {
        if (currentSong != null) {
            System.out.println("Stopped: " + currentSong.getTitle());
            currentSong = null;
            isPlaying = false;
        } else {
            System.out.println("No song is currently playing.");
        }
    }

    public void resume() {
        if (currentSong != null && !isPlaying) {
            isPlaying = true;
            System.out.println("Resumed: " + currentSong.getTitle());
        } else {
            System.out.println("No song to resume.");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

4. SearchService Class

The SearchService class allows users to search for songs by title, artist, or album.

import java.util.ArrayList;
import java.util.List;

public class SearchService {
    private List<Song> songs;

    public SearchService(List<Song> songs) {
        this.songs = songs;
    }

    public List<Song> searchByTitle(String title) {
        List<Song> results = new ArrayList<>();
        for (Song song : songs) {
            if (song.getTitle().equalsIgnoreCase(title)) {
                results.add(song);
            }
        }
        return results;
    }

    public List<Song> searchByArtist(String artist) {
        List<Song> results = new ArrayList<>();
        for (Song song : songs) {
            if (song.getArtist().equalsIgnoreCase(artist)) {
                results.add(song);
            }
        }
        return results;
    }

    public List<Song> searchByAlbum(String album) {
        List<Song> results = new ArrayList<>();
        for (Song song : songs) {
            if (song.getAlbum().equalsIgnoreCase(album)) {
                results.add(song);
            }
        }
        return results;
    }
}
Enter fullscreen mode Exit fullscreen mode

5. StorageService Class

The StorageService class simulates reading songs from local storage.

import java.util.ArrayList;
import java.util.List;

public class StorageService {
    public static List<Song> loadSongs() {
        List<Song> songs = new ArrayList<>();
        songs.add(new Song("1", "Shape of You", "Ed Sheeran", "Divide", 240));
        songs.add(new Song("2", "Blinding Lights", "The Weeknd", "After Hours", 200));
        songs.add(new Song("3", "Levitating", "Dua Lipa", "Future Nostalgia", 220));
        return songs;
    }
}
Enter fullscreen mode Exit fullscreen mode

Example Usage

import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Load songs from storage
        List<Song> songs = StorageService.loadSongs();

        // Search service
        SearchService searchService = new SearchService(songs);
        List<Song> results = searchService.searchByArtist("Ed Sheeran");
        System.out.println("Songs by Ed Sheeran:");
        for (Song song : results) {
            System.out.println(song.getTitle());
        }

        // Play a song
        MusicPlayer musicPlayer = new MusicPlayer();
        musicPlayer.play(songs.get(0));
        musicPlayer.pause();
        musicPlayer.resume();
        musicPlayer.stop();

        // Create a playlist
        Playlist playlist = new Playlist("Favorites");
        playlist.addSong(songs.get(1));
        playlist.addSong(songs.get(2));
        System.out.println("Playlist: " + playlist.getName());
        for (Song song : playlist.getSongs()) {
            System.out.println(song.getTitle());
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • Modularity: Each component has a specific responsibility, making the system easy to maintain and extend.
  • Scalability: The design can easily integrate new features like streaming from online music libraries.
  • User Experience: Supports essential functionalities like playlists, search, and playback.

Top comments (0)