Simon Rettberg 54771e6ddf Minor fixes to ChildProcess
- Don't set FD_CLOEXEC, but close manually before fork:
  Since we don't use pipe2() to set the flag atomically, we're prone to
  races with concurrent fork+execs either way. As ChildProcess uses a
  mutex here anyways, as long as there is no other part in lms that
  would fork+exec, we're not any more or less safe now, but the code
  is shorter and we cannot fail the fcntl.
- Don't make the write-end of the pipe non-blocking. Usually programs
  do not expect this, i.e. they either never check the return code of
  a write to stdout (potential data loss), or if they do, they just
  bail out on any error, and don't handle EAGAIN. ffmpeg seemed
  to handle this fine though (or we were just lucky and always read
  the data faster than ffmpeg could produce it).
- Do not close stdin and stderr. Again ffmpeg seems to handle this,
  at least regarding stdin thanks to -nostdin, but in general if a
  process tries to write to stderr and fd 2 is not open, it might
  just bail out. Even worse, the process might have opened some
  file it wants to work with, and that file got assigned fd 2 (as
  that was the next free fd) - the program would corrupt whatever
  file it opened there whenever it tries to write to stderr.
  Try to open /dev/null instead for stdin and stderr, and if that
  fails, keep whatever lms inherited open, which should be safer
  than relying on the child process to handle this case properly.
- exec() does not return on success, no need to check return code,
  any return from it is a failure.
- Wrong error message in error path when assigning fd to boost stream.
- F_SETPIPE_SZ requires and int, not size_t. This worked on little
  endian systems since the value passed was < 2^32, but on big
  endian systems you'd effectively pass "0" if using a 64bit type.
- Address a few clang-tidy complaints (constness)
2025-06-02 09:18:31 +02:00
2025-04-22 22:55:51 +02:00
2024-04-27 15:16:03 +02:00
2025-06-02 09:18:31 +02:00
2024-12-05 19:57:56 +01:00
2020-06-21 14:29:36 +02:00
2025-04-20 15:50:21 +02:00
2025-03-23 20:52:26 +01:00

LMS - Lightweight Music Server

Last Release

LMS is a self-hosted music streaming software: access your music collection from anywhere using a web interface!

A demo instance is available. Note the administration settings are not available.

Main features

  • Subsonic/OpenSubsonic API support
  • Multi-valued tags: genre, mood, artists, ...
  • Artist relationships: composer, conductor, lyricist, mixer, performer, producer, remixer
  • Release types: album, single, EP, compilation, live, ...
  • Release groups support to show different versions of albums, such as remasters, reissues, etc.
  • MusicBrainz Identifier support to handle duplicated artist and release names
  • ListenBrainz support for:
    • Scrobbling and synchronizing listens
    • Synchronizing 'love' feedbacks
  • Recommendation engine
  • Multi-library support
  • ReplayGain support
  • Audio transcoding for compatibility and reduced bandwidth
  • User management, with several authentication backends
  • Playlists support
  • Lyrics support

Music discovery

LMS provides several ways to help you find the music you like:

  • Tag-based filters (ex: "Rock", "Metal and Aggressive", "Electronic and Relaxed", ...)
  • Recommendations for similar artists and albums
  • Radio mode, with endless filling of the play queue with tracks similar to what is there
  • Searches in album, artist and track names (including sort names)
  • Starred Albums/Artists/Tracks
  • Random/Starred/Most played/Recently played/Recently added for Artist/Albums/Tracks, allowing you to search for things like:
    • Recently added Electronic artists
    • Random Metal and Aggressive albums
    • Most played Relaxed tracks
    • Starred Jazz albums
    • ...

Note: depending on your database size and/or your hardware, the tag-based recommendation engine may significantly slow down the user interface. You can disable it in the administration settings.

About tags

LMS primarily relies on tags to organize your music collection but also supports browsing by directory using the Subsonic/OpenSubsonic API.

Artist information folder

LMS supports an Artist information folder to manage metadata and images for artists. This folder can be placed anywhere within the scanned libraries but is best located in a dedicated ArtistInfo directory in the root of a media library for maximum compatibility with other softwares.

The folder must follow a structure defined by Kodi, as detailed here. artist.nfo files are used to define additional artist information such as biography, sort name, and MusicBrainz ArtistID. See the format here.

Note: artist.nfo files must include both name and musicBrainzArtistID fields to be recognized.

Filtering

It is possible to apply global filters on your collection using genre, mood, grouping, language, and by music library. More tags, including custom ones, can be added in the database administration settings.

Note: You can use the lms-metadata tool to get an idea of the tags parsed by LMS.

Multiple artists

LMS works best when using the default Picard settings, where the artist tag contains a single display-friendly value, and the artists tag holds the actual artist names. This ensures a cleaner, more organized representation of artist names, when multiple artists are involved.

Multiple album artists

While LMS can manage multiple album artists using the albumartist tag, it works better when using the custom albumartists and albumartistssort tags, similar to how it handles regular artist tags.

Note: if you use Picard, add the following script to include these tags:

$setmulti(albumartists,%_albumartists%)
$setmulti(albumartistssort,%_albumartists_sort%)

Album track grouping

The recommended way to group tracks within an album is to use the MUSICBRAINZ_ALBUMID tag.

When this tag is not present, LMS will attempt to group them as best as possible: if the analyzed file contains a disc number and the total number of discs is greater than 1, sibling directories are also scanned to find a matching album. Otherwise, LMS will only consider albums within the current directory.

For an album to be considered a match, the following conditions must be met:

  • Same name
  • Same sort name
  • Same total number of discs
  • Identical 'compilation' flag value
  • Same record labels
  • Same barcode

Artist image lookup

The recommended method is to name the artist image file using the artist's MusicBrainz ArtistID. This file can be placed anywhere within one of the scanned libraries.

If no file with the MusicBrainz ArtistID is found, LMS will first look for files named folder and then thumb in the artist information directory, where the corresponding artist.nfo file is located. If neither exists, it will then search for a file named artist (or another name configured in lms.conf) in the artist's directories, using this logic:

  1. Identify the artist's directory: LMS selects all albums by the artist using the "AlbumArtist" link and determines the longest common path among them.
  2. Scan for the image: the directory is scanned starting from this common path, moving upwards if needed, until the artist image file is found.
  3. Fallback search: if no image is found, LMS will then search within each individual album folder.

Playlist support

LMS supports playlist files in m3u and m3u8 formats. These playlists are synced during the scan process and are available as public shared playlists.

Lyrics support

LMS supports lyrics in lrc files, txt files, and embedded track metadata. Both synchronized and unsynchronized lyrics are supported.

Keyboard shortcuts

  • Play/pause: Space
  • Previous track: Ctrl + Left
  • Next track: Ctrl + Right
  • Decrease volume: Ctrl + Down
  • Increase volume: Ctrl + Up
  • Seek back by 5 seconds: Ctrl + Shift + Left
  • Seek forward by 5 seconds: Ctrl + Shift + Right

Installation

See INSTALL.md file.

Contributing

Any feedback is welcome:

  • feel free to participate in discussions if you have questions,
  • report any bug or request for new features in the issue tracker,
  • submit your pull requests based on the develop branch.
S
Description
Lightweight Music Server. Access your self-hosted music using a web interface.
http://lms-demo.poupon.dev
Readme
16 MiB
Languages
C++ 98.7%
CMake 0.7%
JavaScript 0.3%
Python 0.2%