Skip to content
forked from ATRAN2/fureon

Build and listen to a common music library with friends

License

Notifications You must be signed in to change notification settings

nattofriends/fureon

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fureon (tentative)

Fureon is a way to build and listen to a music library with friends. Heavily inspired by plug.dj, r-a-dio, and Soundcloud, it sets up a server where users contribute to build a global song library and can listen in on a main global music stream. Users can request songs from the library to be played on the main stream to share with others tuning in. Alternatively, they can freely stream and listen to any of the songs in the library.

Installation

Fureon has three main external dependencies: mpd/mpc icecast2 redis

Install and set up mpd/mpc to work as a source for icecast2. Here's a concise guide on how to set up mpd/mpc to stream with icecast2.

redis should typically be available in the repos for most linux distros.

After that, the backend can be quickly installed using setuptools with the provided setup.py. In /backend create and source a virtualenv then execute setup.py with install or develop:

$ python ./setup.py install

All python dependencies should be covered by the install. Several parameters in /backend/fureon/config.py need to be set before the app can run.

Paths

Fureon needs to know where to look for songs and where to save album art.

paths = {
    'song_directory' : '/home/user/music/',
    'static_folder_path' : '/var/www/fureon.site.com/frontend/static/',
    'log_file' : os.path.join(PARENT_DIRECTORY, 'fureon.log'
}

song_directory needs to be set to the same directory as mpd's song directory. static_folder_path needs should be set to where static files intend to be served. This is used as the target location to save album art. Leaving it blank will have the app not save any album art.

Database

Fureon uses SQLAlchemy which requires a database connection. The connection parameters must be set for the database used. An example for PostgreSQL:

database = {
    'drivername' : 'postgres',
    'host' : 'localhost',
    'port' : '5432',
    'username' : 'myusername',
    'password' : 'supersecretpassword',
    'database' : 'fureon',
}

Or for a simple SQLite db:

database = {
    'drivername' : 'sqlite',
    'host' : '',
    'port' : '',
    'username' : '',
    'password' : '',
    'database' : 'fureon.db',
}
Cache

Fureon uses redis to keep track of the delay for song and user request blocking.

cache = {
    'host' : 'localhost',
    'port' : '6379',
}

These are the default redis connection parameters. Change them if the system's redis server is set differently.

Once all the configuration is done, run the app with:

$ fureon-start

Implementation

Backend

The Fureon backend runs on tornado + SQLAlchemy + redis. Tornado was chosen for its performance, modularity and light weight, as well as its ease in implementing websockets. The database is abstracted into models with SQLAlchemy and redis is used as both a cache as well as a means to have a data structure that can expire with time. Fureon shares the music db directory of the system's mpd installation and can scan the directory while also extracting the metadata with mutagen into the database models.

Fureon currently handles playing music to the main stream with mpd controlled by mpc. The mpd output is used as an icecast source to serve listeners. The app watches any changes to mpd with the mpc idle cli command, and upon events such as a transition to the next song, it adds a callback to the tornado ioloop which signals changes to the fureon db playlist which then sends commands back to mpc to update the mpd playlist keeping both the mpd and fureon db playlists consistent.

Many functions in the Fureon backend can be accessed from it's RESTlike API. This includes searching for songs, getting the current playlist, getting song data, as well as requesting songs.

Frontend

Frontend work will be done in cooperation with github user Rifu working on the anzu repo. Powered by Ember.js, it will request the necessary data from the backend's RESTlike endpoints to build the app UI. The projects will merge eventually once a final name is settled and a good merging point is reached.

Backend API

The Fureon backend API has the following endpoints:

$ /api

Returns this description of all api endpoints in JSON format.

$ /api/playlist

Returns the current playlist with the order given as keys. Includes: song title, song artist, song id, song duration, and whether the song was user requested or not.

$ /api/stream_endpoint

Returns the uri for the stream endpoint.

$ /api/song/find?song-id=<song_id>

Returns the full details of a single song with the id <song_id>. Data includes (if available): id, title, artist, album, trackno, date, genre, duration, file_path, art_path, datetime_added, tags, play_count, fave_count.

$ /api/album/find?name=<album_name>

An exact search for albums with the name <album_name>. Will return a numbered object with song titles, song artists, song_ids, tracknos, dates, fave_count, play_count, and art_paths.

$ /api/artist?name=<artist_name>

An exact search for albums with the name <artist_name>. Will return a numbered object with song titles, song_ids, album names, dates, play_count, fave_count.

$ /api/request_song

POST method with params: song-id=<song_id>. Sends a song request to update the main stream playlist with the requested song. User requested songs have higher priority than random songs. Stream playlist order is requested songs in added order, then random songs in added order.

Features to Add / To Do (Priority Highest to Lowest)

User Request Blocking

Users should only be able to request a certain amount of times within a timespan. This is to prevent a single user from hijacking the stream with requests. Implement with redis in the same way the song request blocking works but with the requester's IP instead of song_id.

User Logins

This is for the user to login in order to mark songs as favorites and accessing a favorites page. Will require adding a user model as well as an authentication system. Tornado has authentication built in and storing passwords will most likely be done with passlib.

API Request Validation

Validate the arguments to an API request and return useful error responses if the request is incorrect.

Streaming Individual Songs

Besides the main stream, users should be able to listen to any track that's on the database separately.

Websocket Feed When Playlist Updates

Whenever another user sends a request or a song ends, the playlist order changes. Use websockets to keep a constant connection and send the user playlist change events. Implementation will most likely be done with sockjs-tornad

IRC Bot Control

A way to control the stream by sending commands to an IRC bot. Looking to add a plugin for kochira

About

Build and listen to a common music library with friends

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%