Skip to content
/ monobox Public

An ad-free, lightweight music player that lets you play music from your local library on your mobile device.

Notifications You must be signed in to change notification settings

ozzs/monobox

Repository files navigation

MusicPlayerLogo

An ad-free, lightweight music player that lets you play music from your local library on your mobile device.

React Native JavaScript TypeScript Prettier Python FastAPI SQLite


showcase1 showcase2

Table of Content

Overview

MonoBox is a free music application designed to be easy to operate, intuitive to the user and has fast performance.
Its main purpose is to play the music files you have on your computer, and to allow you to create and customize playlists according to your personal taste.

Users will be able to run their own servers with their own songs. The server itself is implemented in Python and the mobile application in React Native.

Key Features

  • Simple & Easy to use music player
  • Listen from your local library
  • Create and customize your own playlists
  • Open-Source code
  • Dark / Light themes
  • No ads

Tech

Frontend

  • React Native πŸ“±
    • JavaScript & TypeScript
    • Code formatted with Prettier πŸŽ€
    • React Native Track Player - An audio module for music apps 🎡
    • React Query - A powerful library containing hooks for fetching, caching and updating asynchronous data

Backend

  • Python 🐍
    • FastAPI - A modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints
    • SQLModel - A library for interacting with SQL databases from Python code, with Python objects
    • pre-commit, black, mypy and isort are integrated to make sure the code looks good and clean
  • Database πŸ“„
    • SQLite

Installation

First and foremost, make sure your mobile device and PC are using the same wireless network, otherwise the application will not be able to communicate with the server running on the computer.

Then, in the root of the project, create 2 folders:

  • songs contains all the songs in the app library.
  • covers contains all the artworks of the songs in the songs folder.

Now you can copy all the songs you want to display in the app into the songs folder.

Backend

The SQLite backend needs to be running for the API to use for state.

Start - Via task

You can use the included Taskfile to configure much of this project. This Makefile alternative will assume the ignored ./venv path for storage of local binaries and Python libraries.

First ensure task is installed to your PATH somewhere.

After this, the following tasks can be used to build the virtual environment and API backend via the task command.

# Configure virtual environment and pull down requirements
task backend:install

# Start up the backend services in the background
task backend:start &

NOTE: You can force re-run tasks anytime with the -f option. Example: task backend:install -f.

Start - Manual

From the root, you need to navigate to the backend folder. from your terminal:

cd backend

The requirements.txt file lists all the Python libraries that the music player depends on, and they can be installed from your terminal using:

pip install -r requirements.txt

Then, in the main.py file, you have this block of code, where you need to insert your PC's IP address (notice the comment):

host_ip = "0.0.0.0" # Change to your PC's IP
host_port = 5000
music_folder_url = "../songs"
cover_folder_url = "../covers"

The default port is 5000, but you can also change it if you want the server to listen to a different port, although it is required to change this in the Frontend as well.

Finally, run the following command from your terminal to set up your server and create your database:

python main.py

Backend - Validation

Visit the service url with /redocs or /docs to interactively browse the API docs. Example: http://127.0.0.1:5001/docs

Backend - Troubleshooting

If you run into issues running the backend you may need to reconfigure python after having installed the local sqlite3 development libraries (sudo apt install libsqlite3-dev for Ubuntu based systems.).

The included taskfile definition includes asdf-vm install and configuration tasks that can be used to bootstrap the Python and Nodejs environments if required.

Frontend Setup

After setting up the Backend, open a new terminal for the Frontend.
The package.json file lists all the React / React Native libraries that the music player depends on, so let's install them from the terminal using:

npm install

In order for the application to communicate with the server in the Backend, we need to insert the PC's IP address to the Frontend as well.
So now we need to navigate to the mobile/utils folder from the root of the project, and then to the BaseAPI.tsx file.
Inside BaseAPI.tsx you have the following block of code, where you need to insert the same IP address as you did in the Backend (notice the comment):

