Inspiration

The inspiration for Jukebox came from the desire to create a seamless, interactive music-sharing experience for both online and in person meet-ups. After trying and failing to use discord, spotify, and others due to limited selections, paywalls, and ads, we decided to create an app than anyone could host themselves, with an example to check out at https://jukebox.homeworkclub.dev.

What it does

Jukebox allows users to collaboratively build and manage a music playlist in real-time. Users can add songs to the queue by pasting a Spotify link, control playback, shuffle the queue, and clear the playlist if needed. The platform supports synchronized playback across multiple devices, allowing can enjoy the same music experience simultaneously.

How we built it

We built Jukebox using a variety of modern web technologies and frameworks to ensure a robust and scalable solution:

Frontend

  • HTML5: Structured the main layout and elements of the application. HTML5 provided the semantic structure that made the application easy to develop and maintain.

  • CSS3 with DaisyUI and Tailwind CSS:

    • DaisyUI: Utilized for pre-designed, accessible components which significantly sped up the development process. DaisyUI provided a library of UI components that were customizable and consistent in design.
    • Tailwind CSS: Used for utility-first styling, enabling rapid UI development with classes that apply individual CSS properties. Tailwind’s flexibility allowed us to create a responsive and modern design quickly.
  • JavaScript: Handled client-side logic and interactions, including DOM manipulation and event handling. JavaScript was essential for making the application interactive and dynamic.

  • jQuery: Simplified HTML DOM tree traversal and manipulation, event handling, and animation. jQuery was particularly useful for AJAX requests and handling complex UI interactions with less code.

  • Socket.IO: Enabled real-time, bidirectional communication between the client and server for synchronizing playback and managing the queue. This ensured that any changes in one client were reflected across all clients instantly.

  • Audio API: Managed audio playback, including playing, pausing, and seeking within tracks. The Audio API allowed for precise control over audio playback, which was critical for maintaining synchronization across clients.

Backend

  • Flask:

    • Served as the web framework for handling HTTP requests, rendering templates, and serving static files.
    • Provided routes for various API endpoints that the frontend interacted with to manage the playlist and control playback.
  • Flask-SocketIO:

    • Managed WebSocket connections and real-time event handling.
    • Handled events such as play, pause, next song, previous song, and synchronization requests from clients.
    • Enabled broadcasting events to all connected clients to ensure that the playback state was consistent across all devices.
  • Python:

    • Implemented server-side logic, including playlist management, song addition, and synchronization.
    • Used for handling requests, managing the music library, and interfacing with external processes for downloading music.
  • Subprocess and asyncio:

    • Subprocess: Managed external processes for tasks such as downloading songs. This allowed the application to offload resource-intensive tasks to separate processes, ensuring the main application remained responsive.
    • asyncio: Facilitated asynchronous task management, enabling the server to handle multiple operations concurrently without blocking. This was crucial for handling multiple song download requests and real-time synchronization simultaneously.
  • aiohttp:

    • Used for making asynchronous HTTP requests during song download operations.
    • Ensured non-blocking network operations, which improved the performance and responsiveness of the server.
  • JSON:

    • Managed the music library data and metadata for efficient song retrieval and management.
    • Stored metadata about songs, such as URLs, titles, artists, and paths, in a JSON file. This made it easy to load, update, and query the music library.
  • Base64 Encoding:

    • Used for encoding file paths in URLs to ensure safe transmission of data over HTTP. This helped avoid issues with special characters in file paths.
  • Logging:

    • Implemented extensive logging throughout the application to monitor the system’s behavior and diagnose issues. Logging was particularly useful for debugging synchronization issues and tracking song download processes.

Challenges we ran into

  • Real-time Synchronization: Making sure that playback was being perfectly synchronized across multiple clients was a large challenge that we had to overcome multiple times. Handling slight network delays, improper syncs, and differences in client performance all contributed to the complexity of the issue.
  • Special Character: When a user played a song from a different language, it was a real challenge getting those characters to be interpreted by our api. We solved this challenge by decoding the song's path using base64, then reencoding it through the client
  • Error Handling: Robustly handling various edge cases and errors, such as invalid song URLs, failed downloads, clients leaving and rejoining, and conflicting sync's took a lot of testing to iron out.

Accomplishments that we're proud of

  • Real-time Collaboration: Successfully implementing real-time synchronization and collaboration features was a major accomplishment for us. Now, users can seamlessly add, remove, play, manage, skip, scrub, and shuffle songs in a shared playlist.
  • User Interface: Creating an intuitive UI that simple yet effective at managing music.
  • Scalability: Designing the application to handle multiple users and playlists concurrently without performance issues.

What we learned

  • Real-time Web Technologies: Learnt how to implement real-time web applications using Socket.IO and Flask-SocketIO.
  • Asynchronous Programming: Learnt more about asynchronous programming in Python, particularly with asyncio and aiohttp.
  • User Experience Design: Learned the importance of creating a user-friendly interface and the impact of design choices on user engagement.

What's next for Jukebox

  • Enhanced Music Discovery: Integrate additional music discovery features, such as personalized recommendations and trending playlists utilizing the Spotify API.
  • Advanced Playlist Features: Add more advanced playlist management features, such as genre-based sorting, mood-based playlists, and collaborative playlist editing.
  • Add separate listening rooms: Currently, the intended use case is for a group to self host the site, with us hosting it publicly simply as a means to display our project. However, it would be much easier for non-tech oriented groups to enjoy free group music listening if we could create different sessions within one publicly available website

Built With

Share this project:

Updates