Skip to content

Commit dd1a080

Browse files
committed
Merge branch 'develop' for release v3.63.0
2 parents 9ba7966 + 5b73925 commit dd1a080

File tree

117 files changed

+1773
-451
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+1773
-451
lines changed

Dockerfile-release

+11-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM alpine:3.19 AS build
1+
FROM alpine:3.20 AS build
22

33
WORKDIR /tmp/workdir
44

@@ -56,8 +56,8 @@ RUN \
5656
--disable-postproc \
5757
--disable-pixelutils \
5858
--disable-network \
59-
--enable-shared \
60-
--disable-static \
59+
--disable-shared \
60+
--enable-static \
6161
--enable-gpl \
6262
--enable-small \
6363
--enable-version3 \
@@ -73,26 +73,27 @@ RUN \
7373
--enable-muxer=ogg,matroska,mp3,webm \
7474
--enable-protocol=file,pipe \
7575
--enable-filter=aresample \
76+
--enable-lto \
7677
--extra-libs=-ldl && \
7778
make -j$(nproc) && \
7879
make install && \
7980
make distclean
8081

8182
# WT
82-
ARG WT_VERSION=4.10.4
83+
ARG WT_VERSION=4.11.1
8384
RUN \
8485
DIR=/tmp/wt && mkdir -p ${DIR} && cd ${DIR} && \
8586
curl -sLO https://github.com/emweb/wt/archive/${WT_VERSION}.tar.gz && \
8687
tar -x --strip-components=1 -f ${WT_VERSION}.tar.gz
8788

8889
RUN \
8990
DIR=/tmp/wt && mkdir -p ${DIR} && cd ${DIR} && \
90-
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} -DBUILD_EXAMPLES=OFF -DENABLE_LIBWTTEST=OFF -DCONNECTOR_FCGI=OFF -DUSE_SYSTEM_SQLITE3=ON && \
91+
cmake -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=TRUE -DSHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} -DBUILD_EXAMPLES=OFF -DENABLE_LIBWTTEST=OFF -DCONNECTOR_FCGI=OFF -DUSE_SYSTEM_SQLITE3=ON && \
9192
make -j$(nproc) && \
9293
make install
9394