export const BASE_API_URL = '0.0.0.0' // Change to your PC's IP
export const BASE_API_PORT = 5000

If you decided to change the default port in main.py, this is the place to change it as well.

Now you're all set!
You are welcome to try the application yourself or continue to the next section to learn about its features and how to use it.

Usage

Create Playlist

Upon initializtion, in your Homescreen, you'll notice you have a playlist called Liked Songs which does not contain any songs at the moment. Don't worry, we'll get to that later. ↩️
On the top right corner you'll also notice a βž• sign button, with which you can create a new playlist and give it a name!

create-playlists

Add Songs To Playlist

If you followed the instructions on the Installation section and copied all the songs to the designated folder, you should be able to see all of them on your Library screen. πŸ“š
In order to add a song to a playlist, press the button that appears to the right of each song, and choose one of your playlists. Pretty easy so far, huh? ✌️

add-songs-to-playlist

Remove Songs From Playlist

So in order for you to remove a song from a playlist - simply press a song in a playlist and hold it for 2 seconds, and the song will be removed.

remove-songs-from-playlist

Delete Playlist

The same goes for the entire playlist - press its name and hold for 2 seconds, and it will be deleted along with its songs.

delete-playlist

The Songs Carousel

What music app would it be without a Songs Carousel, right? For you to get to the Songs Carousel, just press on any song in a playlist, on any screen you'd like (e.g. Choosing a song from the Library screen will create a queue of all the songs from the Library for you).

Skip Songs

So the Songs Carousel is quite intuitive and familiar to use.
To skip to the next or previous song - click on ◀️ / ▢️ at the bottom of the screen, or alternatively slide the song artwork to the right / left.

Repeat

You also have the πŸ” button which determines whether the list of songs that is currently playing:

  • will repeat itself endlessly ♾️
  • will repeat once πŸ”‚
  • will not repeat itself at all

Slider

Above the Slider, the current running time of the song (on the left) and the time remaining until the end of the song (on the right) are indicated.
Did you like a certain part of the song? The Slider itself allows you to move forward and backward in the song.

Like Button

Pressing the ❀️ button will add the song you selected to the Liked Songs playlist that appears on the Homescreen and the Liked Songs screen (in the navigation drawer).

songs-carousel

The Current Song Tab

You will notice that if a song from a playlist is playing in the background, a new tab will appear at the bottom of the screen, indicating which song is being played, which also (similar to the Songs Carousel) allows you to move forward and backward in the song with the Slider and skip to the next or previous song.

current-song

Toggle Themes

As mentioned before, you can switch themes between dark mode and light mode, using the moon icon that appears at the top right corner of the navigation drawer.

themes

Implementation Notes

Oh, and one more thing!
In case you were wondering how adding/deleting songs works behind the scenes:
Every 30 seconds, the server simultaneously checks for compatibility between the song lists in the songs folder and the database, and for each song one of the following actions is performed:

  • If the song exists only in songs and not in the database ➑️ adds the song to the database.
  • If the song exists only in the database and not in songs ➑️ deletes the song from the database.
  • If the song exists both in the database and in the folder ➑️ does nothing.

Or in a more "Pythonic" way, if you'd like:

if songs in songs_folder:
   if song in database:
     continue
   else:
      database.add(song)
elif song in database:
  database.remove(song)

Support

The product is still in its initial stages, so we would really appreciate feedback and donations πŸ˜„
And don't forget to star us β€” it motivates us a lot! ⭐

Project Resources

Create a bug report or submit a feature request

If you see an error message or run into an issue, or maybe you have an idea, or you're missing a capability that would make development easier and more robust, please create a bug report or submit a feature request.

If a similar feature request already exists, don't forget to leave a "+1". If you add some more information such as your thoughts and vision about the feature, your comments will be embraced warmly πŸ˜ƒ

About

An ad-free, lightweight music player that lets you play music from your local library on your mobile device.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages