MiniMedia Sonic Server

June 6, 2026 ยท View on GitHub

A work in progress Subsonic music server with as backend database, postgres

There is a lot of work to be done still, but the basics work (playing a track, seeing the artists/albums/tracks)

My main goal is to come as close as possible to a real service, so that means performance, features they provide (covers, similar tracks etc)

Roadmap

This roadmap will be ongoing as the project keeps going

  • Support for all OpenSubsonic API's
  • Support for all Navidrome API's
  • Legacy Subsonic authentication (needs to be improved still)
  • Token-based Subsonic authentication
  • Get similar tracks from Tidal
  • Redis caching
  • Support for Navidrome's Smart Playlist (nsp) format

Tested Working Android/iPhone Apps

  1. Android: Symfonium https://www.symfonium.app
  2. iPhone: Arpeggi
  3. iPhone: Narjo https://narjomusic.com
  4. iPhone/Android: Substreamer https://substreamer.org
  5. iPhone: Armperfy

Tested working projects

  1. Feishin https://github.com/jeffvli/feishin

If a app/project was not mentioned in the list it does not mean it won't work, it simply means I personally did not verify it working

Docker Compose

services:
  main_app:
    container_name: MiniMediaSonicServer
    deploy:
      resources:
        limits:
          memory: 256M
    hostname: MiniMediaSonicServer
    image: musicmovearr/minimediasonicserver:latest
    ports:
      - target: 8080
        published: "8080"
        protocol: tcp
    restart: always
    volumes:
      - type: bind
        source: /DATA/AppData/MiniMediaSonicServer/appsettings.json
        target: /app/appsettings.json
      - ~/Music:~/Music:ro

Example Configuration

It's important you bind this file to /app/appsettings.json as above in the docker example

Change the connectionstring to your own postgres database

Change the "aaaaaaa" with a random 64character string, for example on linux you can run, openssl rand -hex 32

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "DatabaseConfiguration":{
    "ConnectionString": "Host=192.168.1.1;Username=postgres;Password=postgres;Database=minimedia;Pooling=true;MinPoolSize=5;MaxPoolSize=100;"
  },
  "EncryptionKeys": {
    "UserPasswordKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  },
  "tls": {
    "Certificate":
    {
      "CertificateFile": "",
      "KeyFile": "",
      "Password": ""
    }
  },
  "Shares": {
    "BaseUrl": "http://192.168.1.2:8080"
  },
  "Redis": {
    "ConnectionString": "",
    "Expiry": "72:00:00",
    "SlidingExpiration": "72:00:00"
  },
  "MusicCache": {
    "Path": "/cache",
    "DirectoryFormat": "{CleanArtistUpper:substr(0,1)}/{CleanArtistUpper:substr(1,1)}/{CleanArtist}/{Album}",
    "DirectorySeparator": "_",
    "FileFormat": "{CleanArtist} - {Album} - {DiscNumber:cond:<=1?{TrackNumber:00}|{DiscNumber:00}-{TrackNumber:00}} - {Title}",
    "MaxCacheSize": 1000000000,
    "MaxFileSize": 50000000,
    "ExposeCachedFilePath": false
  },
  "Jobs": {
    "PlaylistImportCron": "0 0 0 * * ?",
    "NavidromeSmartPlaylistRefreshCron": "0 0 0 * * ?",
    "PlaylistFixTracksCron": "0 0 0 * * ?",
    "PlayHistoryFixTracksCron": "0 0 0 * * ?",
    "ReIndexSearchCron": "0 0 0 * * ?",
    "ImportLastFmScrobblesCron": "0 0 0 * * ?",
    "AutoLikeCron": "0 0 0 * * ?",
    "ScrobblerCron": "0 0/15 * * * ?"
  }
}

Shares

After sharing your url with another user, you'll get to see this retro webplayer image

Webjobs (Scheduled Tasks)