9495
# STB
95-
ARG STB_VERSION=ae721c50eaf761660b4f90cc590453cdb0c2acd0
96+
ARG STB_VERSION=5c205738c191bcb0abc65c4febfa9bd25ff35234
9697
RUN \
9798
DIR=/tmp/stb && mkdir -p ${DIR} && cd ${DIR} && \
9899
curl -sLO https://github.com/nothings/stb/archive/${STB_VERSION}.tar.gz && \
@@ -101,23 +102,23 @@ RUN \
101102
cp ./*.h ${PREFIX}/include/stb
102103

103104
# TAGLIB
104-
ARG TAGLIB_VERSION=v2.0.1
105+
ARG TAGLIB_VERSION=v2.0.2
105106
RUN \
106107
DIR=/tmp/taglib && mkdir -p ${DIR} && cd ${DIR} && \
107108
curl -sLO https://github.com/taglib/taglib/archive/${TAGLIB_VERSION}.tar.gz && \
108109
tar -x --strip-components=1 -f ${TAGLIB_VERSION}.tar.gz
109110

110111
RUN \
111112
DIR=/tmp/taglib && mkdir -p ${DIR} && cd ${DIR} && \
112-
CXXFLAGS="-I/usr/include/utf8cpp" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} -DBUILD_SHARED_LIBS=ON -DBUILD_EXAMPLES=OFF -DBUILD_BINDINGS=OFF -DBUILD_TESTING=OFF -DTRACE_IN_RELEASE=OFF -DWITH_ZLIB=ON && \
113+
CXXFLAGS="-I/usr/include/utf8cpp" cmake -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=TRUE -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} -DBUILD_SHARED_LIBS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_BINDINGS=OFF -DBUILD_TESTING=OFF -DTRACE_IN_RELEASE=OFF -DWITH_ZLIB=ON && \
113114
make -j$(nproc) && \
114115
make install
115116

116117
# LMS
117118
COPY . /tmp/lms/
118119
RUN \
119120
DIR=/tmp/lms/build && mkdir -p ${DIR} && cd ${DIR} && \
120-
PKG_CONFIG_PATH=/tmp/install/lib/pkgconfig CXXFLAGS="-I${PREFIX}/include" LDFLAGS="-L${PREFIX}/lib -Wl,--rpath-link=${PREFIX}/lib" cmake /tmp/lms/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} && \
121+
PKG_CONFIG_PATH=/tmp/install/lib/pkgconfig CXXFLAGS="-I${PREFIX}/include" LDFLAGS="-L${PREFIX}/lib -Wl,--rpath-link=${PREFIX}/lib" cmake /tmp/lms/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=TRUE -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} && \
121122
LD_LIBRARY_PATH=${PREFIX}/lib make -j$(nproc) && \
122123
LD_LIBRARY_PATH=${PREFIX}/lib make test && \
123124
make install && \
@@ -132,11 +133,6 @@ RUN \
132133
strip --strip-all $bin && \
133134
cp $bin /tmp/fakeroot/bin/; \
134135
done && \
135-
for lib in ${PREFIX}/lib/*.so; \
136-
do \
137-
strip --strip-all $lib; \
138-
done && \
139-
cp -r ${PREFIX}/lib /tmp/fakeroot/lib && \
140136
cp -r ${PREFIX}/share /tmp/fakeroot/share && \
141137
rm -rf /tmp/fakeroot/share/doc && \
142138
rm -rf /tmp/fakeroot/share/man
@@ -147,7 +143,7 @@ RUN \
147143
rm -rf /tmp/fakeroot/share/Wt/resources/themes
148144

149145
## Release Stage
150-
FROM alpine:3.19 AS release
146+
FROM alpine:3.20 AS release
151147
LABEL maintainer="Emeric Poupon <[email protected]>"
152148

153149
ARG RUNTIME_PACKAGES=" \

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,15 @@ $setmulti(albumartistssort,%_albumartists_sort%)
6363
_LMS_ supports playlist files in `m3u` and `m3u8` formats. These playlists are synced during the scan process and are available as public shared playlists.
6464

6565
## Lyrics support
66-
_LMS_ supports lyrics in `lrc` files and embedded track metadata. Both synchronized and unsynchronized lyrics are supported.
66+
_LMS_ supports lyrics in `lrc` files, `txt` files, and embedded track metadata. Both synchronized and unsynchronized lyrics are supported.
6767

6868
## Keyboard shortcuts
6969
* Play/pause: <kbd>Space</kbd>
7070
* Previous track: <kbd>Ctrl</kbd> + <kbd>Left</kbd>
7171
* Next track: <kbd>Ctrl</kbd> + <kbd>Right</kbd>
72+
* Decrease volume: <kbd>Ctrl</kbd> + <kbd>Down</kbd>
73+
* Increase volume: <kbd>Ctrl</kbd> + <kbd>Up</kbd>
74+
7275

7376
## Installation
7477
See [INSTALL.md](INSTALL.md) file.

approot/admin-scansettings.xml

+23-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<!--FORMS message blocks-->
55

66
<message id="Lms.Admin.Database.template">
7-
<form class="row g-3">
7+
<form class="row g-3 mb-3">
88
<legend>${tr:Lms.Admin.Database.scan-settings}</legend>
99
<div class="col-sm-6">
1010
<label class="form-label" for="${id:update-period}">
@@ -24,15 +24,7 @@
2424
${update-start-time-info}
2525
</div>
2626
</div>
27-
<div class="col-12">
28-
<label class="form-label" for="${id:similarity-engine-type}">
29-
${tr:Lms.Admin.Database.similarity-engine-type}
30-
</label>
31-
${similarity-engine-type class="form-control"}
32-
<div class="invalid-feedback">
33-
${similarity-engine-type-info}
34-
</div>
35-
</div>
27+
<legend>${tr:Lms.Admin.Database.tag-parsing}</legend>
3628
<div class="col-12">
3729
<label class="form-label" for="${id:extra-tags-to-scan}">
3830
${tr:Lms.Admin.Database.extra-tags-to-scan}
@@ -54,10 +46,30 @@
5446
</label>
5547
${default-tag-delimiter-container class="row gy-3"}
5648
</div>
49+
<legend>${tr:Lms.Admin.Database.misc}</legend>
5750
<div class="col-12">
58-
${save-btn class="btn btn-primary me-1"}${discard-btn class="btn btn-secondary"}
51+
<div class="form-check">
52+
${skip-single-release-playlists class="form-check-input"}
53+
<label class="form-check-label" for="${id:skip-single-release-playlists}">
54+
${tr:Lms.Admin.Database.skip-single-release-playlists}
55+
</label>
56+
<div class="invalid-feedback">
57+
${skip-single-release-playlists-info}
58+
</div>
59+
</div>
60+
</div>
61+
<div class="col-12">
62+
<label class="form-label" for="${id:similarity-engine-type}">
63+
${tr:Lms.Admin.Database.similarity-engine-type}
64+
</label>
65+
${similarity-engine-type class="form-control"}
66+
<div class="invalid-feedback">
67+
${similarity-engine-type-info}
68+
</div>
5969
</div>
6070
</form>
71+
<hr/>
72+
${save-btn class="btn btn-primary me-1"}${discard-btn class="btn btn-secondary"}
6173
</message>
6274

6375
<message id="Lms.Admin.Database.template.line-edit-entry">

approot/explore.xml

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<li>${recently-played class="dropdown-item"}</li>
6464
<li>${most-played class="dropdown-item"}</li>
6565
<li>${recently-added class="dropdown-item"}</li>
66+
<li>${recently-modified class="dropdown-item"}</li>
6667
<li>${all class="dropdown-item"}</li>
6768
</ul>
6869
</div>

approot/messages.xml

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
<message id="Lms.Admin.Database.extra-tags-to-scan">Extra tags to scan</message>
7979
<message id="Lms.Admin.Database.hourly">Hourly</message>
8080
<message id="Lms.Admin.Database.immediate-scan">Scan now!</message>
81+
<message id="Lms.Admin.Database.misc">Miscellaneous</message>
8182
<message id="Lms.Admin.Database.monthly">Monthly</message>
8283
<message id="Lms.Admin.Database.never">Never</message>
8384
<message id="Lms.Admin.Database.scan-aborted">Scan aborted!</message>
@@ -87,7 +88,9 @@
8788
<message id="Lms.Admin.Database.similarity-engine-type">Similarity engine</message>
8889
<message id="Lms.Admin.Database.similarity-engine-type.clusters">Tag-based</message>
8990
<message id="Lms.Admin.Database.similarity-engine-type.none">None</message>
91+
<message id="Lms.Admin.Database.skip-single-release-playlists">Skip playlists that contain tracks from the same album</message>
9092
<message id="Lms.Admin.Database.tag-delimiter-must-not-contain-only-spaces">The tag delimiter must not consist solely of spaces</message>
93+
<message id="Lms.Admin.Database.tag-parsing">Tag parsing</message>
9194
<message id="Lms.Admin.Database.update-period">Update period</message>
9295
<message id="Lms.Admin.Database.update-start-time">Update start time</message>
9396
<message id="Lms.Admin.Database.weekly">Weekly</message>

approot/messages_fr.xml

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
<message id="Lms.Admin.Database.extra-tags-to-scan">Tags supplémentaires à scanner</message>
7979
<message id="Lms.Admin.Database.hourly">Toutes les heures</message>
8080
<message id="Lms.Admin.Database.immediate-scan">Scanner maintenant !</message>
81+
<message id="Lms.Admin.Database.misc">Divers</message>
8182
<message id="Lms.Admin.Database.monthly">Tous les mois</message>
8283
<message id="Lms.Admin.Database.never">Jamais</message>
8384
<message id="Lms.Admin.Database.scan-aborted">Scan interrompu !</message>
@@ -87,7 +88,9 @@
8788
<message id="Lms.Admin.Database.similarity-engine-type">Moteur de similarité</message>
8889
<message id="Lms.Admin.Database.similarity-engine-type.clusters">Basé sur les tags</message>
8990
<message id="Lms.Admin.Database.similarity-engine-type.none">Aucun</message>
91+
<message id="Lms.Admin.Database.skip-single-release-playlists">Ignorer les playlists contenant des pistes d'un même album</message>
9092
<message id="Lms.Admin.Database.tag-delimiter-must-not-contain-only-spaces">Le délimiteur de tag ne doit pas comporter uniquement des espaces</message>
93+
<message id="Lms.Admin.Database.tag-parsing">Analyse des tags</message>
9194
<message id="Lms.Admin.Database.update-period">Périodicité des mises à jour</message>
9295
<message id="Lms.Admin.Database.update-start-time">Heure de départ de la mise à jour</message>
9396
<message id="Lms.Admin.Database.weekly">Toutes les semaines</message>

approot/messages_it.xml

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
<message id="Lms.Admin.Database.extra-tags-to-scan">Tag aggiuntivi da scansionare</message>
7979
<message id="Lms.Admin.Database.hourly">Ogni ora</message>
8080
<message id="Lms.Admin.Database.immediate-scan">Scansiona ora!</message>
81+
<message id="Lms.Admin.Database.misc">Varie</message>
8182
<message id="Lms.Admin.Database.monthly">Mensile</message>
8283
<message id="Lms.Admin.Database.never">Mai</message>
8384
<message id="Lms.Admin.Database.scan-aborted">Scansione annullata!</message>
@@ -87,7 +88,9 @@
8788
<message id="Lms.Admin.Database.similarity-engine-type">Motore di similarità</message>
8889
<message id="Lms.Admin.Database.similarity-engine-type.clusters">Basato su tag</message>
8990
<message id="Lms.Admin.Database.similarity-engine-type.none">Nessuno</message>
91+
<message id="Lms.Admin.Database.skip-single-release-playlists">Salta le playlist che contengono brani dello stesso album</message>
9092
<message id="Lms.Admin.Database.tag-delimiter-must-not-contain-only-spaces">Il delimitatore del tag non deve consistere esclusivamente di spazi</message>
93+
<message id="Lms.Admin.Database.tag-parsing">Analisi dei tag</message>
9194
<message id="Lms.Admin.Database.update-period">Frequenza di aggiornamento</message>
9295
<message id="Lms.Admin.Database.update-start-time">Orario di aggiornamento</message>
9396
<message id="Lms.Admin.Database.weekly">Settimanale</message>

approot/messages_pl.xml

+3
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
<message id="Lms.Admin.Database.extra-tags-to-scan">Szukaj dodatkowych znaczników</message>
8080
<message id="Lms.Admin.Database.hourly">Co godzinę</message>
8181
<message id="Lms.Admin.Database.immediate-scan">Skanuj teraz!</message>
82+
<message id="Lms.Admin.Database.misc">Różne</message>
8283
<message id="Lms.Admin.Database.monthly">Co miesiąc</message>
8384
<message id="Lms.Admin.Database.never">Nigdy</message>
8485
<message id="Lms.Admin.Database.scan-aborted">Skanowanie przerwane!</message>
@@ -88,7 +89,9 @@
8889
<message id="Lms.Admin.Database.similarity-engine-type">Metoda sprawdzania podobieństwa</message>
8990
<message id="Lms.Admin.Database.similarity-engine-type.clusters">Oparta o znaczniki</message>
9091
<message id="Lms.Admin.Database.similarity-engine-type.none">Żadna</message>
92+
<message id="Lms.Admin.Database.skip-single-release-playlists">Pomiń playlisty zawierające utwory z tego samego albumu</message>
9193
<message id="Lms.Admin.Database.tag-delimiter-must-not-contain-only-spaces">Rozdzielacz nie może się składać z samych białych znaków</message>
94+
<message id="Lms.Admin.Database.tag-parsing">Analiza tagów</message>
9295
<message id="Lms.Admin.Database.update-period">Okres aktualizacji</message>
9396
<message id="Lms.Admin.Database.update-start-time">Czas startu aktualizacji</message>
9497
<message id="Lms.Admin.Database.weekly">Co tydzień</message>

approot/messages_zh.xml

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878

7979
<message id="Lms.Admin.Database.hourly">每小时</message>
8080
<message id="Lms.Admin.Database.immediate-scan">立即扫描!</message>
81+
8182
<message id="Lms.Admin.Database.monthly">每月</message>
8283
<message id="Lms.Admin.Database.never">从不</message>
8384

@@ -88,6 +89,8 @@
8889

8990

9091

92+
93+
9194
<message id="Lms.Admin.Database.update-period">更新周期</message>
9295
<message id="Lms.Admin.Database.update-start-time">更新开始时间</message>
9396
<message id="Lms.Admin.Database.weekly">每周</message>

approot/settings.xml

+2-3
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,9 @@
209209
</div>
210210
</div>
211211
${</if-has-change-password>}
212-
<div class="col-12">
213-
${save-btn class="btn btn-primary me-1"}${discard-btn class="btn btn-secondary"}
214-
</div>
215212
</form>
213+
<hr/>
214+
${save-btn class="btn btn-primary me-1"}${discard-btn class="btn btn-secondary"}
216215
</message>
217216

218217
</messages>

conf/lms.conf

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# LMS Sample configuration file
22

3-
# Path to the working directory
4-
# Must have write privileges in order to create and modify this directory
5-
working-dir = "/var/lms/";
3+
# Path to the working directory where the database and other cached files will be written to.
4+
# Ensure this directory exists and has write permissions for the application
5+
working-dir = "/var/lms";
66

77
# ffmpeg location
88
ffmpeg-file = "/usr/bin/ffmpeg";

docroot/js/mediaplayer.js

+25
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ const Mode = {
1515
}
1616
Object.freeze(Mode);
1717

18+
// How much to increase / decrease volume when adjusting it with keyboard shortcuts
19+
const volumeStepAmount = 0.05;
20+
1821
LMS.mediaplayer = function () {
1922
let _root = {};
2023
let _elems = {};
@@ -199,6 +202,20 @@ LMS.mediaplayer = function () {
199202
}
200203
}
201204

205+
let _stepVolumeDown = function() {
206+
let currentVolume = _elems.audio.volume;
207+
let remainder = (currentVolume * 10) % (volumeStepAmount * 10);
208+
let newVolume = remainder === 0 ? currentVolume - volumeStepAmount : currentVolume - (remainder / 10);
209+
_setVolume(Math.max(newVolume, 0));
210+
}
211+
212+
let _stepVolumeUp = function() {
213+
let currentVolume = _elems.audio.volume;
214+
let remainder = (currentVolume * 10) % (volumeStepAmount * 10);
215+
let newVolume = remainder === 0 ? currentVolume + volumeStepAmount : currentVolume + (volumeStepAmount - (remainder / 10));
216+
_setVolume(Math.min(newVolume, 1));
217+
}
218+
202219
let _setReplayGain = function (replayGain) {
203220
_gainNode.gain.value = Math.pow(10, (_settings.replayGain.preAmpGain + replayGain) / 20);
204221
}
@@ -337,6 +354,14 @@ LMS.mediaplayer = function () {
337354
_playNext();
338355
handled = true;
339356
}
357+
else if (event.ctrlKey && event.keyCode == 40) {
358+
_stepVolumeDown();
359+
handled = true;
360+
}
361+
else if (event.ctrlKey && event.keyCode == 38) {
362+
_stepVolumeUp();
363+
handled = true;
364+
}
340365

341366
if (handled)
342367
event.preventDefault();

src/libs/av/CMakeLists.txt

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pkg_check_modules(LIBAV IMPORTED_TARGET libavcodec libavutil libavformat)
22

3-
add_library(lmsav SHARED
3+
add_library(lmsav STATIC
44
impl/AudioFile.cpp
55
impl/RawResourceHandlerCreator.cpp
66
impl/Transcoder.cpp
@@ -26,5 +26,3 @@ target_link_libraries(lmsav PUBLIC
2626
target_link_libraries(lmsav PRIVATE
2727
PkgConfig::LIBAV
2828
)
29-
30-
install(TARGETS lmsav DESTINATION ${CMAKE_INSTALL_LIBDIR})

src/libs/av/impl/AudioFile.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,17 @@ namespace lms::av
130130
AudioFile::AudioFile(const std::filesystem::path& p)
131131
: _p{ p }
132132
{
133-
int error{ avformat_open_input(&_context, _p.string().c_str(), nullptr, nullptr) };
133+
int error{ avformat_open_input(&_context, _p.c_str(), nullptr, nullptr) };
134134
if (error < 0)
135135
{
136-
LMS_LOG(AV, ERROR, "Cannot open " << _p.string() << ": " << averror_to_string(error));
136+
LMS_LOG(AV, ERROR, "Cannot open " << _p << ": " << averror_to_string(error));
137137
throw AudioFileException{ error };
138138
}
139139

140140
error = avformat_find_stream_info(_context, nullptr);
141141
if (error < 0)
142142
{
143-
LMS_LOG(AV, ERROR, "Cannot find stream information on " << _p.string() << ": " << averror_to_string(error));
143+
LMS_LOG(AV, ERROR, "Cannot find stream information on " << _p << ": " << averror_to_string(error));
144144
avformat_close_input(&_context);
145145
throw AudioFileException{ error };
146146
}
@@ -353,7 +353,7 @@ namespace lms::av
353353
{ ".mka", "audio/x-matroska" },
354354
};
355355

356-
auto it{ entries.find(core::stringUtils::stringToLower(fileExtension.string())) };
356+
auto it{ entries.find(core::stringUtils::stringToLower(fileExtension.c_str())) };
357357
if (it == std::cend(entries))
358358
return "";
359359

src/libs/av/impl/Transcoder.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ namespace lms::av::transcoding
9090
throw Exception{ "File error '" + _inputParameters.trackPath.string() + "': " + e.what() };
9191
}
9292

93-
LOG(INFO, "Transcoding file '" << _inputParameters.trackPath.string() << "'");
93+
LOG(INFO, "Transcoding file " << _inputParameters.trackPath);
9494

9595
std::vector<std::string> args;
9696

0 commit comments

Comments
 (0)