From 55e7e8967c35031349bc62ca97e80facb375cf95 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Sat, 30 Jul 2022 19:46:08 +0200 Subject: [PATCH 01/13] navidrome: initial package release - add navidrome 0.47.5 - patch taglib wrapper c++ code for DSM 6 --- cross/navidrome/Makefile | 38 +++++ cross/navidrome/PLIST | 1 + cross/navidrome/digests | 3 + ...1-patch_taglib-wrapper-for-older-gcc.patch | 31 ++++ spk/navidrome/Makefile | 41 ++++++ spk/navidrome/src/navidrome.png | Bin 0 -> 48861 bytes spk/navidrome/src/navidrome.toml | 135 ++++++++++++++++++ spk/navidrome/src/service-setup.sh | 15 ++ spk/navidrome/src/wizard/install_uifile | 57 ++++++++ 9 files changed, 321 insertions(+) create mode 100644 cross/navidrome/Makefile create mode 100644 cross/navidrome/PLIST create mode 100644 cross/navidrome/digests create mode 100644 cross/navidrome/patches/001-patch_taglib-wrapper-for-older-gcc.patch create mode 100644 spk/navidrome/Makefile create mode 100644 spk/navidrome/src/navidrome.png create mode 100644 spk/navidrome/src/navidrome.toml create mode 100644 spk/navidrome/src/service-setup.sh create mode 100644 spk/navidrome/src/wizard/install_uifile diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile new file mode 100644 index 00000000000..2fbd2715588 --- /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 00000000000..4b03eed62d8 --- /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 00000000000..976579ea35a --- /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 00000000000..6a0dcb337e4 --- /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 00000000000..155bc43c528 --- /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 0000000000000000000000000000000000000000..dec48606bc5cbeced026b7645da3c6951126cdc3 GIT binary patch literal 48861 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 Ee_i=yJ^%m! literal 0 HcmV?d00001 diff --git a/spk/navidrome/src/navidrome.toml b/spk/navidrome/src/navidrome.toml new file mode 100644 index 00000000000..2fe6bde828d --- /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 00000000000..0583c34c1c7 --- /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 00000000000..924bda2043b --- /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." + } + ] + } +] From 8c2b02dea930a763a4feabf593ae0d8e8e0d12cf Mon Sep 17 00:00:00 2001 From: hgy59 Date: Mon, 1 Aug 2022 12:57:33 +0200 Subject: [PATCH 02/13] update taglib_wrapper patch --- ...001-patch_taglib-wrapper-for-older-gcc.patch | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) 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 index 6a0dcb337e4..c7b8a3814b7 100644 --- a/cross/navidrome/patches/001-patch_taglib-wrapper-for-older-gcc.patch +++ b/cross/navidrome/patches/001-patch_taglib-wrapper-for-older-gcc.patch @@ -4,8 +4,8 @@ # - 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 +--- scanner/metadata/taglib/taglib_wrapper.cpp.orig 2022-01-22 00:35:19.000000000 +0000 ++++ scanner/metadata/taglib/taglib_wrapper.cpp 2022-07-30 20:04:45.252885556 +0000 @@ -95,7 +95,7 @@ if (TagLib::MPEG::File * mp3File{dynamic_cast(f.file())}) { @@ -15,17 +15,18 @@ hasCover = !frameListMap["APIC"].isEmpty(); } } -@@ -107,8 +107,11 @@ +@@ -107,9 +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; +- hasCover = !coverArtList.isEmpty(); ++ if (mp4File->tag()->itemMap().contains("covr")) { ++ auto const &coverItem = mp4File->tag()->item("covr"); ++ auto const coverArtList = coverItem.toCoverArtList(); ++ hasCover = !coverArtList.isEmpty(); + } -+ auto const &coverItem = mp4File->tag()->item("covr"); -+ auto const coverArtList = coverItem.toCoverArtList(); - hasCover = !coverArtList.isEmpty(); } // ----- Ogg + else if (TagLib::Ogg::Vorbis::File * From f6b03a7ec5c52b92639c36941c1a305162ab50f8 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Fri, 7 Apr 2023 21:40:08 +0200 Subject: [PATCH 03/13] update taglib to v1.13 --- cross/taglib/Makefile | 3 ++- cross/taglib/PLIST | 2 +- cross/taglib/digests | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/cross/taglib/Makefile b/cross/taglib/Makefile index 5534ed89eac..30bd0c3c76f 100644 --- a/cross/taglib/Makefile +++ b/cross/taglib/Makefile @@ -1,5 +1,5 @@ PKG_NAME = taglib -PKG_VERS = 1.12 +PKG_VERS = 1.13 PKG_EXT = tar.gz PKG_DIST_NAME = $(PKG_NAME)-$(PKG_VERS).$(PKG_EXT) PKG_DIST_SITE = https://taglib.org/releases @@ -14,5 +14,6 @@ LICENSE = LGPLv2.1 GNU_CONFIGURE = 1 CMAKE_ARGS += -DBUILD_SHARED_LIBS=ON CMAKE_ARGS += -Wno-dev +ADDITIONAL_CXXFLAGS = -Wno-deprecated-declarations -Wno-sign-compare include ../../mk/spksrc.cross-cmake.mk diff --git a/cross/taglib/PLIST b/cross/taglib/PLIST index e7fb16499e1..324c5821659 100644 --- a/cross/taglib/PLIST +++ b/cross/taglib/PLIST @@ -1,7 +1,7 @@ rsc:bin/taglib-config lnk:lib/libtag.so lnk:lib/libtag.so.1 -lib:lib/libtag.so.1.18.0 +lib:lib/libtag.so.1.19.0 lnk:lib/libtag_c.so lnk:lib/libtag_c.so.0 lib:lib/libtag_c.so.0.0.0 diff --git a/cross/taglib/digests b/cross/taglib/digests index f809fee6bb0..0b1c179fbd9 100644 --- a/cross/taglib/digests +++ b/cross/taglib/digests @@ -1,3 +1,3 @@ -taglib-1.12.tar.gz SHA1 c06c44223f64ef61d29372659059d6b9e27c2efd -taglib-1.12.tar.gz SHA256 7fccd07669a523b07a15bd24c8da1bbb92206cb19e9366c3692af3d79253b703 -taglib-1.12.tar.gz MD5 4313ed2671234e029b7af8f97c84e9af +taglib-1.13.tar.gz SHA1 e68319d1ac8fcf7fd68697c6d08427d847b5ebb3 +taglib-1.13.tar.gz SHA256 58f08b4db3dc31ed152c04896ee9172d22052bc7ef12888028c01d8b1d60ade0 +taglib-1.13.tar.gz MD5 0b75619b67b9149cfcbbe5c127df6395 From ddd5033c07d71a377d142ba5e04d95f6afa13969 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Fri, 7 Apr 2023 21:41:36 +0200 Subject: [PATCH 04/13] navidrome: update to v0.49.3 and fix for native/nodejs v18 --- cross/navidrome/Makefile | 7 +++++-- cross/navidrome/digests | 6 +++--- spk/navidrome/Makefile | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile index 2fbd2715588..107384c1955 100644 --- a/cross/navidrome/Makefile +++ b/cross/navidrome/Makefile @@ -1,5 +1,5 @@ PKG_NAME = navidrome -PKG_VERS = 0.47.5 +PKG_VERS = 0.49.3 PKG_EXT = tar.gz PKG_DIST_NAME = v$(PKG_VERS).$(PKG_EXT) PKG_DIST_SITE = https://github.com/navidrome/navidrome/archive @@ -15,7 +15,7 @@ UNSUPPORTED_ARCHS = $(ARMv5_ARCHS) UNSUPPORTED_ARCHS += $(PPC_ARCHS) HOMEPAGE = https://www.navidrome.org/ -COMMENT = ☁ Modern Music Server and Streamer compatible with Subsonic/Airsonic. +COMMENT = ����☁ Modern Music Server and Streamer compatible with Subsonic/Airsonic. LICENSE = GPL-3.0 License PRE_COMPILE_TARGET = navidrome_pre_compile @@ -29,6 +29,9 @@ include ../../mk/spksrc.cross-go.mk ENV += NPM_CONFIG_USER=root PATH := $(WORK_DIR)/../../../native/nodejs/work-native/node/bin:$(PATH) +# avoid webpack error ERR_OSSL_EVP_UNSUPPORTED with nodejs v18 +ENV += NODE_OPTIONS=--openssl-legacy-provider + .PHONY: navidrome_pre_compile navidrome_pre_compile: @$(RUN) $(MAKE) setup diff --git a/cross/navidrome/digests b/cross/navidrome/digests index 976579ea35a..d6639d85343 100644 --- a/cross/navidrome/digests +++ b/cross/navidrome/digests @@ -1,3 +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 +navidrome-0.49.3.tar.gz SHA1 b34029e626886432786291d13594ad0dcfb16e86 +navidrome-0.49.3.tar.gz SHA256 ab48eadeb74f64456b612655941bac4eb95a0f546bfee473baa316319fb4a17a +navidrome-0.49.3.tar.gz MD5 bad6015f46be2d39e570499fbd67a803 diff --git a/spk/navidrome/Makefile b/spk/navidrome/Makefile index 155bc43c528..a4850d9eaf5 100644 --- a/spk/navidrome/Makefile +++ b/spk/navidrome/Makefile @@ -1,5 +1,5 @@ SPK_NAME = navidrome -SPK_VERS = 0.47.5 +SPK_VERS = 0.49.3 SPK_REV = 1 SPK_ICON = src/navidrome.png From 34be67de68edcb8860297130ba49c3ffb9b79331 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Mon, 22 Jan 2024 23:07:16 +0100 Subject: [PATCH 05/13] taglib: update to v1.13.1 --- cross/taglib/Makefile | 2 +- cross/taglib/PLIST | 3 +-- cross/taglib/digests | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cross/taglib/Makefile b/cross/taglib/Makefile index 30bd0c3c76f..8efa31ef30e 100644 --- a/cross/taglib/Makefile +++ b/cross/taglib/Makefile @@ -1,5 +1,5 @@ PKG_NAME = taglib -PKG_VERS = 1.13 +PKG_VERS = 1.13.1 PKG_EXT = tar.gz PKG_DIST_NAME = $(PKG_NAME)-$(PKG_VERS).$(PKG_EXT) PKG_DIST_SITE = https://taglib.org/releases diff --git a/cross/taglib/PLIST b/cross/taglib/PLIST index 324c5821659..126246e1e69 100644 --- a/cross/taglib/PLIST +++ b/cross/taglib/PLIST @@ -1,7 +1,6 @@ -rsc:bin/taglib-config lnk:lib/libtag.so lnk:lib/libtag.so.1 -lib:lib/libtag.so.1.19.0 +lib:lib/libtag.so.1.19.1 lnk:lib/libtag_c.so lnk:lib/libtag_c.so.0 lib:lib/libtag_c.so.0.0.0 diff --git a/cross/taglib/digests b/cross/taglib/digests index 0b1c179fbd9..0c45e7deb08 100644 --- a/cross/taglib/digests +++ b/cross/taglib/digests @@ -1,3 +1,3 @@ -taglib-1.13.tar.gz SHA1 e68319d1ac8fcf7fd68697c6d08427d847b5ebb3 -taglib-1.13.tar.gz SHA256 58f08b4db3dc31ed152c04896ee9172d22052bc7ef12888028c01d8b1d60ade0 -taglib-1.13.tar.gz MD5 0b75619b67b9149cfcbbe5c127df6395 +taglib-1.13.1.tar.gz SHA1 33325da48456d13c45fed7f772020f655bd1acca +taglib-1.13.1.tar.gz SHA256 c8da2b10f1bfec2cd7dbfcd33f4a2338db0765d851a50583d410bacf055cfd0b +taglib-1.13.1.tar.gz MD5 2fe6089da73ad414aa1b982b83415362 From 4bbd0edd08140ba5cc412173845b56687f08d687 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Mon, 22 Jan 2024 23:08:45 +0100 Subject: [PATCH 06/13] navidrome: update to v 0.51.0 - update navidrom to v 0.51.0 - use new shared folder handling --- cross/navidrome/Makefile | 10 ++----- cross/navidrome/digests | 6 ++-- spk/navidrome/Makefile | 5 ++-- spk/navidrome/src/service-setup.sh | 2 +- spk/navidrome/src/wizard/install_uifile | 39 +++---------------------- 5 files changed, 13 insertions(+), 49 deletions(-) diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile index 107384c1955..e2c53f28b3b 100644 --- a/cross/navidrome/Makefile +++ b/cross/navidrome/Makefile @@ -1,5 +1,5 @@ PKG_NAME = navidrome -PKG_VERS = 0.49.3 +PKG_VERS = 0.51.0 PKG_EXT = tar.gz PKG_DIST_NAME = v$(PKG_VERS).$(PKG_EXT) PKG_DIST_SITE = https://github.com/navidrome/navidrome/archive @@ -19,7 +19,7 @@ COMMENT = ����☁ Modern Music Server and Streamer compatible with Subs LICENSE = GPL-3.0 License PRE_COMPILE_TARGET = navidrome_pre_compile -COMPILE_TARGET = navidrome_compile +COMPILE_MAKE_OPTIONS = buildall CGO_ENABLED = 1 GO_BIN_DIR = $(WORK_DIR)/$(PKG_DIR)/$(PKG_NAME) @@ -27,7 +27,7 @@ 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) +PATH := $(abspath $(WORK_DIR)/../../../native/nodejs/work-native/node/bin):$(PATH) # avoid webpack error ERR_OSSL_EVP_UNSUPPORTED with nodejs v18 ENV += NODE_OPTIONS=--openssl-legacy-provider @@ -35,7 +35,3 @@ ENV += NODE_OPTIONS=--openssl-legacy-provider .PHONY: navidrome_pre_compile navidrome_pre_compile: @$(RUN) $(MAKE) setup - -.PHONY: navidrome_compile -navidrome_compile: - @$(RUN) $(MAKE) buildall diff --git a/cross/navidrome/digests b/cross/navidrome/digests index d6639d85343..05d77906c5a 100644 --- a/cross/navidrome/digests +++ b/cross/navidrome/digests @@ -1,3 +1,3 @@ -navidrome-0.49.3.tar.gz SHA1 b34029e626886432786291d13594ad0dcfb16e86 -navidrome-0.49.3.tar.gz SHA256 ab48eadeb74f64456b612655941bac4eb95a0f546bfee473baa316319fb4a17a -navidrome-0.49.3.tar.gz MD5 bad6015f46be2d39e570499fbd67a803 +navidrome-0.51.0.tar.gz SHA1 374446a1c7420cc4e1fc38876963548252dd29e5 +navidrome-0.51.0.tar.gz SHA256 0f744b60c0a012c9e89e71dd1849cb342c7677ec9862ab3a75d5fdbf83b7bfbf +navidrome-0.51.0.tar.gz MD5 71a677edf8fc16641153aa42e3f23727 diff --git a/spk/navidrome/Makefile b/spk/navidrome/Makefile index a4850d9eaf5..e578f3a0c8f 100644 --- a/spk/navidrome/Makefile +++ b/spk/navidrome/Makefile @@ -1,5 +1,5 @@ SPK_NAME = navidrome -SPK_VERS = 0.49.3 +SPK_VERS = 0.51.0 SPK_REV = 1 SPK_ICON = src/navidrome.png @@ -28,8 +28,7 @@ SERVICE_PORT_TITLE = Navidrome (HTTP) ADMIN_PORT = $(SERVICE_PORT) WIZARDS_DIR = src/wizard -SERVICE_WIZARD_SHARE = wizard_music_folder -USE_DATA_SHARE_WORKER = yes +SERVICE_WIZARD_SHARENAME = wizard_music_folder POST_STRIP_TARGET = navidrome_extra_install diff --git a/spk/navidrome/src/service-setup.sh b/spk/navidrome/src/service-setup.sh index 0583c34c1c7..ee32310db25 100644 --- a/spk/navidrome/src/service-setup.sh +++ b/spk/navidrome/src/service-setup.sh @@ -10,6 +10,6 @@ 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" \ + sed -e "s|@@wizard_music_folder@@|${SHARE_PATH}|g" \ -i "${CONFIG_FILE}" } diff --git a/spk/navidrome/src/wizard/install_uifile b/spk/navidrome/src/wizard/install_uifile index 924bda2043b..d1fa20df0f1 100644 --- a/spk/navidrome/src/wizard/install_uifile +++ b/spk/navidrome/src/wizard/install_uifile @@ -1,37 +1,7 @@ [{ - "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;}" - } - } - ] - }, { + "step_title": "Basic configuration", + "items": [ + { "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": [{ @@ -53,5 +23,4 @@ "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." } ] - } -] +}] From 090cbf607a370f9c6ee821e4fa2c79a6b0c9c964 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Wed, 24 Jan 2024 20:47:03 +0100 Subject: [PATCH 07/13] add workaround to build and include the frontend --- cross/navidrome/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile index e2c53f28b3b..fa2b0e93fcc 100644 --- a/cross/navidrome/Makefile +++ b/cross/navidrome/Makefile @@ -15,7 +15,7 @@ UNSUPPORTED_ARCHS = $(ARMv5_ARCHS) UNSUPPORTED_ARCHS += $(PPC_ARCHS) HOMEPAGE = https://www.navidrome.org/ -COMMENT = ����☁ Modern Music Server and Streamer compatible with Subsonic/Airsonic. +COMMENT = ☁ Modern Music Server and Streamer compatible with Subsonic/Airsonic. LICENSE = GPL-3.0 License PRE_COMPILE_TARGET = navidrome_pre_compile @@ -27,11 +27,14 @@ GO_BIN_DIR = $(WORK_DIR)/$(PKG_DIR)/$(PKG_NAME) include ../../mk/spksrc.cross-go.mk ENV += NPM_CONFIG_USER=root -PATH := $(abspath $(WORK_DIR)/../../../native/nodejs/work-native/node/bin):$(PATH) +PATH := $(WORK_DIR)/../../../native/nodejs/work-native/node/bin:$(PATH) # avoid webpack error ERR_OSSL_EVP_UNSUPPORTED with nodejs v18 ENV += NODE_OPTIONS=--openssl-legacy-provider .PHONY: navidrome_pre_compile navidrome_pre_compile: + @$(MSG) Prepare Navidrom build with "make setup" @$(RUN) $(MAKE) setup + @$(MSG) Prepare Navidrom build with "make buildjs" + @$(RUN) $(MAKE) buildjs From 48d90be01b5e9bf7a0f4bcb09e985418621c895e Mon Sep 17 00:00:00 2001 From: hgy59 Date: Wed, 24 Jan 2024 21:33:44 +0100 Subject: [PATCH 08/13] fix frontend build --- cross/navidrome/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile index fa2b0e93fcc..85884970384 100644 --- a/cross/navidrome/Makefile +++ b/cross/navidrome/Makefile @@ -24,6 +24,12 @@ COMPILE_MAKE_OPTIONS = buildall CGO_ENABLED = 1 GO_BIN_DIR = $(WORK_DIR)/$(PKG_DIR)/$(PKG_NAME) +# with parallel make, sometimes the frontent build (make buildjs) fails with: +# # github.com/navidrome/navidrome/ui +# ui/embed.go:9:5: embed build/asset-manifest.json: open ui/build/asset-manifest.json: no such file or directory +# ui/embed.go:9:5: embed build/index.html: open ui/build/index.html: no such file or directory +.NOTPARALLEL: + include ../../mk/spksrc.cross-go.mk ENV += NPM_CONFIG_USER=root @@ -33,6 +39,8 @@ PATH := $(WORK_DIR)/../../../native/nodejs/work-native/node/bin:$(PATH) ENV += NODE_OPTIONS=--openssl-legacy-provider .PHONY: navidrome_pre_compile +# without "make buildjs" make buildall has warning: +# WARNING: This command does not build the frontend, it uses the latest built with 'make buildjs' navidrome_pre_compile: @$(MSG) Prepare Navidrom build with "make setup" @$(RUN) $(MAKE) setup From 5c1a5df33ab4c79d9c4386f4613f9c211cd3d494 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Thu, 25 Jan 2024 03:43:24 +0100 Subject: [PATCH 09/13] split "make buildall" into "make buildjs" and "make build" --- cross/navidrome/Makefile | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile index 85884970384..7c7a263f708 100644 --- a/cross/navidrome/Makefile +++ b/cross/navidrome/Makefile @@ -15,11 +15,10 @@ UNSUPPORTED_ARCHS = $(ARMv5_ARCHS) UNSUPPORTED_ARCHS += $(PPC_ARCHS) HOMEPAGE = https://www.navidrome.org/ -COMMENT = ☁ Modern Music Server and Streamer compatible with Subsonic/Airsonic. +COMMENT = 🎧☁ Modern Music Server and Streamer compatible with Subsonic/Airsonic. LICENSE = GPL-3.0 License -PRE_COMPILE_TARGET = navidrome_pre_compile -COMPILE_MAKE_OPTIONS = buildall +COMPILE_TARGET = navidrome_compile CGO_ENABLED = 1 GO_BIN_DIR = $(WORK_DIR)/$(PKG_DIR)/$(PKG_NAME) @@ -35,14 +34,14 @@ include ../../mk/spksrc.cross-go.mk ENV += NPM_CONFIG_USER=root PATH := $(WORK_DIR)/../../../native/nodejs/work-native/node/bin:$(PATH) -# avoid webpack error ERR_OSSL_EVP_UNSUPPORTED with nodejs v18 -ENV += NODE_OPTIONS=--openssl-legacy-provider - -.PHONY: navidrome_pre_compile +.PHONY: navidrome_compile # without "make buildjs" make buildall has warning: # WARNING: This command does not build the frontend, it uses the latest built with 'make buildjs' -navidrome_pre_compile: - @$(MSG) Prepare Navidrom build with "make setup" +# therefore split "make buildall" into "make buildjs" and "make build" +navidrome_compile: + @$(MSG) "### Navidrom build prepare (make setup)" @$(RUN) $(MAKE) setup - @$(MSG) Prepare Navidrom build with "make buildjs" + @$(MSG) "### Navidrom build frontend (make buildjs)" @$(RUN) $(MAKE) buildjs + @$(MSG) "### Navidrom build application (make build)" + @$(RUN) $(MAKE) build From 92d90719aaee369490e01b670aa6fc6868e5109b Mon Sep 17 00:00:00 2001 From: hgy59 Date: Tue, 2 Apr 2024 23:32:56 +0200 Subject: [PATCH 10/13] update navidrome and native/nodejs - update navidrome to v0.51.1 - update native/nodejs to v18.20.0 --- cross/navidrome/Makefile | 2 +- cross/navidrome/digests | 6 +++--- native/nodejs/Makefile | 2 +- native/nodejs/digests | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile index 7c7a263f708..5f191e7c498 100644 --- a/cross/navidrome/Makefile +++ b/cross/navidrome/Makefile @@ -1,5 +1,5 @@ PKG_NAME = navidrome -PKG_VERS = 0.51.0 +PKG_VERS = 0.51.1 PKG_EXT = tar.gz PKG_DIST_NAME = v$(PKG_VERS).$(PKG_EXT) PKG_DIST_SITE = https://github.com/navidrome/navidrome/archive diff --git a/cross/navidrome/digests b/cross/navidrome/digests index 05d77906c5a..2481350e377 100644 --- a/cross/navidrome/digests +++ b/cross/navidrome/digests @@ -1,3 +1,3 @@ -navidrome-0.51.0.tar.gz SHA1 374446a1c7420cc4e1fc38876963548252dd29e5 -navidrome-0.51.0.tar.gz SHA256 0f744b60c0a012c9e89e71dd1849cb342c7677ec9862ab3a75d5fdbf83b7bfbf -navidrome-0.51.0.tar.gz MD5 71a677edf8fc16641153aa42e3f23727 +navidrome-0.51.1.tar.gz SHA1 a4f327e122c303412d088627e6832ac131f2559f +navidrome-0.51.1.tar.gz SHA256 fc962e3acbedfad63934eda016d4e380dd3a06b4636f2b1e61ade9700a2addcd +navidrome-0.51.1.tar.gz MD5 4a464cda00f194a138f534fe69c4d4e3 diff --git a/native/nodejs/Makefile b/native/nodejs/Makefile index 24425d81c5b..211b1e740d7 100644 --- a/native/nodejs/Makefile +++ b/native/nodejs/Makefile @@ -1,7 +1,7 @@ PKG_NAME = nodejs # https://nodejs.org/en/about/releases/ # v18 is active LTS Version "Hydrogen" from 2022-10-25 to 2023-10-18 with EOL at 2025-04-30 -PKG_VERS = 18.15.0 +PKG_VERS = 18.20.0 PKG_EXT = tar.xz PKG_DIST_NAME = node-v$(PKG_VERS)-linux-x64.$(PKG_EXT) PKG_DIST_SITE = https://nodejs.org/dist/v$(PKG_VERS) diff --git a/native/nodejs/digests b/native/nodejs/digests index 8cebd05d136..4e0ebd6b4eb 100644 --- a/native/nodejs/digests +++ b/native/nodejs/digests @@ -1,3 +1,3 @@ -node-v18.15.0-linux-x64.tar.xz SHA1 d48194e3dda2794f9031963cfeea30f51c70059b -node-v18.15.0-linux-x64.tar.xz SHA256 c8c5fa53ce0c0f248e45983e86368e0b1daf84b77e88b310f769c3cfc12682ef -node-v18.15.0-linux-x64.tar.xz MD5 bd769e5856565976fbea53d9720e51a3 +node-v18.20.0-linux-x64.tar.xz SHA1 8d67b84fcf19a5830f0acc95873da8579019dead +node-v18.20.0-linux-x64.tar.xz SHA256 03eea148e56785babb27930b05ed6bf311aaa3bc573c0399dd63cad2fe5713c7 +node-v18.20.0-linux-x64.tar.xz MD5 23ab56b824d15ffd1d022bb5e2abc7ec From 3713c978cd1e9335b7d742fb32072daa81e14a65 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Wed, 3 Apr 2024 00:19:43 +0200 Subject: [PATCH 11/13] update version in spk/navidrome/Makefile --- spk/navidrome/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spk/navidrome/Makefile b/spk/navidrome/Makefile index e578f3a0c8f..67bc9be6ec7 100644 --- a/spk/navidrome/Makefile +++ b/spk/navidrome/Makefile @@ -1,5 +1,5 @@ SPK_NAME = navidrome -SPK_VERS = 0.51.0 +SPK_VERS = 0.51.1 SPK_REV = 1 SPK_ICON = src/navidrome.png From d66b4c3b48424697955d0f265476fcbdbcc7e1c1 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Tue, 9 Jul 2024 23:25:55 +0200 Subject: [PATCH 12/13] navidrome: update to v0.52.5 - update navidrome to v0.52.5 - remove ffmpeg package dependency --- cross/navidrome/Makefile | 2 +- cross/navidrome/digests | 6 +++--- spk/navidrome/Makefile | 4 +--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile index 5f191e7c498..5dbfb565127 100644 --- a/cross/navidrome/Makefile +++ b/cross/navidrome/Makefile @@ -1,5 +1,5 @@ PKG_NAME = navidrome -PKG_VERS = 0.51.1 +PKG_VERS = 0.52.5 PKG_EXT = tar.gz PKG_DIST_NAME = v$(PKG_VERS).$(PKG_EXT) PKG_DIST_SITE = https://github.com/navidrome/navidrome/archive diff --git a/cross/navidrome/digests b/cross/navidrome/digests index 2481350e377..16c829834f0 100644 --- a/cross/navidrome/digests +++ b/cross/navidrome/digests @@ -1,3 +1,3 @@ -navidrome-0.51.1.tar.gz SHA1 a4f327e122c303412d088627e6832ac131f2559f -navidrome-0.51.1.tar.gz SHA256 fc962e3acbedfad63934eda016d4e380dd3a06b4636f2b1e61ade9700a2addcd -navidrome-0.51.1.tar.gz MD5 4a464cda00f194a138f534fe69c4d4e3 +navidrome-0.52.5.tar.gz SHA1 384b0d5cf555ca1c345eef9a6ebb4c8ae839a65a +navidrome-0.52.5.tar.gz SHA256 9e5a81589d3e0c04d8cd06dccc680942d082f3d02aa4f0fd2b67dedf9902063b +navidrome-0.52.5.tar.gz MD5 1770e27e8760f465cc6bc1c484f924b5 diff --git a/spk/navidrome/Makefile b/spk/navidrome/Makefile index 67bc9be6ec7..db032fea60d 100644 --- a/spk/navidrome/Makefile +++ b/spk/navidrome/Makefile @@ -1,5 +1,5 @@ SPK_NAME = navidrome -SPK_VERS = 0.51.1 +SPK_VERS = 0.52.5 SPK_REV = 1 SPK_ICON = src/navidrome.png @@ -10,8 +10,6 @@ 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. From e49d21788dd26b4cae331406051f2277b769efd8 Mon Sep 17 00:00:00 2001 From: hgy59 Date: Thu, 31 Oct 2024 23:59:10 +0100 Subject: [PATCH 13/13] navidrome: update to v0.53.3 --- cross/navidrome/Makefile | 2 +- cross/navidrome/digests | 6 +++--- spk/navidrome/Makefile | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cross/navidrome/Makefile b/cross/navidrome/Makefile index 5dbfb565127..ded480f8185 100644 --- a/cross/navidrome/Makefile +++ b/cross/navidrome/Makefile @@ -1,5 +1,5 @@ PKG_NAME = navidrome -PKG_VERS = 0.52.5 +PKG_VERS = 0.53.3 PKG_EXT = tar.gz PKG_DIST_NAME = v$(PKG_VERS).$(PKG_EXT) PKG_DIST_SITE = https://github.com/navidrome/navidrome/archive diff --git a/cross/navidrome/digests b/cross/navidrome/digests index 16c829834f0..1f8e8fd32b4 100644 --- a/cross/navidrome/digests +++ b/cross/navidrome/digests @@ -1,3 +1,3 @@ -navidrome-0.52.5.tar.gz SHA1 384b0d5cf555ca1c345eef9a6ebb4c8ae839a65a -navidrome-0.52.5.tar.gz SHA256 9e5a81589d3e0c04d8cd06dccc680942d082f3d02aa4f0fd2b67dedf9902063b -navidrome-0.52.5.tar.gz MD5 1770e27e8760f465cc6bc1c484f924b5 +navidrome-0.53.3.tar.gz SHA1 62f402fab156aa03e09be382688899bad79c4910 +navidrome-0.53.3.tar.gz SHA256 e0d5b0280c302938177b2241a5f9868a4b40cd603ddf5acb2ff0f9c40e44c13a +navidrome-0.53.3.tar.gz MD5 cb7ead899f64dca6526441e8ccd72e47 diff --git a/spk/navidrome/Makefile b/spk/navidrome/Makefile index db032fea60d..0bc09e09a04 100644 --- a/spk/navidrome/Makefile +++ b/spk/navidrome/Makefile @@ -1,5 +1,5 @@ SPK_NAME = navidrome -SPK_VERS = 0.52.5 +SPK_VERS = 0.53.3 SPK_REV = 1 SPK_ICON = src/navidrome.png