* Matcher: Musicbrainz test: fix
* Matcher: When resolving providers from musicbrainz, filter out resolved providers
* tmp
* Matcher: Use async in tests
* Mobile: Auth form is in a modal
* Mobile: State: Save current/other meelo instances
* Mobile: Fix typing
* Mobile: Switch server from settings
* Mobile: Select server from auth page
* Mobile: Settings: Refresh cache when connecting a new server
* Mobile: Validate Instances objects when restoring from local storage
* Scanner: Install C fs watcher
* Scanner: Setup Library watchers
* Scanner: Call go function on FS event
* Scanner: Pass library and event payload to fs event handler
* Scanner: Add tasks to queue on file system event
* Scanner: Fix DL script, setup env in CI and docker
* Scanner: README: Add setup instructions for the C library
* Scanner: TODO on fs event for modified file
* Mobile: Infinite song Page: Query param by genre
* Mobile: Infinite album Page: Query param by genre
* Mobile: List Item: allow not to have illustration
* Mobile: Base Infinte Genre Page
* Mobile: Genre Context Menu
* Mobile: Genre Chip
* Mobile: Home Page: Top Genre List
* Mobile: Lint
* Front: Player State: Add featuring artist state
* Front: Web: Pass featuring artists to player state when possible
* Front: Mobile: Pass featuring artists to player state when possible
* Server: add album, artist and playlist to playlist
* Front: API method to add to playlist
* Front: Web: Use 'addToPlaylist' API method
* Front: Web: Add artist, album, release and playlist to playlist
* Server: Add artist's songs to playlist: sort songs by name
* Front: Mobile: Add artist, album, release and playlist to playlist
* Front: Mobile: Resource header: add context menu
* Server: add album, artist and playlist to playlist
* Front: API method to add to playlist
* Front: Web: Use 'addToPlaylist' API method
* Front: Web: Add artist, album, release and playlist to playlist
* Server: Add artist's songs to playlist: sort songs by name
* Front: Mobile: Add artist, album, release and playlist to playlist
* Server: Playlist service: factor 'addToPlaylist'
* Front: fix typo
* Server: Define EP album type
* Matcher: Consider EP album type with MusicBrainz
* Front: EP album type + Function to translate resource types
* Server: Parser service: Fix tests
* Server: Settings: Add 'Enable user registration' field
* Server: User Controller: Disable registration endpoint according to settings
* Front: Disable signup button when registration is disabled
* Server: Test disabled user registration + fix permission tests
* Front: Setup workspace for web app
* Front: Move models to their own package
* Front: API: Move logic of 'isDev', 'isSSR' to hook
* Front: Move sorting parameters to model package
* Front: Move union for yup to models package
* Front: Define base tsconfigs
* Front: Model package: add typescript as dev dep to be able to run tsc
* Front: Make test (finally) typecheck
* Front: Add tsc command to root package.json
* Front: Change name + import path of libs
Removing '@meelo' prefix
* Front: Move api, state and utils to packages
* Front: Monorepo: Move translations out of web project
* Front: Update Dockerfile to work with monorepo
* Front: Update Dev Docker for monorepo
* CI: Front: Use monorepo path + remove test job
* CI: Front: Trigger when packages and translation changed
* Front: Init 'components' package + move ctxt menu + tiles there
* Front: Move infinite scroll + list items to component package
* Front: format
* Front: remove dependency to iconsax in web add
* Front: Docker: Copy component package
* Front: API: Fix url of illustrationsin SSR
* Added russian lang support
* Added russian lang support
* Fixed indents
* Fixed indent on 98 line
* Added line ending
* Changed spaces to tabs
* Russian Translation: Fix indentation
---------
Co-authored-by: Arthur Jamet <arthur.jamet@gmail.com>
* Front: Mark a song as played according to last fm's scrobbling rules
See 'https://www.last.fm/api/scrobbling#when-is-a-scrobble-a-scrobble'
* Prisma: Add Scrobbler Table
* Server: Add Scheduler/Cron job module
* Server: Scrobbler Service + Controller + Implem LastFM
* Front: Queries + Model for Scrobbler Statuses
* Front: Callback handler for LastFM Auth
* Front: Settings: Add Section for Scrobblers
* Doc: Add LastFM Fields in .env
* Server: Scrobbler Controller: Only authed requests can get lastfm auth url
* Server: Scrobbler: Error handling when pushing scrobbles fail
* Front: Scrobbler Settings: Make things a bit more generic
* Server: Scrobbler: Implement ListenBrainz
* Server: Scrobbler: Implement ListenBrainz
* Front: Settings: Add form to connect ListenBrainz
* README: Mention Scrobbling feature
* Server: Scrobbler: Unlink
* Front: Settings: Unlink Scrobbler account
* Server: README: List Lastfm env vars
* Server: ListenBrainz: remove ununsed model
* Server: Scrobbler Service: Avoid crash when deleting scrobbler that is not connected
* Server: Scrobbler: Test CRUD
* Front: Translation: Structure file for english
* Front: i18next: only use english json structure for typing
* Front: Use new translation keys
* Front: i18next: update french translation file structure
* Prisma: add visibility field to playlist table
* Server: Test: add user to dummy repository
* Server: Fix permission of route that accept both anonymous requests and authed ones
* Server: add 'isPublic' and 'allowChanges' to playlist
* Prisma: Make Migration for playlist visibility non breaking
* Front: Playlist Form: add visibility fields
* Front: Playlist Menu: Filter out update action if not owner
* API: allow filter playlist by 'allowChanges'
* Front: Filter out playlist that cannot be edited in 'select playlist' form
* Front: Playlist: Disable edit + delete button depending on user permissions
* Front: Fix uploading illustration, because 'this' wasn't bound
* Server: Test 'changeable' selector in playlist controller
* Front: Remove debug msg
* Server: Playlist Service: Make query make more sense
* Front: Refactor API + Query
* Front: Use New API + Query hooks
* Front: Fix 'transform' in player state + simplify pagination handling in API
* Front: Prevent undefined error in player after logout
* Front: Fix Pagination in API
* Front: Remove comment
* Front: Fix wrong toas tmessage on user un-admin
* Front: Setting Grids: fix color of header
* Front: Bump MUI to v6
* Front: Bump MUI DataGrid to v6
* Front: MUI: Use Grid2 for library form + list items
* Front: MUI: Use Grid2 for artist page + page sections component
* Front: MUI: Use Grid2 for playlist page
* Front: MUI: Use Grid2 for UI settings
* Front: MUI: Use Grid2 for Release Page
* Front: MUI: Use Grid2 for Highlight Cards
* Front: MUI: Use Grid2 for empty state
* Front: MUI: Use Grid2 for Library Settings
* Front: MUI: Use Grid2 for Genre tiles
* Front: MUI: Use Grid2 for Player Slider
* Front: MUI: Use Grid2 for Track items
* Front: MUI: Use Grid2 for Relation Page Header
* Front: MUI: Use Grid2 for Actions + Infinite view controls
* Front: MUI: Use Grid2 for Player's minimized controls
* Front: MUI: Use Grid2 for Keyboard Biding Modal
* Front: MUI: Use Grid2 for Player's expanded controls
* Front: MUI: Use Grid2 for Auth form
* Front: Lint
* Front: MUI 7: Use new Grid import
* Front: MUI 7: Re-setup Style in SSR
* Front: Lint
* Front: Bump MUI DataGrid to v7
* Front: Fix MUI Migration
* Front: Start new Controls + Actio Group
* Front: New Controls: Layout Button
* Front: New Controls: Split into subcomponents
* Front: New Controls: Layout Hook
* Front: New Controls: Sort Hook
* Front: New Controls: Filter Hook
* Front: TMP
* Front: New Controls: Fixes for Sorting
* Front: New Controls: Specialize filter for single/multiple choices
* Front: New Controls: Fix typing for song groups
* Front: New Controls: Use in Album View
* Front: New Controls: Use in Video View
* Front: New Controls: Use in Track View
* Front: New Controls: Use in Playlist View
* Front: New Controls: Fix opeing actions' dialog
* Front: New Controls: Use in Artist View
* Front: Remove Old controls
* Front: New Controls: Rename files, shorten paths
* Front: New Controls: Fix initial state of layout when SSR
* Front: New Controls: Filters and Sort have dedicated button groups
* Front: New Controls: Fix 'selected' state when filter has multiple choices
* Front: New Controls: Remove 'defaultSortingKey' from Sort Control
* Use the embeded video illustration as thumbnail if one exists.
This falls back to the existing implementation of using a frame from the video if no embeded illustration is present.
* Add aspect ratio check
* Revert "Add aspect ratio check"
This reverts commit 73a0c737156feda2c9a1a05e6736cb8d07d4c5d4.
* Add "useEmbeddedThumbnails" option
* Format code
* Add song type icons next to the name
* Use translated name for song type tooltip
* Move icons to song info page and track info modal
* Change icons for cut and edit song types
* Remove leftover code edits
* Change demo song type icon
* Improve songType french translation
* Remove unnecessary casts
* Make the track info song type icon fit the font size
This also makes it smaller overall
* Remove song type icon tooltip
* Handle the case where a track has no song during song type display
* Show a skeleton for song type while the data is loading
This also makes the icon a bit smaller
* Fix type check, lint & format
* Scanner: Parse BPM
* Scanner: Add BPM to Registration DTO
* Server: Persist BPM
* API: Sort Songs by BPM
* Front: Show BPM in Track Info Modal
* Front: Make Info Icon look like an info icon
* Front: Song Contextual Menu: add link to song info page
* Scanner: Fix tests
* Scanner: Add progress value in worker
* Scanner: add progress in /tasks response + set progress for scan task
* Scanner: set progress for refresh task
* Scanner: set progress for cleaning task
Hi! Thanks for considering contributing to Meelo. The project is open-source and is free, so contributions are essential to keep the project alive.
Be aware that your code contributions will be published under the [GPL-3.0 license](https://github.com/Arthi-chaud/Meelo/blob/main/LICENSE).
## Kinds of contributions
In this document we consider three kinds of contributions:
- Ideas
- Bug reports
- Feature or improvement ideas
- Code
- Documentation
- For users (e.g. wiki) or developers (e.g. the READMEs in each app directory)
## General guidelines
When contributing, please consider the following:
- If you want to suggest new feature or improvement, please open an issue first
- If you want to implement said feature, clearly state it in the issue's body
- Wait for the approval of the maintainer before starting.
- If you noticed a bug
- Either open an issue to report or ask about it
- If you are certain it is a bug and not a design choice and wish to fix it, you can open a pull request, no need to create an issue beforehand.
- If you want to contribute to the user documentation
- please first open an issue listing what you want to add/modify
- provide the new content in the issue's body.
- If you want to contribute to the developer's documentation
- No need for an issue, you can create your pull request right away.
## Code-related guidelines
### Submitting a pull request
1. Fork and clone the repository.
2. Create a new branch: `git checkout -b my-branch-name`.
3. Write code.
4. Make sure the code is formatted correctly.
5. Make sure all previous tests pass.
6. Push to your fork and submit a pull request.
### Developer documentation
Each service/app comes with a README dedicated to developers. Please read it to better understand about how the project works. **Warning**: these may be incomplete and/or outdated. If that's the case, please report it (or open a PR).
### Code formatting
All submitted code should be formatted and linted. When submitting code, please make sure your code is formatted properly (e.g. with Biome) and does not trigger any lint errors.
If you are not sure what tooling is used for a specific app, please open an issue.
### Testing
Some apps have unit tests. If it is doable, please write tests for your code. This is not mandatory but highly appreciated. If you have questions about how to set up the testing environment, please open an issue.
**All tests should pass locally**. As long as that's not the case, your contribution will not be accepted.
### CI
If you opened a pull request, the `Dockerisation` steps of the CI might fail. This is expected and should be addressed at some point. All other CI steps should pass (with one exception: the Matcher's tests might fail randomly).
Welcome! Meelo is a self-hosted music server and web app. It works similarly to Plex, Jellyfin, Koel and Black Candy, but focuses on flexibility, browsing and listening experiences. Actually, Meelo is designed for music collectors. What does it mean? Scroll down to see our killer features :arrow_heading_down:
While the software wants to be a flexible as possible, it requires a little bit of setup. However, once everything is ready, you will just have to sit back, relax, and enjoy your music. :sunglasses:
Welcome! Meelo is a self-hosted music server. It works similarly to Plex, Jellyfin, Koel and Black Candy, but focuses on flexibility, browsing and listening experiences. Actually, Meelo is designed for music collectors. What does it mean? Scroll down to see our killer features :arrow_heading_down:
While the software aims to be a flexible as possible, it requires a little bit of setup. However, once everything is ready, you will just have to sit back, relax, and enjoy your music. :sunglasses:
## :star: Features
@@ -25,62 +30,83 @@ Meelo has all the basic features you might expect from a music player/server (pl
- Songs have _tracks_
- It is pretty much the same as for albums and releases
- No duplicated songs when browsing your library!
- Song Versions
- Browse Songs [grouped by version](./assets/examples/song-groups.png)
- Songs have _versions_
- See an example [here](./assets/examples/song-groups.png)
- Album and Song types
- Finding instrumental songs or live recordings has never been this simple!
- Filter Songs that are exclusive to an album (compilations only)
- Filter Songs that are exclusive to an album (for compilation albums only)
- Supports all formats!
- Thanks to transcoding and the way we parse files, any audio and video format is virtually supported
- (Note: Transcoding is only used when the file format is not supported in the browser)
- Flexible metadata parsing
- Use either the embedded metadata or the file's name (or both!) to extract metadata
- Also works with album covers!
- Get genres, descriptions, and ratings using MusicBrainz, Genius, Wikipedia and many more providers!
-Download lyrics
- Get genres, descriptions, and ratings using MusicBrainz, Genius, Wikipedia and many other providers!
-Push Scrobbles to ListenBrainz and LastFM!
- Download (synced) lyrics or get them from embedded metadata and `.lrc` files
Keep track of the upcoming features [here](https://github.com/Arthi-chaud/Meelo/issues)
To use Meelo, you'll need a 'clean' collection: either with embedded metadata or standard file/folder architecture. Using iTunes or Beets is a great way to start.
## 🔧 Setup
Meelo is shipped though Docker images. You might need to know a bit about Regexes.
Look over [here](https://arthi-chaud.github.io/Meelo/) for setup instructions.
:point_right: To get started, follow the dedicated [wiki](https://github.com/Arthi-chaud/Meelo/wiki)
You'll need a 'clean' collection: either with embedded metadata or standard file/folder architecture. Using iTunes or Beets is a great way to start.
> [!NOTE]
> Meelo is shipped though Docker images. You might need to know a bit about Regexes.
## :iphone: Android App
Meelo now has an Android app :tada:. However, it is still in alpha and lacks some important features.
Go [here](https://github.com/Arthi-chaud/Meelo/discussions/1130) for more information.
You can find the known issues and the list of missing/upcoming features [here](https://github.com/Arthi-chaud/Meelo/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22Front%20(Mobile)%22)
While the app is in alpha, we recommend using the web app. With its responsive design, it works perfectly on mobile devices.
:point_right: You can find more screenshots of the UI [here](./docs/screenshots/)
>[!NOTE]
> Some screenshots may be outdated and may not show the state of the latest version of the app. Some minor details may change (e.g. logo, spacing, etc.)
</details>
## :desktop_computer: Live Demo
We are actively working on a public demo, so that you can try out Meelo. Stay tuned...
## :camera: Screenshots
## 🌐 Translation
<details>
<summary>Unfold to see what the web application looks like!</summary>
Meelo uses [Weblate](https://weblate.org/en-gb/) to handle translations.
Feel free to contribute [here](https://hosted.weblate.org/engage/meelo/)!
Any questions about this? Open a discussion [here](https://github.com/Arthi-chaud/Meelo/discussions/categories/translation)!
## :handshake: Contributing and Bugs reporting
:hammer: Would you like to contribute to Meelo? Feel free to [open a pull request](https://github.com/Arthi-chaud/Meelo/compare).
:thinking: Is there a feature you would like to have? [Open an issue](https://github.com/Arthi-chaud/Meelo/issues/new/choose), and we will be happy to discuss it!
:wrench: Need help with the setup process? Open a discussion [here](https://github.com/Arthi-chaud/Meelo/discussions/categories/need-help-with-setting-up).
:bug: Have you encountered a bug? Ugh we don't like 'em here! Report it by [opening an issue](https://github.com/Arthi-chaud/Meelo/issues/new/choose).
:hammer: Would you like to contribute to Meelo? Feel free to [open a pull request](https://github.com/Arthi-chaud/Meelo/compare).
---
Get ready to make the most out of you music collection!
In Music Apps, we usually call any song container an *Album*. While this is technically incorrect, many music streaming services categorizes these *Albums* in sub-categories: Albums, Singles, Live, Compilations, etc.
## Available Types
Meelo supports this categorization, and the following album types:
- Studio Recording
- What we would usually call *Albums*
- Live Recording
- Compilation
- Single
- Soundtrack
- Remix Album
- Collections that would mainly have remixes of songs by a single artist, while not being a Single
- Video Album
- Any kind of collection that would only contain video tracks
## Type recognition
Meelo tries to be as independent of user interactions as possible. Therefore, type recognition is done automatically, when a new album is registered.
For now, Type recognition is solely based on the Album's title. Keywords to recognize an album's type were inspired by the way other music streaming services would categorize an album. Therefore, if your music collection's naming convention work a similar way to Spotify, Apple Music, ..., there might not be a lot to change if you want to fully enjoy this feature. However, if you consider that one of the following ways to recognize a type is incomplete or incorrect, feel free to [open an issue](https://github.com/Arthi-chaud/Meelo/issues).
Meelo is now able to parse and recognise featuring artists on a song, based on:
- Its name
- Its artist field (from the metadata)
It does not leverage the album artist.
For example, a song named 'My Song (feat. Another Artist)' by 'Primary Artist & Other Artist' would be parsed to 'My Song' by artist 'Primary artist', featuring 'Other Artist' and 'Another Artist'.
Therefore, each featuring artist will be added to the database, and treated like any other artist.
Parsing works with `()`, `[]` and `-` as delimiters.
## Examples
In this section, we list examples that would be successfully parsed by Meelo
- 'My Song (feat. B)' by 'A'
- Name: 'My Song'
- Artist: 'A'
- Featuring: 'B'
- 'My Song (Remix) [feat. B]' by 'A'
- Name: 'My Song (Remix)'
- Artist: 'A'
- Featuring: 'B'
- 'My Song' by 'A & B'
- Name: 'My Song'
- Artist: 'A'
- Featuring: 'B'
- 'My Song' by 'A, B & C'
- Name: 'My Song'
- Artist: 'A'
- Featuring: 'B', 'C'
- 'My Song - With D' by 'A, B & C'
- Name: 'My Song'
- Artist: 'A'
- Featuring: 'B', 'C', 'D'
- 'My Song - Version With Drums' by 'A'
- Name: 'My Song - Version With Drums'
- Artist: 'A'
- Featuring: None
- 'My Song' by 'A Vs. B'
- Name: 'My Song'
- Artist: 'A'
- Featuring: 'B'
## Special Case: Artist is already known
By default, we use '&' to find and split a list of artist. However, this behaviour changes if an artist containing '&' already exists.
For example, if we had an *album* artist named 'A & B' (since album artist are not parsed as much as song artists), a song named 'My Song (feat. A & B)' would be parsed as 'My Song', with featuring artist 'A & B'.
In your `Meelo` folder, copy this [docker-compose file](https://raw.githubusercontent.com/Arthi-chaud/Meelo/master/docker-compose.prod.yml) as `docker-compose.yml`. It can be used as-is.
Additionally, you should copy [nginx configuration file](https://raw.githubusercontent.com/Arthi-chaud/Meelo/master/nginx.conf.template) as is in your `Meelo` folder.
In your `Meelo` directory, copy this [`.env.example`](https://raw.githubusercontent.com/Arthi-chaud/Meelo/master/.env.example) as `.env` and fill the variables
The toughest part is to have an structured music library. The way files are organised are up to you! But here is a recommended architecture:
```tree
Library's Folder
│
Artist 1
│ │
│ └───Album 1
│ │ 01 Track 1.m4a
│ │ 02 Track 2.m4a
| | cover.jpg
│ │ ...
│ ...
```
Meelo provides two ways of collecting metadata: using embedded tags, or using the path of the file. If a metadata source does not provide a specific field, you can use the other as a fallback. (You will configure this behaviour in the next sections). But before going any further, you should decide which metadata collection method to use.
In the `settings.json`, ff the `provider` object does not contain a provider's settings, this provider will be disabled.
Providers can also be disabled explicitly by setting the Provider's settings' field `enabled` at `false`. For example:
```json
// In settings.json
{
//... Other properties
"providers":{
"provider1":{},// Provider 1 is enabled
// Provider 2 was not specified, it is therefore disabled
"provider3":{
"enabled":true// Provider 3 is enabled
},
"provider4":{
"enabled":false,// Provider 4 is disabled
"apiKey":""// Other property of provider 4
}
}
}
```
If a provider is disabled, no call to its service will be done.
## Providers' properties and features
| Provider Name | Key | Additional Properties | Artist Description | Artist Illustration | Album Description | Album Rating | Song Description | Song Lyrics | Release Identification | Album Genres |
| AllMusic | `allmusic` | None | | | x | x | | | | |
| MetaCritic | `metacritic` | None | | | x | x | | | | |
| Wikipedia | `wikipedia` | None | x | | x | | x | | | |
| Discogs | `discogs` | `apiKey`: Access Token, you can get it [here](https://www.discogs.com/settings/developers) | x | | | | | | x | x |
**Warning**: Meelo heavily relies on Wikidata to optimize the metadata fetching. It is used if, and only if the MusicBrainz Provider is enabled. It is not possible to use one without the other.
*Note*: If MusicBrainz is enabled, we might make requests to [AcoustID](https://acoustid.org)'s API to match songs using audio fingerprints (No data will be submitted).
In your `Meelo` folder, download and fill [this `settings.json` file](https://raw.githubusercontent.com/Arthi-chaud/Meelo/master/settings.json)
All fields are **required**
-`trackRegex`: Probably the most important setting for Meelo. This field takes an array of strings, each string being a Regular Expression string. The RegExp will be used to find the files to import (It will be matched against the **absolute path** of the file). As mentioned before, the path of the file can be used as a metadata source. Therefore, **the Regular Expression accepts groups to find metadata**:
-`AlbumArtist`: The artist of the parent album.
- Special Case: If it equals `Compilations`, related album will be considered as compilation albums (with no main artist, like soundtrack albums)
-`Artist`: The artist of the track. If it is not present, it will use the `AlbumArtist` field.
-`Release`: Usually no present in a standard file architecture; the name of the *release*. When it is not present, the `Album` field will be used.
-`Album`: The name of the album of the material. This field will then be parsed to group related album releases.
-`Year`: The Year of the release of the material
-`Disc`: The Index of the disc the track is on.
-`Index`: The index of the track in a playlist/on a disc.
-`Track`: The name of the track
-`Genre`: The genre of the material
-`DiscogsID`: The Discogs ID of the parent release. A Discogs ID should take the form of a digit-only string. This ID can be found in the URL of the release's Discogs page or in the top-right corner of that page (displayed as `[rXXXXXXXX]`)
- *Note*: **If you do not use embedded data**, most regex groups are optional. Only `Track` and (`AlbumArtist` or `Artist`) are required for the file to be accepted by the scanner.
-`metadata`: Configuration of the **metadata extraction** system:
-`source`: The **primary metadata source** to use:
-`embedded`: Using the embedded tags
-`path`: Using the Regular Expression's groups.
-`order`: Define the missing metadata fallback behaviour. *Note*: if this method is enabled, it will consider 'cover.*' file in the same directory as the media file as an illustration candidate.
-`only`: If a field is missing from the primary metadata source, will not use the other method to get it.
-`preferred`: If a field is missing from the primary metadata source, will try to use the other method to get it.
-`useExternalProviderGenres`: Set to `true` if you want genres from external metadata providers to be used. These genres will be used alongside with embedded genres (if parsing embedded metadata is enabled)
-`providers`: Please refer to [*Providers*](../providers)
-`compilations`:
-`artists`: Optional field. If an album artist in this list, their albums will be considered to be compilation albums.
-`useID3CompTag`: If true, use iTunes' non-standard ID3 tags for compilations.
*Note*: The provided Regular Expression uses the iTunes file architecture.
*Note*: Regular Expression must use the Golang Flavour.
Loaded 100 of 734 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.