By default the following jobs are scheduled hourly which can be changed in the appsettings.json

  1. Playlist Import: Will look into the "/playlists" folder looking for .m3u files to import
  2. Playlist Fix Tracks: will look for playlist track files that were replaced (e.g. mp3 > flac) so files don't exist anymore but are in your playlists, it will search & replace that track with another with 99% accuracy match
  3. ReIndex Search: Keeping the search up-to-date whenever new tracks were added/remove/updated
  4. AutoLike: Per user configurable, when listening an artist e.g. +100x, automatically favorite the artist. later I will implement it as well for albums. User properties available (AutoLike_Artists_Enabled, AutoLike_Artists_DaysRecent, AutoLike_Artists_ListenCount)
  5. AutoRate: Per user configurable, when you've rated tracks in a album by e.g. >50% and minimum rating comes out as 4/5 stars. rate the album 4 or 5 stars automatically. User properties available (AutoRate_Albums_Enabled, AutoRate_Albums_MinimumRating, AutoRate_Albums_TracksRatedPercentage)
  6. AutoRate: Per user configurable, When you've rated a track from an album/single(etc), rate all other duplicate with +99% accuracy based on Acoustid Fingerprint tracks with the same rating. When matching based on Acoustid Fingerprint, this is an cpu intense task using multiple cpu cores. User properties available (AutoRate_DuplicateTracks_Enabled)
  7. Scrobbler: Scrobbles pending scrobbles to services like ListenBrainz, LibreFm, Maloja

Implemented API's

A lot of Not yet/Partially but on iPhone the Arpeggi/Narjo/SubStreamer apps are usable, mind you with missing API implementations

APIImplementedStatus
AddChatMessageNot yet
ChangePasswordNot yet
CreateBookmarkWorking
CreateInternetRadioStationNot yet
CreatePlaylistWorking
CreatePodcastChannelNot yet
CreateShareWorking
CreateUserWorking
DeleteBookmarkWorking
DeleteInternetRadioStationNot yet
DeletePlaylistWorking
DeletePodcastChannelNot yet
DeletePodcastEpisodeNot yet
DeleteShareWorking
DeleteUserWorking
DownloadWorking
DownloadPodcastEpisodeNot yet
GetAlbumWorking
GetAlbumList2Working
GetAlbumListWorking
GetArtistWorking
GetArtistInfo2Working
GetArtistInfoWorking
GetArtistsWorking
GetAvatarNot yet
GetBookmarksWorking
GetCaptionsNot yet
GetChatMessagesNot yet
GetCoverArtWorking
GetGenresWorking
GetIndexesNot yet
GetInternetRadioStationsNot yet
GetLicenseNot yet
GetLyricsBySongIdNot yet
GetLyricsNot yet
GetMusicDirectoryNot yet
GetMusicFoldersPartially
GetNewestPodcastsNot yet
GetNowPlayingNot yet
GetOpenSubsonicExtensionsWorking
GetPlaylistWorking
GetPlaylistsWorking
GetPlayQueueByIndexWorking
GetPlayQueueWorking
GetPodcastEpisodeNot yet
GetPodcastsNot yet
GetRandomSongsWorking
GetScanStatusNot yet
GetSharesWorking
GetSimilarSongs2Working
GetSimilarSongsWorking
GetSongWorking
GetSongsByGenreWorking
GetStarred2Working
GetStarredWorking
GetTopSongsWorking
GetTranscodeDecisionNot yet
GetTranscodeStreamNot yet
GetUserWorking
GetUsersWorking
GetVideoInfoNot yet
GetVideosNot yet
HLSNot yet
JukeboxControlNot yet
PingWorking
RefreshPodcastsNot yet
SavePlayQueueByIndexWorking
SavePlayQueueWorking
ScrobbleWorkingHistory via database and scrobbling ListenBrainz, Maloja work
Search2Not yet
Search3Working
SearchNot yet
SetRatingWorking
StarWorking
StartScanNot yet
StreamWorking
TokenInfoNot yet
UnstarWorking
UpdateInternetRadioStationNot yet
UpdatePlaylistWorking
UpdateShareWorking
UpdateUserWorking