swingmx / swingmusic

Swing Music is a beautiful, self-hosted music player for your local audio files. Like a cooler Spotify ... but bring your own music.
https://swingmx.com
MIT License
718 stars 41 forks source link

[FEATURE] Exporting and importing portable M3U files. #106

Closed cwilvx closed 1 year ago

cwilvx commented 1 year ago

This feature will allow the user to import an existing m3u playlist file into a playlist. It also allows the user to export the playlists created in Swing into an m3u file which can be usable by other music players.

Importing m3u playlists

  1. The user uploads the file
  2. File is sent to server over api
  3. File is checked and lines read
  4. Each line is searched in the database depending on the structure.
    1. If entry is full path, search by path
    2. If entry is a filename search by filename
  5. All the found files are added into a playlist in the database

Exporting m3u playlists

  1. A request is sent on the server to generate m3u
  2. All tracks fetched from database
  3. Tracks data is converted to an m3u readable format (no clear picture at the moment)
  4. The data is written to a file
  5. A link is returned to download the file.
cwilvx commented 1 year ago

Possible ... not urgent

ryanwwest commented 7 months ago

This would be nice to have. I'm honestly looking for portable apps that use universal m3u(8) files to store the playlists themselves so different apps can automatically get the same playlists, but maybe there are disadvantages so this hasn't caught on...

nk-gears commented 7 months ago

I wish to see this feature and wish to contribute as well.

cwilvx commented 7 months ago

Hello @nk-gears

Thanks for offering to contribute. Here is some information to get you started.

The database methods can be found at app/db/sqlite/playlists.py in the SQLitePlaylistMethods class and the api routes at app/api/playlist.py.

For importing playlists, you can create a function (or a class) that receives a M3U filepath and reads the music paths. With that list, you can find the tracks in the track store (app/store/tracks.py).

The TrackStore class has a .tracks property which is a list of indexed tracks held in memory. You can loop over them looking for matches. When you get your playlist tracks, you can use the SQLitePlaylistMethods.insert_one_playlist method to add the playlist to the database.

There also needs to be an API methods that receives a M3U path for triggering the process.

You can add the function for parsing M3U in the app/utils folder under a playlists.py file. You can find the track model at app/models/track.py.

If you have any questions, let me know. If you get stuck anywhere, feel free to ask for assistance.

Your contributions are appreciated.

PS: Let me know when you start working on this, so that I can reopen this issue.

nk-gears commented 7 months ago

@cwilvx Thanks for the detailed instructions.

Here some initial queries : Importing M3u file : As far i understand a m3u file will contain a http based url list. Should we need to support non-http paths as well ?

I have attached a sample file. Is my understanding correct ? sample-m3u.m3u.txt

cwilvx commented 7 months ago

@nk-gears

I was assuming that the M3U files don't contain http urls. That is, the files inside the playlist file are locally available.

The expected M3U file would look something like this:

Savage Garden - To the Moon & Back.mp3
Shanice - I Love Your Smile.mp3
Sixpence None the Richer CD 1 TRACK 4 (320).mp3

Sometimes, the M3U file might reference the full path instead of the filename.


Swing Music is built with local files in mind. That does not mean http files support can't be added.

The main problem with http files is reading the metadata (tags, cover image). If we can get the tags, we can just add a flag in the Track object to indicate the client should stream from the url. Without the tags, the whole playlist will have tracks with Unknown artists, albums, title, etc which will break the hashing. ie. all tracks will be treated as duplicates of each other. (Check app/utils/hashing.py)

Is there a way we extract track metadata from http playlists?

nk-gears commented 7 months ago

Downloading all the mp3 files is not recommended for extracting the Meta. We can use the Partial metadata download remotely but it will not work if the webserver fails to support partial download of file.

Suggestion : We can use the filename of the mp3 url as the Title and the Parent Path as Album.