diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile new file mode 100644 index 000000000000..2fbd27155881 --- /dev/null +++ b/cross/navidrome/Makefile @@ -0,0 +1,38 @@ +PKG_NAME = navidrome +PKG_VERS = 0.47.5 +PKG_EXT = tar.gz +PKG_DIST_NAME = v$(PKG_VERS).$(PKG_EXT) +PKG_DIST_SITE = https://github.com/navidrome/navidrome/archive +PKG_DIST_FILE = $(PKG_NAME)-$(PKG_VERS).$(PKG_EXT) +PKG_DIR = $(PKG_NAME)-$(PKG_VERS) + +BUILD_DEPENDS = native/go native/nodejs +DEPENDS = cross/taglib + +# C++11 compiler required +UNSUPPORTED_ARCHS = $(ARMv5_ARCHS) +# go does not support ppc archs +UNSUPPORTED_ARCHS += $(PPC_ARCHS) + +HOMEPAGE = https://www.navidrome.org/ +COMMENT = ☁ Modern Music Server and Streamer compatible with Subsonic/Airsonic. +LICENSE = GPL-3.0 License + +PRE_COMPILE_TARGET = navidrome_pre_compile +COMPILE_TARGET = navidrome_compile + +CGO_ENABLED = 1 +GO_BIN_DIR = $(WORK_DIR)/$(PKG_DIR)/$(PKG_NAME) + +include ../../mk/spksrc.cross-go.mk + +ENV += NPM_CONFIG_USER=root +PATH := $(WORK_DIR)/../../../native/nodejs/work-native/node/bin:$(PATH) + +.PHONY: navidrome_pre_compile +navidrome_pre_compile: + @$(RUN) $(MAKE) setup + +.PHONY: navidrome_compile +navidrome_compile: + @$(RUN) $(MAKE) buildall diff --git a/cross/navidrome/PLIST b/cross/navidrome/PLIST new file mode 100644 index 000000000000..4b03eed62d88 --- /dev/null +++ b/cross/navidrome/PLIST @@ -0,0 +1 @@ +bin:bin/navidrome diff --git a/cross/navidrome/digests b/cross/navidrome/digests new file mode 100644 index 000000000000..976579ea35a8 --- /dev/null +++ b/cross/navidrome/digests @@ -0,0 +1,3 @@ +navidrome-0.47.5.tar.gz SHA1 9df716b6ca6f6497fca264f2a40f38d193a9f1b4 +navidrome-0.47.5.tar.gz SHA256 68f9f013d8e17a769770cdd7a1f4d9fc279b3d5e83418bbb54018781de96ab76 +navidrome-0.47.5.tar.gz MD5 5012c0fbd543be2fb044ee688df12b32 diff --git a/cross/navidrome/patches/001-patch_taglib-wrapper-for-older-gcc.patch b/cross/navidrome/patches/001-patch_taglib-wrapper-for-older-gcc.patch new file mode 100644 index 000000000000..6a0dcb337e4e --- /dev/null +++ b/cross/navidrome/patches/001-patch_taglib-wrapper-for-older-gcc.patch @@ -0,0 +1,31 @@ +# fix for older gcc (like 4.9.x) +# - mp3 tags: use explicit type for mp3File->ID3v2Tag()->frameListMap() +# as older gcc cannot dereference std::initializer_list correctly +# - mp4 tags: use mp4File->tag()->item instead of mp4File->tag()->itemMap() to access covers +# as side effect this fixes the build with older gcc +# +--- scanner/metadata/taglib/taglib_wrapper.cpp.orig 2022-01-22 01:35:19.000000000 +0100 ++++ scanner/metadata/taglib/taglib_wrapper.cpp 2022-07-30 13:44:25.711760171 +0200 +@@ -95,7 +95,7 @@ + if (TagLib::MPEG::File * + mp3File{dynamic_cast(f.file())}) { + if (mp3File->ID3v2Tag()) { +- const auto &frameListMap{mp3File->ID3v2Tag()->frameListMap()}; ++ const TagLib::ID3v2::FrameListMap &frameListMap{mp3File->ID3v2Tag()->frameListMap()}; + hasCover = !frameListMap["APIC"].isEmpty(); + } + } +@@ -107,8 +107,11 @@ + // ----- MP4 + else if (TagLib::MP4::File * + mp4File{dynamic_cast(f.file())}) { +- auto &coverItem{mp4File->tag()->itemMap()["covr"]}; +- TagLib::MP4::CoverArtList coverArtList{coverItem.toCoverArtList()}; ++ if (!mp4File->tag()->itemMap().contains("covr")) { ++ return false; ++ } ++ auto const &coverItem = mp4File->tag()->item("covr"); ++ auto const coverArtList = coverItem.toCoverArtList(); + hasCover = !coverArtList.isEmpty(); + } + // ----- Ogg diff --git a/spk/navidrome/Makefile b/spk/navidrome/Makefile new file mode 100644 index 000000000000..155bc43c5281 --- /dev/null +++ b/spk/navidrome/Makefile @@ -0,0 +1,41 @@ +SPK_NAME = navidrome +SPK_VERS = 0.47.5 +SPK_REV = 1 +SPK_ICON = src/navidrome.png + +DEPENDS = cross/navidrome + +# C++11 compiler required +UNSUPPORTED_ARCHS = $(ARMv5_ARCHS) +# go does not support ppc archs +UNSUPPORTED_ARCHS += $(PPC_ARCHS) + +SPK_DEPENDS = "ffmpeg" + +MAINTAINER = hgy59 +HOMEPAGE = https://www.navidrome.org/ +DESCRIPTION = 🎧☁ Modern Music Server and Streamer compatible with Subsonic/Airsonic. It gives you freedom to listen to your music collection from any browser or mobile device. +LICENSE = GPLv3 +DISPLAY_NAME = Navidrome +CHANGELOG = "Initial package release" + +STARTABLE = yes +SERVICE_SETUP = src/service-setup.sh + +SERVICE_USER = auto +SERVICE_PORT = 4533 +SERVICE_PORT_TITLE = Navidrome (HTTP) +ADMIN_PORT = $(SERVICE_PORT) + +WIZARDS_DIR = src/wizard +SERVICE_WIZARD_SHARE = wizard_music_folder +USE_DATA_SHARE_WORKER = yes + +POST_STRIP_TARGET = navidrome_extra_install + +include ../../mk/spksrc.spk.mk + +.PHONY: navidrome_extra_install +navidrome_extra_install: + install -d -m 755 $(STAGING_DIR)/var + install -m 644 src/navidrome.toml $(STAGING_DIR)/var/ diff --git a/spk/navidrome/src/navidrome.png b/spk/navidrome/src/navidrome.png new file mode 100644 index 000000000000..dec48606bc5c Binary files /dev/null and b/spk/navidrome/src/navidrome.png differ diff --git a/spk/navidrome/src/navidrome.toml b/spk/navidrome/src/navidrome.toml new file mode 100644 index 000000000000..2fe6bde828dd --- /dev/null +++ b/spk/navidrome/src/navidrome.toml @@ -0,0 +1,135 @@ +# For all available configuration options see: +# https://www.navidrome.org/docs/usage/configuration-options/#available-options +# For security considerations see: +# https://www.navidrome.org/docs/usage/security/ +# + +# Folder where your music library is stored. Can be read-only +MusicFolder = "@@wizard_music_folder@@" + +# Folder to store application data (DB, cache...) +DataFolder= "/var/packages/navidrome/var" + +# Configure periodic scans using "cron" syntax. To disable it altogether, set it to "0" +# ScanSchedule = "@every 1m" + +# Log level. Useful for troubleshooting. Possible values: error, warn, info, debug, trace +# LogLevel = "info" + +# Whether or not sensitive information (like tokens and passwords) should be redacted (hidden) in the logs +# EnableLogRedacting = true + +# IP address the server will bind to +# Address = 0.0.0.0 + +# Enables transcoding configuration in the UI +# EnableTranscodingConfig = false + +# Size of transcoding cache. Set to "0" to disable cache +# TranscodingCacheSize = "100MB" + +# Size of image (art work) cache. Set to "0" to disable cache +# ImageCacheSize = "100MB" + +# Enable/disable .m3u playlist auto-import +# AutoImportPlaylists = true + +# Where to search for and import playlists from. Can be a list of folders/globs (separated by : ). Paths are relative to MusicFolder +# PlaylistsPath = ".:**/**" # (meaning MusicFolder and all its subfolders)" + +# Base URL (only the path part) to configure Navidrome behind a proxy (ex: /music) +# BaseUrl = "" + +# Change background image used in the Login page +# UILoginBackgroundUrl = "random music image from Unsplash.com" + +# Add a welcome message to the login screen +# UIWelcomeMessage = "" + +# Send basic info to your own Google Analytics account. Must be in the format UA-XXXXXXXX +# GATrackingID = "" + +# Sets the default theme used by the UI when logging in from a new browser. This value must match one of the options in the UI +# DefaultTheme = Dark + +# Controls whether the player in the UI will animate the album cover (rotation) +# EnableCoverAnimation = true + +# List of ignored articles when sorting/indexing artists +# IgnoredArticles = "The El La Los Las Le Les Os As O A Der Die Das" + +# Match query strings anywhere in searchable fields, not only in word boundaries. Useful for languages where words are not space separated +# SearchFullString = false + +# Uses music files' modification time when sorting by "Recently Added". Otherwise use import time +# RecentlyAddedByModTime = false + +# Configure the order to look for cover art images. Use special embedded value to get embedded images from the audio files +# CoverArtPriority = "embedded, cover.*, folder.*, front.*" + +# Set JPEG quality percentage for resized cover art images +# CoverJpegQuality = 75 + +# Enable the option in the UI to download music/albums/artists/playlists from the server +# EnableDownloads = true + +# How long Navidrome will wait before closing web ui idle sessions +# SessionTimeout = "24h" + +# How many login requests can be processed from a single IP during the AuthWindowLength. Set to 0 to disable the limit rater +# AuthRequestLimit = 5 + +# Window Length for the authentication rate limit +# AuthWindowLength = "20s" + +# Select metadata extractor implementation. Options: taglib or ffmpeg +# Scanner.Extractor = "taglib" + +# List of separators to split genre tags +# Scanner.GenreSeparators = ";/," + +# Set this to false to completely disable Last.fm integration +# LastFM.Enabled = true + +# Last.fm ApiKey +# LastFM.ApiKey = "Navidrome project's shared ApiKey" + +# Last.fm Shared Secret +# LastFM.Secret = "Navidrome project's shared Secret" + +# Two letter-code for language to be used to retrieve biographies from Last.fm +# LastFM.Language = "en" + +# Spotify Client ID. Required if you want Artist images +# Spotify.ID = "" + +# Spotify Client Secret. Required if you want Artist images +# Spotify.Secret = "" + +# Set this to false to completely disable ListenBrainz integration +# ListenBrainz.Enabled = true + +# Use Gravatar images as the user profile image. Needs the user's email to be filled +# EnableGravatar = false + +# Set this to false to completely disable ALL external integrations +# EnableExternalServices = true + +# Enable toggling "Heart"/"Loved" for songs/albums/artists in the UI (maps to "Star"/"Starred" in Subsonic Clients) +# EnableFavourites = true + +# Enable 5-star ratings in the UI +# EnableStarRating = true + +# Enable regular users to edit their details and change their password +# EnableUserEditing = true + +# Passphrase used to encrypt passwords in the DB. +# For details see: https://www.navidrome.org/docs/usage/security/#encrypted-passwords) +# PasswordEncryptionKey = "-" + +# HTTP header containing user name from authenticated proxy +# ReverseProxyUserHeader = "Remote-User" + +# Comma separated list of IP CIDRs which are allowed to use reverse proxy authentication, empty means "deny all" +# ReverseProxyWhitelist = "" diff --git a/spk/navidrome/src/service-setup.sh b/spk/navidrome/src/service-setup.sh new file mode 100644 index 000000000000..0583c34c1c73 --- /dev/null +++ b/spk/navidrome/src/service-setup.sh @@ -0,0 +1,15 @@ + +CONFIG_FILE="${SYNOPKG_PKGVAR}/navidrome.toml" +SERVICE_COMMAND="${SYNOPKG_PKGDEST}/bin/navidrome --port ${SERVICE_PORT} --configfile=${CONFIG_FILE}" +SVC_WRITE_PID=y +SVC_BACKGROUND=y + +# navidrome executable does not contain rpath +export LD_LIBRARY_PATH="${SYNOPKG_PKGDEST}/lib" + +service_postinst () +{ + # update config with values from wizard variables + sed -e "s|@@wizard_music_folder@@|${wizard_music_volume}/${wizard_music_folder}|g" \ + -i "${CONFIG_FILE}" +} diff --git a/spk/navidrome/src/wizard/install_uifile b/spk/navidrome/src/wizard/install_uifile new file mode 100644 index 000000000000..924bda2043be --- /dev/null +++ b/spk/navidrome/src/wizard/install_uifile @@ -0,0 +1,57 @@ +[{ + "step_title": "Basic configuration", + "items": [{ + "type": "combobox", + "desc": "Please select a volume to use for the music folder", + "subitems": [{ + "key": "wizard_music_volume", + "desc": "Volume name", + "displayField": "display_name", + "valueField": "volume_path", + "editable": false, + "mode": "remote", + "api_store": { + "api": "SYNO.Core.Storage.Volume", + "method": "list", + "version": 1, + "baseParams": { + "limit": -1, + "offset": 0, + "location": "internal" + }, + "root": "volumes", + "idProperty": "volume_path", + "fields": [ + "display_name", + "volume_path" + ] + }, + "validator": { + "fn": "{console.log(arguments);return true;}" + } + } + ] + }, { + "type": "textfield", + "desc": "Shared music folder. This must be a name for the shared folder only, without any path. This share is created at installation when it does not already exist.", + "subitems": [{ + "key": "wizard_music_folder", + "desc": "Shared music folder", + "defaultValue": "music", + "validator": { + "allowBlank": false, + "regex": { + "expr": "/^[^<>: */?\"]*/", + "errorText": "Share name must be a folder name only. Path separators, spaces and other special chars are not allowed." + } + } + } + ] + }, { + "desc": "" + }, { + "desc": "Navidrome runs as internal service user 'sc-navidrome' in DSM. The shared music folder above is configured at installation time to be accessible by this user.

If you manually change the music folder, make sure 'sc-navidrome' has permissions to access it.

Please read Permission Management for details." + } + ] + } +]