Some more renaming
This commit is contained in:
+14
-14
@@ -245,8 +245,8 @@
|
|||||||
<message id="Lms.Settings.backend.listenbrainz">ListenBrainz</message>
|
<message id="Lms.Settings.backend.listenbrainz">ListenBrainz</message>
|
||||||
<message id="Lms.Settings.backend.listenbrainz-token">ListenBrainz API token</message>
|
<message id="Lms.Settings.backend.listenbrainz-token">ListenBrainz API token</message>
|
||||||
<message id="Lms.Settings.change-password">Change password</message>
|
<message id="Lms.Settings.change-password">Change password</message>
|
||||||
<message id="Lms.Settings.default-transcode-bitrate">Default transcode bitrate</message>
|
<message id="Lms.Settings.default-transcoding-output-bitrate">Default transcoding output bitrate</message>
|
||||||
<message id="Lms.Settings.default-transcode-format">Default transcode format</message>
|
<message id="Lms.Settings.default-transcoding-output-format">Default transcoding output format</message>
|
||||||
<message id="Lms.Settings.demo-cannot-save">Cannot save using a demo account!</message>
|
<message id="Lms.Settings.demo-cannot-save">Cannot save using a demo account!</message>
|
||||||
<message id="Lms.Settings.feedback">Feedback</message>
|
<message id="Lms.Settings.feedback">Feedback</message>
|
||||||
<message id="Lms.Settings.menu-settings"><i class="fa fa-fw fa-cog" aria-hidden="true"></i> Settings</message>
|
<message id="Lms.Settings.menu-settings"><i class="fa fa-fw fa-cog" aria-hidden="true"></i> Settings</message>
|
||||||
@@ -267,18 +267,18 @@
|
|||||||
<message id="Lms.Settings.subsonic-artist-list-mode.release-artists">Album artists</message>
|
<message id="Lms.Settings.subsonic-artist-list-mode.release-artists">Album artists</message>
|
||||||
<message id="Lms.Settings.subsonic-artist-list-mode.track-artists">Track artists</message>
|
<message id="Lms.Settings.subsonic-artist-list-mode.track-artists">Track artists</message>
|
||||||
<message id="Lms.Settings.subsonic-api">Subsonic API</message>
|
<message id="Lms.Settings.subsonic-api">Subsonic API</message>
|
||||||
<message id="Lms.Settings.transcode">Transcoding</message>
|
<message id="Lms.Settings.transcoding">Transcoding</message>
|
||||||
<message id="Lms.Settings.transcode-bitrate">Transcode bitrate</message>
|
<message id="Lms.Settings.transcoding-output-bitrate">Transcoding output bitrate</message>
|
||||||
<message id="Lms.Settings.transcode-format">Transcode format</message>
|
<message id="Lms.Settings.transcoding-output-format">Transcoding output format</message>
|
||||||
<message id="Lms.Settings.transcode-format.matroska_opus">Matroska/Opus</message>
|
<message id="Lms.Settings.transcoding-output-format.matroska_opus">Matroska/Opus</message>
|
||||||
<message id="Lms.Settings.transcode-format.mp3">MP3</message>
|
<message id="Lms.Settings.transcoding-output-format.mp3">MP3</message>
|
||||||
<message id="Lms.Settings.transcode-format.ogg_opus">Ogg/Opus</message>
|
<message id="Lms.Settings.transcoding-output-format.ogg_opus">Ogg/Opus</message>
|
||||||
<message id="Lms.Settings.transcode-format.ogg_vorbis">Ogg/Vorbis</message>
|
<message id="Lms.Settings.transcoding-output-format.ogg_vorbis">Ogg/Vorbis</message>
|
||||||
<message id="Lms.Settings.transcode-format.webm_vorbis">WebM/Vorbis</message>
|
<message id="Lms.Settings.transcoding-output-format.webm_vorbis">WebM/Vorbis</message>
|
||||||
<message id="Lms.Settings.transcode-mode">Enable transcoding</message>
|
<message id="Lms.Settings.transcoding-mode">Enable transcoding</message>
|
||||||
<message id="Lms.Settings.transcode-mode.always">Always</message>
|
<message id="Lms.Settings.transcoding-mode.always">Always</message>
|
||||||
<message id="Lms.Settings.transcode-mode.if-format-not-supported">Only when format is not supported</message>
|
<message id="Lms.Settings.transcoding-mode.if-format-not-supported">Only when format is not supported by the browser</message>
|
||||||
<message id="Lms.Settings.transcode-mode.never">Never</message>
|
<message id="Lms.Settings.transcoding-mode.never">Never</message>
|
||||||
<message id="Lms.Settings.settings-saved">New settings saved!</message>
|
<message id="Lms.Settings.settings-saved">New settings saved!</message>
|
||||||
|
|
||||||
</messages>
|
</messages>
|
||||||
|
|||||||
+14
-14
@@ -245,8 +245,8 @@
|
|||||||
<message id="Lms.Settings.backend.listenbrainz">ListenBrainz</message>
|
<message id="Lms.Settings.backend.listenbrainz">ListenBrainz</message>
|
||||||
<message id="Lms.Settings.backend.listenbrainz-token">Jeton d'API ListenBrainz</message>
|
<message id="Lms.Settings.backend.listenbrainz-token">Jeton d'API ListenBrainz</message>
|
||||||
<message id="Lms.Settings.change-password">Changement de mot de passe</message>
|
<message id="Lms.Settings.change-password">Changement de mot de passe</message>
|
||||||
<message id="Lms.Settings.default-transcode-bitrate">Bitrate par defaut du transcodage</message>
|
<message id="Lms.Settings.default-transcoding-output-bitrate">Bitrate par defaut du transcodage</message>
|
||||||
<message id="Lms.Settings.default-transcode-format">Format par defaut du transcodage</message>
|
<message id="Lms.Settings.default-transcoding-output-format">Format par defaut du transcodage</message>
|
||||||
<message id="Lms.Settings.demo-cannot-save">Impossible de sauvegarder en utilisant un compte de démo !</message>
|
<message id="Lms.Settings.demo-cannot-save">Impossible de sauvegarder en utilisant un compte de démo !</message>
|
||||||
<message id="Lms.Settings.feedback">Feedback</message>
|
<message id="Lms.Settings.feedback">Feedback</message>
|
||||||
<message id="Lms.Settings.menu-settings"><i class="fa fa-fw fa-cog" aria-hidden="true"></i> Paramètres</message>
|
<message id="Lms.Settings.menu-settings"><i class="fa fa-fw fa-cog" aria-hidden="true"></i> Paramètres</message>
|
||||||
@@ -267,18 +267,18 @@
|
|||||||
<message id="Lms.Settings.subsonic-artist-list-mode.release-artists">Tous les artistes d'album</message>
|
<message id="Lms.Settings.subsonic-artist-list-mode.release-artists">Tous les artistes d'album</message>
|
||||||
<message id="Lms.Settings.subsonic-artist-list-mode.track-artists">Tous les artistes de piste</message>
|
<message id="Lms.Settings.subsonic-artist-list-mode.track-artists">Tous les artistes de piste</message>
|
||||||
<message id="Lms.Settings.subsonic-api">API Subsonic</message>
|
<message id="Lms.Settings.subsonic-api">API Subsonic</message>
|
||||||
<message id="Lms.Settings.transcode">Transcodage</message>
|
<message id="Lms.Settings.transcoding">Transcodage</message>
|
||||||
<message id="Lms.Settings.transcode-bitrate">Bitrate du transcodage</message>
|
<message id="Lms.Settings.transcoding-output-bitrate">Bitrate du transcodage</message>
|
||||||
<message id="Lms.Settings.transcode-format">Format du transcodage</message>
|
<message id="Lms.Settings.transcoding-output-format">Format du transcodage</message>
|
||||||
<message id="Lms.Settings.transcode-format.matroska_opus">Matroska/Opus</message>
|
<message id="Lms.Settings.transcoding-output-format.matroska_opus">Matroska/Opus</message>
|
||||||
<message id="Lms.Settings.transcode-format.mp3">MP3</message>
|
<message id="Lms.Settings.transcoding-output-format.mp3">MP3</message>
|
||||||
<message id="Lms.Settings.transcode-format.ogg_opus">Ogg/Opus</message>
|
<message id="Lms.Settings.transcoding-output-format.ogg_opus">Ogg/Opus</message>
|
||||||
<message id="Lms.Settings.transcode-format.ogg_vorbis">Ogg/Vorbis</message>
|
<message id="Lms.Settings.transcoding-output-format.ogg_vorbis">Ogg/Vorbis</message>
|
||||||
<message id="Lms.Settings.transcode-format.webm_vorbis">WebM/Vorbis</message>
|
<message id="Lms.Settings.transcoding-output-format.webm_vorbis">WebM/Vorbis</message>
|
||||||
<message id="Lms.Settings.transcode-mode">Appliquer le transcodage</message>
|
<message id="Lms.Settings.transcoding-mode">Appliquer le transcodage</message>
|
||||||
<message id="Lms.Settings.transcode-mode.always">Toujours</message>
|
<message id="Lms.Settings.transcoding-mode.always">Toujours</message>
|
||||||
<message id="Lms.Settings.transcode-mode.if-format-not-supported">Seulement lorsque le format n'est pas pris en charge</message>
|
<message id="Lms.Settings.transcoding-mode.if-format-not-supported">Seulement lorsque le format n'est pas pris en charge par votre navigateur</message>
|
||||||
<message id="Lms.Settings.transcode-mode.never">Jamais</message>
|
<message id="Lms.Settings.transcoding-mode.never">Jamais</message>
|
||||||
<message id="Lms.Settings.settings-saved">Paramètres sauvegardés !</message>
|
<message id="Lms.Settings.settings-saved">Paramètres sauvegardés !</message>
|
||||||
|
|
||||||
<!--Wt-->
|
<!--Wt-->
|
||||||
|
|||||||
+12
-12
@@ -267,18 +267,18 @@
|
|||||||
<message id="Lms.Settings.subsonic-artist-list-mode.release-artists">Artisti album</message>
|
<message id="Lms.Settings.subsonic-artist-list-mode.release-artists">Artisti album</message>
|
||||||
<message id="Lms.Settings.subsonic-artist-list-mode.track-artists">Artisti tracce</message>
|
<message id="Lms.Settings.subsonic-artist-list-mode.track-artists">Artisti tracce</message>
|
||||||
<message id="Lms.Settings.subsonic-api">Subsonic API</message>
|
<message id="Lms.Settings.subsonic-api">Subsonic API</message>
|
||||||
<message id="Lms.Settings.transcode">Transcodifica</message>
|
<message id="Lms.Settings.transcoding">Transcodifica</message>
|
||||||
<message id="Lms.Settings.transcode-bitrate">Bitrate transcodifica</message>
|
<message id="Lms.Settings.transcoding-output-bitrate">Bitrate transcodifica</message>
|
||||||
<message id="Lms.Settings.transcode-format">Formato di transcodifica</message>
|
<message id="Lms.Settings.transcoding-output-format">Formato di transcodifica</message>
|
||||||
<message id="Lms.Settings.transcode-format.matroska_opus">Matroska/Opus</message>
|
<message id="Lms.Settings.transcoding-output-format.matroska_opus">Matroska/Opus</message>
|
||||||
<message id="Lms.Settings.transcode-format.mp3">MP3</message>
|
<message id="Lms.Settings.transcoding-output-format.mp3">MP3</message>
|
||||||
<message id="Lms.Settings.transcode-format.ogg_opus">Ogg/Opus</message>
|
<message id="Lms.Settings.transcoding-output-format.ogg_opus">Ogg/Opus</message>
|
||||||
<message id="Lms.Settings.transcode-format.ogg_vorbis">Ogg/Vorbis</message>
|
<message id="Lms.Settings.transcoding-output-format.ogg_vorbis">Ogg/Vorbis</message>
|
||||||
<message id="Lms.Settings.transcode-format.webm_vorbis">WebM/Vorbis</message>
|
<message id="Lms.Settings.transcoding-output-format.webm_vorbis">WebM/Vorbis</message>
|
||||||
<message id="Lms.Settings.transcode-mode">Abilita transcodifica</message>
|
<message id="Lms.Settings.transcoding-mode">Abilita transcodifica</message>
|
||||||
<message id="Lms.Settings.transcode-mode.always">Sempre</message>
|
<message id="Lms.Settings.transcoding-mode.always">Sempre</message>
|
||||||
<message id="Lms.Settings.transcode-mode.if-format-not-supported">Quando il formato non è supportato</message>
|
<message id="Lms.Settings.transcoding-mode.if-format-not-supported">Quando il formato non è supportato</message>
|
||||||
<message id="Lms.Settings.transcode-mode.never">Mai</message>
|
<message id="Lms.Settings.transcoding-mode.never">Mai</message>
|
||||||
<message id="Lms.Settings.settings-saved">Nuove impostazioni salvate!</message>
|
<message id="Lms.Settings.settings-saved">Nuove impostazioni salvate!</message>
|
||||||
|
|
||||||
<!--Wt-->
|
<!--Wt-->
|
||||||
|
|||||||
+12
-12
@@ -267,18 +267,18 @@
|
|||||||
<message id="Lms.Settings.subsonic-artist-list-mode.release-artists">专辑歌手</message>
|
<message id="Lms.Settings.subsonic-artist-list-mode.release-artists">专辑歌手</message>
|
||||||
<message id="Lms.Settings.subsonic-artist-list-mode.track-artists">音轨歌手</message>
|
<message id="Lms.Settings.subsonic-artist-list-mode.track-artists">音轨歌手</message>
|
||||||
<message id="Lms.Settings.subsonic-api">Subsonic 应用程序接口</message>
|
<message id="Lms.Settings.subsonic-api">Subsonic 应用程序接口</message>
|
||||||
<message id="Lms.Settings.transcode">转码</message>
|
<message id="Lms.Settings.transcoding">转码</message>
|
||||||
<message id="Lms.Settings.transcode-bitrate">转码比特率</message>
|
<message id="Lms.Settings.transcoding-output-bitrate">转码比特率</message>
|
||||||
<message id="Lms.Settings.transcode-format">转码格式</message>
|
<message id="Lms.Settings.transcoding-output-format">转码格式</message>
|
||||||
<message id="Lms.Settings.transcode-format.matroska_opus">Matroska/Opus</message>
|
<message id="Lms.Settings.transcoding-output-format.matroska_opus">Matroska/Opus</message>
|
||||||
<message id="Lms.Settings.transcode-format.mp3">MP3</message>
|
<message id="Lms.Settings.transcoding-output-format.mp3">MP3</message>
|
||||||
<message id="Lms.Settings.transcode-format.ogg_opus">Ogg/Opus</message>
|
<message id="Lms.Settings.transcoding-output-format.ogg_opus">Ogg/Opus</message>
|
||||||
<message id="Lms.Settings.transcode-format.ogg_vorbis">Ogg/Vorbis</message>
|
<message id="Lms.Settings.transcoding-output-format.ogg_vorbis">Ogg/Vorbis</message>
|
||||||
<message id="Lms.Settings.transcode-format.webm_vorbis">WebM/Vorbis</message>
|
<message id="Lms.Settings.transcoding-output-format.webm_vorbis">WebM/Vorbis</message>
|
||||||
<message id="Lms.Settings.transcode-mode">启动转码</message>
|
<message id="Lms.Settings.transcoding-mode">启动转码</message>
|
||||||
<message id="Lms.Settings.transcode-mode.always">总是</message>
|
<message id="Lms.Settings.transcoding-mode.always">总是</message>
|
||||||
<message id="Lms.Settings.transcode-mode.if-format-not-supported">仅当格式不支持时使用</message>
|
<message id="Lms.Settings.transcoding-mode.if-format-not-supported">仅当格式不支持时使用</message>
|
||||||
<message id="Lms.Settings.transcode-mode.never">从不</message>
|
<message id="Lms.Settings.transcoding-mode.never">从不</message>
|
||||||
<message id="Lms.Settings.settings-saved">新设置已保存!</message>
|
<message id="Lms.Settings.settings-saved">新设置已保存!</message>
|
||||||
|
|
||||||
<!--Wt-->
|
<!--Wt-->
|
||||||
|
|||||||
+20
-20
@@ -10,33 +10,33 @@
|
|||||||
${tr:Lms.Settings.audio-settings-are-local}
|
${tr:Lms.Settings.audio-settings-are-local}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:transcode-mode}">
|
<label class="form-label" for="${id:transcoding-mode}">
|
||||||
${tr:Lms.Settings.transcode-mode}
|
${tr:Lms.Settings.transcoding-mode}
|
||||||
</label>
|
</label>
|
||||||
${transcode-mode class="form-control"}
|
${transcoding-mode class="form-control"}
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
${transcode-mode-info}
|
${transcoding-mode-info}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:transcode-format}">
|
<label class="form-label" for="${id:transcoding-output-format}">
|
||||||
${tr:Lms.Settings.transcode-format}
|
${tr:Lms.Settings.transcoding-output-format}
|
||||||
</label>
|
</label>
|
||||||
${transcode-format class="form-control"}
|
${transcoding-output-format class="form-control"}
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
${transcode-format-info}
|
${transcoding-output-format-info}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
<label class="form-label" for="${id:transcode-bitrate}">
|
<label class="form-label" for="${id:transcoding-output-bitrate}">
|
||||||
${tr:Lms.Settings.transcode-bitrate}
|
${tr:Lms.Settings.transcoding-output-bitrate}
|
||||||
</label>
|
</label>
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
${transcode-bitrate class="form-control"}
|
${transcoding-output-bitrate class="form-control"}
|
||||||
<span class="input-group-text">kbps</span>
|
<span class="input-group-text">kbps</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
${transcode-bitrate-info}
|
${transcoding-output-bitrate-info}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
@@ -75,24 +75,24 @@
|
|||||||
${<if-has-subsonic-api>}
|
${<if-has-subsonic-api>}
|
||||||
<legend>${tr:Lms.Settings.subsonic-api}</legend>
|
<legend>${tr:Lms.Settings.subsonic-api}</legend>
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<label class="form-label" for="${id:subsonic-transcode-format}">
|
<label class="form-label" for="${id:subsonic-transcoding-output-format}">
|
||||||
${tr:Lms.Settings.default-transcode-format}
|
${tr:Lms.Settings.default-transcoding-output-format}
|
||||||
</label>
|
</label>
|
||||||
${subsonic-transcode-format class="form-control"}
|
${subsonic-transcoding-output-format class="form-control"}
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
${subsonic-transcode-format-info class="help-block"}
|
${subsonic-transcoding-output-format-info class="help-block"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
<label class="form-label" for="${id:subsonic-transcode-bitrate}">
|
<label class="form-label" for="${id:subsonic-transcoding-output-bitrate}">
|
||||||
${tr:Lms.Settings.default-transcode-bitrate}
|
${tr:Lms.Settings.default-transcoding-output-bitrate}
|
||||||
</label>
|
</label>
|
||||||
<div class="input-group mb-3">
|
<div class="input-group mb-3">
|
||||||
${subsonic-transcode-bitrate class="form-control"}
|
${subsonic-transcoding-output-bitrate class="form-control"}
|
||||||
<span class="input-group-text">kbps</span>
|
<span class="input-group-text">kbps</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
${subsonic-transcode-bitrate-info class="help-block"}
|
${subsonic-transcoding-output-bitrate-info class="help-block"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
|||||||
+12
-12
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
var LMS = LMS || {};
|
var LMS = LMS || {};
|
||||||
|
|
||||||
// Keep in sync with MediaPlayer::TranscodeMode cpp
|
// Keep in sync with MediaPlayer::TranscodingMode cpp
|
||||||
const TranscodeMode = {
|
const TranscodingMode = {
|
||||||
Never: 0,
|
Never: 0,
|
||||||
Always: 1,
|
Always: 1,
|
||||||
IfFormatNotSupported: 2,
|
IfFormatNotSupported: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Mode = {
|
const Mode = {
|
||||||
Transcode: 1,
|
Transcoding: 1,
|
||||||
File: 2,
|
File: 2,
|
||||||
}
|
}
|
||||||
Object.freeze(Mode);
|
Object.freeze(Mode);
|
||||||
@@ -22,7 +22,7 @@ LMS.mediaplayer = function () {
|
|||||||
let _trackId = null;
|
let _trackId = null;
|
||||||
let _duration = 0;
|
let _duration = 0;
|
||||||
let _audioNativeSrc;
|
let _audioNativeSrc;
|
||||||
let _audioTranscodeSrc;
|
let _audioTranscodingSrc;
|
||||||
let _settings = {};
|
let _settings = {};
|
||||||
let _playedDuration = 0;
|
let _playedDuration = 0;
|
||||||
let _lastStartPlaying = null;
|
let _lastStartPlaying = null;
|
||||||
@@ -236,10 +236,10 @@ LMS.mediaplayer = function () {
|
|||||||
let selectedOffset = parseInt(_elems.seek.value, 10);
|
let selectedOffset = parseInt(_elems.seek.value, 10);
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case Mode.Transcode:
|
case Mode.Transcoding:
|
||||||
_offset = selectedOffset;
|
_offset = selectedOffset;
|
||||||
_removeAudioSources();
|
_removeAudioSources();
|
||||||
_addAudioSource(_audioTranscodeSrc + "&offset=" + _offset);
|
_addAudioSource(_audioTranscodingSrc + "&offset=" + _offset);
|
||||||
_elems.audio.load();
|
_elems.audio.load();
|
||||||
_elems.audio.currentTime = 0;
|
_elems.audio.currentTime = 0;
|
||||||
_playTrack();
|
_playTrack();
|
||||||
@@ -270,7 +270,7 @@ LMS.mediaplayer = function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_elems.audio.addEventListener("canplay", function() {
|
_elems.audio.addEventListener("canplay", function() {
|
||||||
if (_getAudioMode() == Mode.Transcode) {
|
if (_getAudioMode() == Mode.Transcoding) {
|
||||||
_elems.transcodingActive.style.display = "inline";
|
_elems.transcodingActive.style.display = "inline";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -337,7 +337,7 @@ LMS.mediaplayer = function () {
|
|||||||
let _getAudioMode = function() {
|
let _getAudioMode = function() {
|
||||||
if (_elems.audio.currentSrc) {
|
if (_elems.audio.currentSrc) {
|
||||||
if (_elems.audio.currentSrc.includes("format"))
|
if (_elems.audio.currentSrc.includes("format"))
|
||||||
return Mode.Transcode;
|
return Mode.Transcoding;
|
||||||
else
|
else
|
||||||
return Mode.File;
|
return Mode.File;
|
||||||
}
|
}
|
||||||
@@ -353,19 +353,19 @@ LMS.mediaplayer = function () {
|
|||||||
_offset = 0;
|
_offset = 0;
|
||||||
_duration = params.duration;
|
_duration = params.duration;
|
||||||
_audioNativeSrc = params.nativeResource;
|
_audioNativeSrc = params.nativeResource;
|
||||||
_audioTranscodeSrc = params.transcodeResource + "&bitrate=" + _settings.transcode.bitrate + "&format=" + _settings.transcode.format;
|
_audioTranscodingSrc = params.transcodingResource + "&bitrate=" + _settings.transcoding.bitrate + "&format=" + _settings.transcoding.format;
|
||||||
|
|
||||||
_elems.seek.max = _duration;
|
_elems.seek.max = _duration;
|
||||||
|
|
||||||
_removeAudioSources();
|
_removeAudioSources();
|
||||||
// ! order is important
|
// ! order is important
|
||||||
if (_settings.transcode.mode == TranscodeMode.Never || _settings.transcode.mode == TranscodeMode.IfFormatNotSupported)
|
if (_settings.transcoding.mode == TranscodingMode.Never || _settings.transcoding.mode == TranscodingMode.IfFormatNotSupported)
|
||||||
{
|
{
|
||||||
_addAudioSource(_audioNativeSrc);
|
_addAudioSource(_audioNativeSrc);
|
||||||
}
|
}
|
||||||
if (_settings.transcode.mode == TranscodeMode.Always || _settings.transcode.mode == TranscodeMode.IfFormatNotSupported)
|
if (_settings.transcoding.mode == TranscodingMode.Always || _settings.transcoding.mode == TranscodingMode.IfFormatNotSupported)
|
||||||
{
|
{
|
||||||
_addAudioSource(_audioTranscodeSrc);
|
_addAudioSource(_audioTranscodingSrc);
|
||||||
}
|
}
|
||||||
_elems.audio.load();
|
_elems.audio.load();
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
namespace Av::Transcoding
|
namespace Av::Transcoding
|
||||||
{
|
{
|
||||||
|
|
||||||
#define LOG(sev) LMS_LOG(TRANSCODE, sev) << "[" << _debugId << "] - "
|
#define LOG(sev) LMS_LOG(TRANSCODING, sev) << "[" << _debugId << "] - "
|
||||||
|
|
||||||
static std::atomic<size_t> globalId{};
|
static std::atomic<size_t> globalId{};
|
||||||
static std::filesystem::path ffmpegPath;
|
static std::filesystem::path ffmpegPath;
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ namespace Av::Transcoding
|
|||||||
, _transcoder{ inputParameters, outputParameters }
|
, _transcoder{ inputParameters, outputParameters }
|
||||||
{
|
{
|
||||||
if (_estimatedContentLength)
|
if (_estimatedContentLength)
|
||||||
LMS_LOG(TRANSCODE, DEBUG) << "Estimated content length = " << *_estimatedContentLength;
|
LMS_LOG(TRANSCODING, DEBUG) << "Estimated content length = " << *_estimatedContentLength;
|
||||||
else
|
else
|
||||||
LMS_LOG(TRANSCODE, DEBUG) << "Not using estimated content length";
|
LMS_LOG(TRANSCODING, DEBUG) << "Not using estimated content length";
|
||||||
}
|
}
|
||||||
|
|
||||||
Wt::Http::ResponseContinuation* TranscodingResourceHandler::processRequest(const Wt::Http::Request& /*request*/, Wt::Http::Response& response)
|
Wt::Http::ResponseContinuation* TranscodingResourceHandler::processRequest(const Wt::Http::Request& /*request*/, Wt::Http::Response& response)
|
||||||
@@ -53,11 +53,11 @@ namespace Av::Transcoding
|
|||||||
if (_estimatedContentLength)
|
if (_estimatedContentLength)
|
||||||
response.setContentLength(*_estimatedContentLength);
|
response.setContentLength(*_estimatedContentLength);
|
||||||
response.setMimeType(_transcoder.getOutputMimeType());
|
response.setMimeType(_transcoder.getOutputMimeType());
|
||||||
LMS_LOG(TRANSCODE, DEBUG) << "Transcoder finished = " << _transcoder.finished() << ", total served bytes = " << _totalServedByteCount << ", mime type = " << _transcoder.getOutputMimeType();
|
LMS_LOG(TRANSCODING, DEBUG) << "Transcoder finished = " << _transcoder.finished() << ", total served bytes = " << _totalServedByteCount << ", mime type = " << _transcoder.getOutputMimeType();
|
||||||
|
|
||||||
if (_bytesReadyCount > 0)
|
if (_bytesReadyCount > 0)
|
||||||
{
|
{
|
||||||
LMS_LOG(TRANSCODE, DEBUG) << "Writing " << _bytesReadyCount << " bytes back to client";
|
LMS_LOG(TRANSCODING, DEBUG) << "Writing " << _bytesReadyCount << " bytes back to client";
|
||||||
|
|
||||||
response.out().write(reinterpret_cast<const char*>(&_buffer[0]), _bytesReadyCount);
|
response.out().write(reinterpret_cast<const char*>(&_buffer[0]), _bytesReadyCount);
|
||||||
_totalServedByteCount += _bytesReadyCount;
|
_totalServedByteCount += _bytesReadyCount;
|
||||||
@@ -70,7 +70,7 @@ namespace Av::Transcoding
|
|||||||
continuation->waitForMoreData();
|
continuation->waitForMoreData();
|
||||||
_transcoder.asyncRead(_buffer.data(), _buffer.size(), [=](std::size_t nbBytesRead)
|
_transcoder.asyncRead(_buffer.data(), _buffer.size(), [=](std::size_t nbBytesRead)
|
||||||
{
|
{
|
||||||
LMS_LOG(TRANSCODE, DEBUG) << "Have " << nbBytesRead << " more bytes to send back";
|
LMS_LOG(TRANSCODING, DEBUG) << "Have " << nbBytesRead << " more bytes to send back";
|
||||||
|
|
||||||
assert(_bytesReadyCount == 0);
|
assert(_bytesReadyCount == 0);
|
||||||
_bytesReadyCount = nbBytesRead;
|
_bytesReadyCount = nbBytesRead;
|
||||||
@@ -86,7 +86,7 @@ namespace Av::Transcoding
|
|||||||
{
|
{
|
||||||
const std::size_t padSize{ *_estimatedContentLength - _totalServedByteCount };
|
const std::size_t padSize{ *_estimatedContentLength - _totalServedByteCount };
|
||||||
|
|
||||||
LMS_LOG(TRANSCODE, DEBUG) << "Adding " << padSize << " padding bytes";
|
LMS_LOG(TRANSCODING, DEBUG) << "Adding " << padSize << " padding bytes";
|
||||||
|
|
||||||
for (std::size_t i{}; i < padSize; ++i)
|
for (std::size_t i{}; i < padSize; ++i)
|
||||||
response.out().put(0);
|
response.out().put(0);
|
||||||
@@ -94,7 +94,7 @@ namespace Av::Transcoding
|
|||||||
_totalServedByteCount += padSize;
|
_totalServedByteCount += padSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
LMS_LOG(TRANSCODE, DEBUG) << "Transcoding finished. Total served byte count = " << _totalServedByteCount;
|
LMS_LOG(TRANSCODING, DEBUG) << "Transcoding finished. Total served byte count = " << _totalServedByteCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -21,59 +21,59 @@
|
|||||||
|
|
||||||
const char* getModuleName(Module mod)
|
const char* getModuleName(Module mod)
|
||||||
{
|
{
|
||||||
switch (mod)
|
switch (mod)
|
||||||
{
|
{
|
||||||
case Module::API_SUBSONIC: return "API_SUBSONIC";
|
case Module::API_SUBSONIC: return "API_SUBSONIC";
|
||||||
case Module::AUTH: return "AUTH";
|
case Module::AUTH: return "AUTH";
|
||||||
case Module::AV: return "AV";
|
case Module::AV: return "AV";
|
||||||
case Module::CHILDPROCESS: return "CHILDPROC";
|
case Module::CHILDPROCESS: return "CHILDPROC";
|
||||||
case Module::COVER: return "COVER";
|
case Module::COVER: return "COVER";
|
||||||
case Module::DB: return "DB";
|
case Module::DB: return "DB";
|
||||||
case Module::DBUPDATER: return "DB UPDATER";
|
case Module::DBUPDATER: return "DB UPDATER";
|
||||||
case Module::FEATURE: return "FEATURE";
|
case Module::FEATURE: return "FEATURE";
|
||||||
case Module::FEEDBACK: return "FEEDBACK";
|
case Module::FEEDBACK: return "FEEDBACK";
|
||||||
case Module::HTTP: return "HTTP";
|
case Module::HTTP: return "HTTP";
|
||||||
case Module::MAIN: return "MAIN";
|
case Module::MAIN: return "MAIN";
|
||||||
case Module::METADATA: return "METADATA";
|
case Module::METADATA: return "METADATA";
|
||||||
case Module::REMOTE: return "REMOTE";
|
case Module::REMOTE: return "REMOTE";
|
||||||
case Module::SCROBBLING: return "SCROBBLING";
|
case Module::SCROBBLING: return "SCROBBLING";
|
||||||
case Module::SERVICE: return "SERVICE";
|
case Module::SERVICE: return "SERVICE";
|
||||||
case Module::RECOMMENDATION: return "RECOMMENDATION";
|
case Module::RECOMMENDATION: return "RECOMMENDATION";
|
||||||
case Module::TRANSCODE: return "TRANSCODE";
|
case Module::TRANSCODING: return "TRANSCODING";
|
||||||
case Module::UI: return "UI";
|
case Module::UI: return "UI";
|
||||||
case Module::UTILS: return "UTILS";
|
case Module::UTILS: return "UTILS";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* getSeverityName(Severity sev)
|
const char* getSeverityName(Severity sev)
|
||||||
{
|
{
|
||||||
switch (sev)
|
switch (sev)
|
||||||
{
|
{
|
||||||
case Severity::FATAL: return "fatal";
|
case Severity::FATAL: return "fatal";
|
||||||
case Severity::ERROR: return "error";
|
case Severity::ERROR: return "error";
|
||||||
case Severity::WARNING: return "warning";
|
case Severity::WARNING: return "warning";
|
||||||
case Severity::INFO: return "info";
|
case Severity::INFO: return "info";
|
||||||
case Severity::DEBUG: return "debug";
|
case Severity::DEBUG: return "debug";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
Log::Log(Logger* logger, Module module, Severity severity)
|
Log::Log(Logger* logger, Module module, Severity severity)
|
||||||
: _module {module},
|
: _module{ module },
|
||||||
_severity {severity},
|
_severity{ severity },
|
||||||
_logger {logger}
|
_logger{ logger }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Log::~Log()
|
Log::~Log()
|
||||||
{
|
{
|
||||||
if (_logger)
|
if (_logger)
|
||||||
_logger->processLog(*this);
|
_logger->processLog(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Log::getMessage() const
|
Log::getMessage() const
|
||||||
{
|
{
|
||||||
return _oss.str();
|
return _oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ enum class Module
|
|||||||
SCROBBLING,
|
SCROBBLING,
|
||||||
SERVICE,
|
SERVICE,
|
||||||
RECOMMENDATION,
|
RECOMMENDATION,
|
||||||
TRANSCODE,
|
TRANSCODING,
|
||||||
UI,
|
UI,
|
||||||
UTILS,
|
UTILS,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ add_executable(lms
|
|||||||
ui/explore/TrackListsView.cpp
|
ui/explore/TrackListsView.cpp
|
||||||
ui/explore/TracksView.cpp
|
ui/explore/TracksView.cpp
|
||||||
ui/resource/AudioFileResource.cpp
|
ui/resource/AudioFileResource.cpp
|
||||||
ui/resource/AudioTranscodeResource.cpp
|
ui/resource/AudioTranscodingResource.cpp
|
||||||
ui/resource/CoverResource.cpp
|
ui/resource/CoverResource.cpp
|
||||||
ui/resource/DownloadResource.cpp
|
ui/resource/DownloadResource.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
#include "explore/Explore.hpp"
|
#include "explore/Explore.hpp"
|
||||||
#include "explore/Filters.hpp"
|
#include "explore/Filters.hpp"
|
||||||
#include "resource/AudioFileResource.hpp"
|
#include "resource/AudioFileResource.hpp"
|
||||||
#include "resource/AudioTranscodeResource.hpp"
|
#include "resource/AudioTranscodingResource.hpp"
|
||||||
#include "resource/DownloadResource.hpp"
|
#include "resource/DownloadResource.hpp"
|
||||||
#include "resource/CoverResource.hpp"
|
#include "resource/CoverResource.hpp"
|
||||||
#include "Auth.hpp"
|
#include "Auth.hpp"
|
||||||
|
|||||||
+240
-249
@@ -35,7 +35,7 @@
|
|||||||
#include "services/database/User.hpp"
|
#include "services/database/User.hpp"
|
||||||
|
|
||||||
#include "resource/CoverResource.hpp"
|
#include "resource/CoverResource.hpp"
|
||||||
#include "resource/AudioTranscodeResource.hpp"
|
#include "resource/AudioTranscodingResource.hpp"
|
||||||
#include "resource/AudioFileResource.hpp"
|
#include "resource/AudioFileResource.hpp"
|
||||||
|
|
||||||
#include "utils/String.hpp"
|
#include "utils/String.hpp"
|
||||||
@@ -44,304 +44,295 @@
|
|||||||
#include "LmsApplication.hpp"
|
#include "LmsApplication.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
|
||||||
namespace UserInterface {
|
namespace UserInterface
|
||||||
|
|
||||||
static std::string settingsToJSString(const MediaPlayer::Settings& settings)
|
|
||||||
{
|
{
|
||||||
namespace Json = Wt::Json;
|
namespace
|
||||||
|
{
|
||||||
|
std::string settingsToJSString(const MediaPlayer::Settings& settings)
|
||||||
|
{
|
||||||
|
namespace Json = Wt::Json;
|
||||||
|
|
||||||
Json::Object res;
|
Json::Object res;
|
||||||
|
|
||||||
{
|
{
|
||||||
Json::Object transcode;
|
Json::Object transcoding;
|
||||||
transcode["mode"] = static_cast<int>(settings.transcode.mode);
|
transcoding["mode"] = static_cast<int>(settings.transcoding.mode);
|
||||||
transcode["format"] = static_cast<int>(settings.transcode.format);
|
transcoding["format"] = static_cast<int>(settings.transcoding.format);
|
||||||
transcode["bitrate"] = static_cast<int>(settings.transcode.bitrate);
|
transcoding["bitrate"] = static_cast<int>(settings.transcoding.bitrate);
|
||||||
res["transcode"] = std::move(transcode);
|
res["transcoding"] = std::move(transcoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Json::Object replayGain;
|
Json::Object replayGain;
|
||||||
replayGain["mode"] = static_cast<int>(settings.replayGain.mode);
|
replayGain["mode"] = static_cast<int>(settings.replayGain.mode);
|
||||||
replayGain["preAmpGain"] = settings.replayGain.preAmpGain;
|
replayGain["preAmpGain"] = settings.replayGain.preAmpGain;
|
||||||
replayGain["preAmpGainIfNoInfo"] = settings.replayGain.preAmpGainIfNoInfo;
|
replayGain["preAmpGainIfNoInfo"] = settings.replayGain.preAmpGainIfNoInfo;
|
||||||
res["replayGain"] = std::move(replayGain);
|
res["replayGain"] = std::move(replayGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Json::serialize(res);
|
return Json::serialize(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
std::optional<MediaPlayer::Settings::Transcoding::Mode> transcodingModeFromString(const std::string& str)
|
||||||
std::optional<MediaPlayer::Settings::Transcode::Mode>
|
{
|
||||||
transcodeModeFromString(const std::string& str)
|
const auto value{ StringUtils::readAs<int>(str) };
|
||||||
{
|
if (!value)
|
||||||
const auto value {StringUtils::readAs<int>(str)};
|
return std::nullopt;
|
||||||
if (!value)
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
MediaPlayer::Settings::Transcode::Mode mode {static_cast<MediaPlayer::Settings::Transcode::Mode>(*value)};
|
MediaPlayer::Settings::Transcoding::Mode mode{ static_cast<MediaPlayer::Settings::Transcoding::Mode>(*value) };
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case MediaPlayer::Settings::Transcode::Mode::Never:
|
case MediaPlayer::Settings::Transcoding::Mode::Never:
|
||||||
case MediaPlayer::Settings::Transcode::Mode::Always:
|
case MediaPlayer::Settings::Transcoding::Mode::Always:
|
||||||
case MediaPlayer::Settings::Transcode::Mode::IfFormatNotSupported:
|
case MediaPlayer::Settings::Transcoding::Mode::IfFormatNotSupported:
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
std::optional<MediaPlayer::Format> formatFromString(const std::string& str)
|
||||||
std::optional<MediaPlayer::Format>
|
{
|
||||||
formatFromString(const std::string& str)
|
const auto value{ StringUtils::readAs<int>(str) };
|
||||||
{
|
if (!value)
|
||||||
const auto value {StringUtils::readAs<int>(str)};
|
return std::nullopt;
|
||||||
if (!value)
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
MediaPlayer::Format format {static_cast<MediaPlayer::Format>(*value)};
|
MediaPlayer::Format format{ static_cast<MediaPlayer::Format>(*value) };
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case MediaPlayer::Format::MP3:
|
case MediaPlayer::Format::MP3:
|
||||||
case MediaPlayer::Format::OGG_OPUS:
|
case MediaPlayer::Format::OGG_OPUS:
|
||||||
case MediaPlayer::Format::MATROSKA_OPUS:
|
case MediaPlayer::Format::MATROSKA_OPUS:
|
||||||
case MediaPlayer::Format::OGG_VORBIS:
|
case MediaPlayer::Format::OGG_VORBIS:
|
||||||
case MediaPlayer::Format::WEBM_VORBIS:
|
case MediaPlayer::Format::WEBM_VORBIS:
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
std::optional<MediaPlayer::Bitrate> bitrateFromString(const std::string& str)
|
||||||
std::optional<MediaPlayer::Bitrate>
|
{
|
||||||
bitrateFromString(const std::string& str)
|
const auto value{ StringUtils::readAs<int>(str) };
|
||||||
{
|
if (!value)
|
||||||
const auto value {StringUtils::readAs<int>(str)};
|
return std::nullopt;
|
||||||
if (!value)
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
if (!Database::isAudioBitrateAllowed(*value))
|
if (!Database::isAudioBitrateAllowed(*value))
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
return *value;
|
return *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
std::optional<MediaPlayer::Settings::ReplayGain::Mode> replayGainModeFromString(const std::string& str)
|
||||||
std::optional<MediaPlayer::Settings::ReplayGain::Mode>
|
{
|
||||||
replayGainModeFromString(const std::string& str)
|
const auto value{ StringUtils::readAs<int>(str) };
|
||||||
{
|
if (!value)
|
||||||
const auto value {StringUtils::readAs<int>(str)};
|
return std::nullopt;
|
||||||
if (!value)
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
MediaPlayer::Settings::ReplayGain::Mode mode {static_cast<MediaPlayer::Settings::ReplayGain::Mode>(*value)};
|
MediaPlayer::Settings::ReplayGain::Mode mode{ static_cast<MediaPlayer::Settings::ReplayGain::Mode>(*value) };
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case MediaPlayer::Settings::ReplayGain::Mode::None:
|
case MediaPlayer::Settings::ReplayGain::Mode::None:
|
||||||
case MediaPlayer::Settings::ReplayGain::Mode::Auto:
|
case MediaPlayer::Settings::ReplayGain::Mode::Auto:
|
||||||
case MediaPlayer::Settings::ReplayGain::Mode::Track:
|
case MediaPlayer::Settings::ReplayGain::Mode::Track:
|
||||||
case MediaPlayer::Settings::ReplayGain::Mode::Release:
|
case MediaPlayer::Settings::ReplayGain::Mode::Release:
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
std::optional<float> replayGainPreAmpGainFromString(const std::string& str)
|
||||||
std::optional<float>
|
{
|
||||||
replayGainPreAmpGainFromString(const std::string& str)
|
const auto value{ StringUtils::readAs<double>(str) };
|
||||||
{
|
if (!value)
|
||||||
const auto value {StringUtils::readAs<double>(str)};
|
return std::nullopt;
|
||||||
if (!value)
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
return ::Utils::clamp(*value, (double)MediaPlayer::Settings::ReplayGain::minPreAmpGain, (double)MediaPlayer::Settings::ReplayGain::maxPreAmpGain);
|
return ::Utils::clamp(*value, (double)MediaPlayer::Settings::ReplayGain::minPreAmpGain, (double)MediaPlayer::Settings::ReplayGain::maxPreAmpGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MediaPlayer::Settings settingsfromJSString(const std::string& strSettings)
|
MediaPlayer::Settings settingsfromJSString(const std::string& strSettings)
|
||||||
{
|
{
|
||||||
using Settings = MediaPlayer::Settings;
|
using Settings = MediaPlayer::Settings;
|
||||||
namespace Json = Wt::Json;
|
namespace Json = Wt::Json;
|
||||||
Json::Object parsedSettings;
|
Json::Object parsedSettings;
|
||||||
|
|
||||||
Json::parse(strSettings, parsedSettings);
|
Json::parse(strSettings, parsedSettings);
|
||||||
|
|
||||||
MediaPlayer::Settings settings;
|
MediaPlayer::Settings settings;
|
||||||
|
|
||||||
{
|
{
|
||||||
const Json::Value transcodeValue {parsedSettings.get("transcode")};
|
const Json::Value transcodingValue{ parsedSettings.get("transcoding") };
|
||||||
if (transcodeValue.type() == Json::Type::Object)
|
if (transcodingValue.type() == Json::Type::Object)
|
||||||
{
|
{
|
||||||
const Json::Object transcode {transcodeValue};
|
const Json::Object transcoding{ transcodingValue };
|
||||||
settings.transcode.mode = transcodeModeFromString(transcode.get("mode").toString().orIfNull("")).value_or(Settings::Transcode::defaultMode);
|
settings.transcoding.mode = transcodingModeFromString(transcoding.get("mode").toString().orIfNull("")).value_or(Settings::Transcoding::defaultMode);
|
||||||
settings.transcode.format = formatFromString(transcode.get("format").toString().orIfNull("")).value_or(Settings::Transcode::defaultFormat);
|
settings.transcoding.format = formatFromString(transcoding.get("format").toString().orIfNull("")).value_or(Settings::Transcoding::defaultFormat);
|
||||||
settings.transcode.bitrate = bitrateFromString(transcode.get("bitrate").toString().orIfNull("")).value_or(Settings::Transcode::defaultBitrate);
|
settings.transcoding.bitrate = bitrateFromString(transcoding.get("bitrate").toString().orIfNull("")).value_or(Settings::Transcoding::defaultBitrate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const Json::Value replayGainValue {parsedSettings.get("replayGain")};
|
const Json::Value replayGainValue{ parsedSettings.get("replayGain") };
|
||||||
if (replayGainValue.type() == Json::Type::Object)
|
if (replayGainValue.type() == Json::Type::Object)
|
||||||
{
|
{
|
||||||
const Json::Object replayGain {replayGainValue};
|
const Json::Object replayGain{ replayGainValue };
|
||||||
settings.replayGain.mode = replayGainModeFromString(replayGain.get("mode").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultMode);
|
settings.replayGain.mode = replayGainModeFromString(replayGain.get("mode").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultMode);
|
||||||
settings.replayGain.preAmpGain = replayGainPreAmpGainFromString(replayGain.get("preAmpGain").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultPreAmpGain);
|
settings.replayGain.preAmpGain = replayGainPreAmpGainFromString(replayGain.get("preAmpGain").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultPreAmpGain);
|
||||||
settings.replayGain.preAmpGainIfNoInfo = replayGainPreAmpGainFromString(replayGain.get("preAmpGainIfNoInfo").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultPreAmpGain);
|
settings.replayGain.preAmpGainIfNoInfo = replayGainPreAmpGainFromString(replayGain.get("preAmpGainIfNoInfo").toString().orIfNull("")).value_or(Settings::ReplayGain::defaultPreAmpGain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MediaPlayer::MediaPlayer()
|
MediaPlayer::MediaPlayer()
|
||||||
: Wt::WTemplate {Wt::WString::tr("Lms.MediaPlayer.template")}
|
: Wt::WTemplate{ Wt::WString::tr("Lms.MediaPlayer.template") }
|
||||||
, playPrevious {this, "playPrevious"}
|
, playPrevious{ this, "playPrevious" }
|
||||||
, playNext {this, "playNext"}
|
, playNext{ this, "playNext" }
|
||||||
, scrobbleListenNow {this, "scrobbleListenNow"}
|
, scrobbleListenNow{ this, "scrobbleListenNow" }
|
||||||
, scrobbleListenFinished {this, "scrobbleListenFinished"}
|
, scrobbleListenFinished{ this, "scrobbleListenFinished" }
|
||||||
, playbackEnded {this, "playbackEnded"}
|
, playbackEnded{ this, "playbackEnded" }
|
||||||
, _settingsLoaded {this, "settingsLoaded"}
|
, _settingsLoaded{ this, "settingsLoaded" }
|
||||||
{
|
{
|
||||||
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
addFunction("tr", &Wt::WTemplate::Functions::tr);
|
||||||
|
|
||||||
_audioTranscodeResource = std::make_unique<AudioTranscodeResource>();
|
_audioTranscodingResource = std::make_unique<AudioTranscodingResource>();
|
||||||
_audioFileResource = std::make_unique<AudioFileResource>();
|
_audioFileResource = std::make_unique<AudioFileResource>();
|
||||||
|
|
||||||
_title = bindNew<Wt::WText>("title");
|
_title = bindNew<Wt::WText>("title");
|
||||||
_artist = bindNew<Wt::WAnchor>("artist");
|
_artist = bindNew<Wt::WAnchor>("artist");
|
||||||
_release = bindNew<Wt::WAnchor>("release");
|
_release = bindNew<Wt::WAnchor>("release");
|
||||||
_separator = bindNew<Wt::WText>("separator");
|
_separator = bindNew<Wt::WText>("separator");
|
||||||
_playQueue = bindNew<Wt::WPushButton>("playqueue-btn", Wt::WString::tr("Lms.MediaPlayer.template.playqueue-btn").arg(0), Wt::TextFormat::XHTML);
|
_playQueue = bindNew<Wt::WPushButton>("playqueue-btn", Wt::WString::tr("Lms.MediaPlayer.template.playqueue-btn").arg(0), Wt::TextFormat::XHTML);
|
||||||
_playQueue->setLink(Wt::WLink {Wt::LinkType::InternalPath, "/playqueue"});
|
_playQueue->setLink(Wt::WLink{ Wt::LinkType::InternalPath, "/playqueue" });
|
||||||
_playQueue->setToolTip(tr("Lms.PlayQueue.playqueue"));
|
_playQueue->setToolTip(tr("Lms.PlayQueue.playqueue"));
|
||||||
|
|
||||||
_settingsLoaded.connect([this](const std::string& settings)
|
_settingsLoaded.connect([this](const std::string& settings)
|
||||||
{
|
{
|
||||||
LMS_LOG(UI, DEBUG) << "Settings loaded! '" << settings << "'";
|
LMS_LOG(UI, DEBUG) << "Settings loaded! '" << settings << "'";
|
||||||
|
|
||||||
_settings = settingsfromJSString(settings);
|
_settings = settingsfromJSString(settings);
|
||||||
|
|
||||||
settingsLoaded.emit();
|
settingsLoaded.emit();
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
Settings defaultSettings;
|
Settings defaultSettings;
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "LMS.mediaplayer.init("
|
oss << "LMS.mediaplayer.init("
|
||||||
<< jsRef()
|
<< jsRef()
|
||||||
<< ", defaultSettings = " << settingsToJSString(defaultSettings)
|
<< ", defaultSettings = " << settingsToJSString(defaultSettings)
|
||||||
<< ")";
|
<< ")";
|
||||||
|
|
||||||
LMS_LOG(UI, DEBUG) << "Running js = '" << oss.str() << "'";
|
LMS_LOG(UI, DEBUG) << "Running js = '" << oss.str() << "'";
|
||||||
doJavaScript(oss.str());
|
doJavaScript(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MediaPlayer::loadTrack(Database::TrackId trackId, bool play, float replayGain)
|
||||||
MediaPlayer::loadTrack(Database::TrackId trackId, bool play, float replayGain)
|
{
|
||||||
{
|
LMS_LOG(UI, DEBUG) << "Playing track ID = " << trackId.toString();
|
||||||
LMS_LOG(UI, DEBUG) << "Playing track ID = " << trackId.toString();
|
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
{
|
{
|
||||||
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
|
auto transaction{ LmsApp->getDbSession().createSharedTransaction() };
|
||||||
|
|
||||||
const auto track {Database::Track::find(LmsApp->getDbSession(), trackId)};
|
const auto track{ Database::Track::find(LmsApp->getDbSession(), trackId) };
|
||||||
if (!track)
|
if (!track)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::string transcodeResource {_audioTranscodeResource->getUrl(trackId)};
|
const std::string transcodingResource{ _audioTranscodingResource->getUrl(trackId) };
|
||||||
const std::string nativeResource {_audioFileResource->getUrl(trackId)};
|
const std::string nativeResource{ _audioFileResource->getUrl(trackId) };
|
||||||
|
|
||||||
const auto artists {track->getArtists({Database::TrackArtistLinkType::Artist})};
|
const auto artists{ track->getArtists({Database::TrackArtistLinkType::Artist}) };
|
||||||
|
|
||||||
oss
|
oss
|
||||||
<< "var params = {"
|
<< "var params = {"
|
||||||
<< " trackId :\"" << trackId.toString() << "\","
|
<< " trackId :\"" << trackId.toString() << "\","
|
||||||
<< " nativeResource: \"" << nativeResource << "\","
|
<< " nativeResource: \"" << nativeResource << "\","
|
||||||
<< " transcodeResource: \"" << transcodeResource << "\","
|
<< " transcodingResource: \"" << transcodingResource << "\","
|
||||||
<< " duration: " << std::chrono::duration_cast<std::chrono::seconds>(track->getDuration()).count() << ","
|
<< " duration: " << std::chrono::duration_cast<std::chrono::seconds>(track->getDuration()).count() << ","
|
||||||
<< " replayGain: " << replayGain << ","
|
<< " replayGain: " << replayGain << ","
|
||||||
<< " title: \"" << StringUtils::jsEscape(track->getName()) << "\","
|
<< " title: \"" << StringUtils::jsEscape(track->getName()) << "\","
|
||||||
<< " artist: \"" << (!artists.empty() ? StringUtils::jsEscape(artists.front()->getName()) : "") << "\","
|
<< " artist: \"" << (!artists.empty() ? StringUtils::jsEscape(artists.front()->getName()) : "") << "\","
|
||||||
<< " release: \"" << (track->getRelease() ? StringUtils::jsEscape(track->getRelease()->getName()) : "") << "\","
|
<< " release: \"" << (track->getRelease() ? StringUtils::jsEscape(track->getRelease()->getName()) : "") << "\","
|
||||||
<< " artwork: ["
|
<< " artwork: ["
|
||||||
<< " { src: \"" << LmsApp->getCoverResource()->getTrackUrl(trackId, CoverResource::Size::Small) << "\", sizes: \"128x128\", type: \"image/jpeg\" },"
|
<< " { src: \"" << LmsApp->getCoverResource()->getTrackUrl(trackId, CoverResource::Size::Small) << "\", sizes: \"128x128\", type: \"image/jpeg\" },"
|
||||||
<< " { src: \"" << LmsApp->getCoverResource()->getTrackUrl(trackId, CoverResource::Size::Large) << "\", sizes: \"512x512\", type: \"image/jpeg\" },"
|
<< " { src: \"" << LmsApp->getCoverResource()->getTrackUrl(trackId, CoverResource::Size::Large) << "\", sizes: \"512x512\", type: \"image/jpeg\" },"
|
||||||
<< " ]"
|
<< " ]"
|
||||||
<< "};";
|
<< "};";
|
||||||
oss << "LMS.mediaplayer.loadTrack(params, " << (play ? "true" : "false") << ")"; // true to autoplay
|
// Update 'sizes' above to match this:
|
||||||
|
static_assert(static_cast<std::underlying_type_t<CoverResource::Size>>(CoverResource::Size::Small) == 128);
|
||||||
|
static_assert(static_cast<std::underlying_type_t<CoverResource::Size>>(CoverResource::Size::Large) == 512);
|
||||||
|
oss << "LMS.mediaplayer.loadTrack(params, " << (play ? "true" : "false") << ")"; // true to autoplay
|
||||||
|
|
||||||
_title->setTextFormat(Wt::TextFormat::Plain);
|
_title->setTextFormat(Wt::TextFormat::Plain);
|
||||||
_title->setText(Wt::WString::fromUTF8(track->getName()));
|
_title->setText(Wt::WString::fromUTF8(track->getName()));
|
||||||
|
|
||||||
bool needSeparator {true};
|
bool needSeparator{ true };
|
||||||
|
|
||||||
if (!artists.empty())
|
if (!artists.empty())
|
||||||
{
|
{
|
||||||
_artist->setTextFormat(Wt::TextFormat::Plain);
|
_artist->setTextFormat(Wt::TextFormat::Plain);
|
||||||
_artist->setText(Wt::WString::fromUTF8(artists.front()->getName()));
|
_artist->setText(Wt::WString::fromUTF8(artists.front()->getName()));
|
||||||
_artist->setLink(Utils::createArtistLink(artists.front()));
|
_artist->setLink(Utils::createArtistLink(artists.front()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_artist->setText("");
|
_artist->setText("");
|
||||||
_artist->setLink({});
|
_artist->setLink({});
|
||||||
needSeparator = false;
|
needSeparator = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (track->getRelease())
|
if (track->getRelease())
|
||||||
{
|
{
|
||||||
_release->setTextFormat(Wt::TextFormat::Plain);
|
_release->setTextFormat(Wt::TextFormat::Plain);
|
||||||
_release->setText(Wt::WString::fromUTF8(track->getRelease()->getName()));
|
_release->setText(Wt::WString::fromUTF8(track->getRelease()->getName()));
|
||||||
_release->setLink(Utils::createReleaseLink(track->getRelease()));
|
_release->setLink(Utils::createReleaseLink(track->getRelease()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_release->setText("");
|
_release->setText("");
|
||||||
_release->setLink({});
|
_release->setLink({});
|
||||||
needSeparator = false;
|
needSeparator = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needSeparator)
|
if (needSeparator)
|
||||||
_separator->setText(" — ");
|
_separator->setText(" — ");
|
||||||
else
|
else
|
||||||
_separator->setText("");
|
_separator->setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
LMS_LOG(UI, DEBUG) << "Running js = '" << oss.str() << "'";
|
LMS_LOG(UI, DEBUG) << "Running js = '" << oss.str() << "'";
|
||||||
doJavaScript(oss.str());
|
doJavaScript(oss.str());
|
||||||
|
|
||||||
_trackIdLoaded = trackId;
|
_trackIdLoaded = trackId;
|
||||||
trackLoaded.emit(*_trackIdLoaded);
|
trackLoaded.emit(*_trackIdLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MediaPlayer::stop()
|
||||||
MediaPlayer::stop()
|
{
|
||||||
{
|
doJavaScript("LMS.mediaplayer.stop()");
|
||||||
doJavaScript("LMS.mediaplayer.stop()");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void MediaPlayer::setSettings(const Settings& settings)
|
||||||
MediaPlayer::setSettings(const Settings& settings)
|
{
|
||||||
{
|
_settings = settings;
|
||||||
_settings = settings;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "LMS.mediaplayer.setSettings(settings = " << settingsToJSString(settings) << ")";
|
oss << "LMS.mediaplayer.setSettings(settings = " << settingsToJSString(settings) << ")";
|
||||||
|
|
||||||
LMS_LOG(UI, DEBUG) << "Running js = '" << oss.str() << "'";
|
LMS_LOG(UI, DEBUG) << "Running js = '" << oss.str() << "'";
|
||||||
doJavaScript(oss.str());
|
doJavaScript(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void MediaPlayer::onPlayQueueUpdated(std::size_t trackCount)
|
||||||
MediaPlayer::onPlayQueueUpdated(std::size_t trackCount)
|
{
|
||||||
{
|
_playQueue->setText(Wt::WString::tr("Lms.MediaPlayer.template.playqueue-btn").arg(trackCount));
|
||||||
_playQueue->setText(Wt::WString::tr("Lms.MediaPlayer.template.playqueue-btn").arg(trackCount));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace UserInterface
|
} // namespace UserInterface
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
namespace UserInterface
|
namespace UserInterface
|
||||||
{
|
{
|
||||||
class AudioFileResource;
|
class AudioFileResource;
|
||||||
class AudioTranscodeResource;
|
class AudioTranscodingResource;
|
||||||
|
|
||||||
class MediaPlayer : public Wt::WTemplate
|
class MediaPlayer : public Wt::WTemplate
|
||||||
{
|
{
|
||||||
@@ -47,7 +47,7 @@ namespace UserInterface
|
|||||||
|
|
||||||
struct Settings
|
struct Settings
|
||||||
{
|
{
|
||||||
struct Transcode
|
struct Transcoding
|
||||||
{
|
{
|
||||||
enum class Mode
|
enum class Mode
|
||||||
{
|
{
|
||||||
@@ -84,16 +84,14 @@ namespace UserInterface
|
|||||||
Gain preAmpGainIfNoInfo{ defaultPreAmpGain };
|
Gain preAmpGainIfNoInfo{ defaultPreAmpGain };
|
||||||
};
|
};
|
||||||
|
|
||||||
Transcode transcode;
|
Transcoding transcoding;
|
||||||
ReplayGain replayGain;
|
ReplayGain replayGain;
|
||||||
};
|
};
|
||||||
|
|
||||||
MediaPlayer();
|
MediaPlayer();
|
||||||
|
~MediaPlayer() = default;
|
||||||
MediaPlayer(const MediaPlayer&) = delete;
|
MediaPlayer(const MediaPlayer&) = delete;
|
||||||
MediaPlayer(MediaPlayer&&) = delete;
|
|
||||||
MediaPlayer& operator=(const MediaPlayer&) = delete;
|
MediaPlayer& operator=(const MediaPlayer&) = delete;
|
||||||
MediaPlayer& operator=(MediaPlayer&&) = delete;
|
|
||||||
|
|
||||||
std::optional<Database::TrackId> getTrackLoaded() const { return _trackIdLoaded; }
|
std::optional<Database::TrackId> getTrackLoaded() const { return _trackIdLoaded; }
|
||||||
|
|
||||||
@@ -118,7 +116,7 @@ namespace UserInterface
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<AudioFileResource> _audioFileResource;
|
std::unique_ptr<AudioFileResource> _audioFileResource;
|
||||||
std::unique_ptr<AudioTranscodeResource> _audioTranscodeResource;
|
std::unique_ptr<AudioTranscodingResource> _audioTranscodingResource;
|
||||||
|
|
||||||
std::optional<Database::TrackId> _trackIdLoaded;
|
std::optional<Database::TrackId> _trackIdLoaded;
|
||||||
std::optional<Settings> _settings;
|
std::optional<Settings> _settings;
|
||||||
|
|||||||
+58
-58
@@ -44,23 +44,23 @@
|
|||||||
#include "LmsApplication.hpp"
|
#include "LmsApplication.hpp"
|
||||||
#include "MediaPlayer.hpp"
|
#include "MediaPlayer.hpp"
|
||||||
|
|
||||||
namespace UserInterface {
|
namespace UserInterface
|
||||||
|
{
|
||||||
using namespace Database;
|
using namespace Database;
|
||||||
|
|
||||||
class SettingsModel : public Wt::WFormModel
|
class SettingsModel : public Wt::WFormModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Associate each field with a unique string literal.
|
// Associate each field with a unique string literal.
|
||||||
static inline const Field TranscodeModeField{ "transcode-mode" };
|
static inline const Field TranscodingModeField{ "transcoding-mode" };
|
||||||
static inline const Field TranscodeFormatField{ "transcode-format" };
|
static inline const Field TranscodeFormatField{ "transcoding-output-format" };
|
||||||
static inline const Field TranscodeBitrateField{ "transcode-bitrate" };
|
static inline const Field TranscodeBitrateField{ "transcoding-output-bitrate" };
|
||||||
static inline const Field ReplayGainModeField{ "replaygain-mode" };
|
static inline const Field ReplayGainModeField{ "replaygain-mode" };
|
||||||
static inline const Field ReplayGainPreAmpGainField{ "replaygain-preamp" };
|
static inline const Field ReplayGainPreAmpGainField{ "replaygain-preamp" };
|
||||||
static inline const Field ReplayGainPreAmpGainIfNoInfoField{ "replaygain-preamp-no-rg-info" };
|
static inline const Field ReplayGainPreAmpGainIfNoInfoField{ "replaygain-preamp-no-rg-info" };
|
||||||
static inline const Field SubsonicArtistListModeField{ "subsonic-artist-list-mode" };
|
static inline const Field SubsonicArtistListModeField{ "subsonic-artist-list-mode" };
|
||||||
static inline const Field SubsonicTranscodingOutputFormatField{ "subsonic-transcode-format" };
|
static inline const Field SubsonicTranscodingOutputFormatField{ "subsonic-transcoding-output-format" };
|
||||||
static inline const Field SubsonicTranscodingOutputBitrateField{ "subsonic-transcode-bitrate" };
|
static inline const Field SubsonicTranscodingOutputBitrateField{ "subsonic-transcoding-output-bitrate" };
|
||||||
static inline const Field FeedbackBackendField{ "feedback-backend" };
|
static inline const Field FeedbackBackendField{ "feedback-backend" };
|
||||||
static inline const Field ScrobblingBackendField{ "scrobbling-backend" };
|
static inline const Field ScrobblingBackendField{ "scrobbling-backend" };
|
||||||
static inline const Field ListenBrainzTokenField{ "listenbrainz-token" };
|
static inline const Field ListenBrainzTokenField{ "listenbrainz-token" };
|
||||||
@@ -68,7 +68,7 @@ namespace UserInterface {
|
|||||||
static inline const Field PasswordField{ "password" };
|
static inline const Field PasswordField{ "password" };
|
||||||
static inline const Field PasswordConfirmField{ "password-confirm" };
|
static inline const Field PasswordConfirmField{ "password-confirm" };
|
||||||
|
|
||||||
using TranscodingModeModel = ValueStringModel<MediaPlayer::Settings::Transcode::Mode>;
|
using TranscodingModeModel = ValueStringModel<MediaPlayer::Settings::Transcoding::Mode>;
|
||||||
using ReplayGainModeModel = ValueStringModel<MediaPlayer::Settings::ReplayGain::Mode>;
|
using ReplayGainModeModel = ValueStringModel<MediaPlayer::Settings::ReplayGain::Mode>;
|
||||||
using FeedbackBackendModel = ValueStringModel<FeedbackBackend>;
|
using FeedbackBackendModel = ValueStringModel<FeedbackBackend>;
|
||||||
using ScrobblingBackendModel = ValueStringModel<ScrobblingBackend>;
|
using ScrobblingBackendModel = ValueStringModel<ScrobblingBackend>;
|
||||||
@@ -79,7 +79,7 @@ namespace UserInterface {
|
|||||||
{
|
{
|
||||||
initializeModels();
|
initializeModels();
|
||||||
|
|
||||||
addField(TranscodeModeField);
|
addField(TranscodingModeField);
|
||||||
addField(TranscodeBitrateField);
|
addField(TranscodeBitrateField);
|
||||||
addField(TranscodeFormatField);
|
addField(TranscodeFormatField);
|
||||||
addField(ReplayGainModeField);
|
addField(ReplayGainModeField);
|
||||||
@@ -105,7 +105,7 @@ namespace UserInterface {
|
|||||||
addField(PasswordConfirmField);
|
addField(PasswordConfirmField);
|
||||||
}
|
}
|
||||||
|
|
||||||
setValidator(TranscodeModeField, createMandatoryValidator());
|
setValidator(TranscodingModeField, createMandatoryValidator());
|
||||||
setValidator(TranscodeBitrateField, createMandatoryValidator());
|
setValidator(TranscodeBitrateField, createMandatoryValidator());
|
||||||
setValidator(TranscodeFormatField, createMandatoryValidator());
|
setValidator(TranscodeFormatField, createMandatoryValidator());
|
||||||
setValidator(ReplayGainModeField, createMandatoryValidator());
|
setValidator(ReplayGainModeField, createMandatoryValidator());
|
||||||
@@ -124,7 +124,7 @@ namespace UserInterface {
|
|||||||
|
|
||||||
std::shared_ptr<TranscodingModeModel> getTranscodingModeModel() { return _transcodingModeModeModel; }
|
std::shared_ptr<TranscodingModeModel> getTranscodingModeModel() { return _transcodingModeModeModel; }
|
||||||
std::shared_ptr<Wt::WAbstractItemModel> getTranscodingOutputBitrateModel() { return _transcodingOutputBitrateModel; }
|
std::shared_ptr<Wt::WAbstractItemModel> getTranscodingOutputBitrateModel() { return _transcodingOutputBitrateModel; }
|
||||||
std::shared_ptr<Wt::WAbstractItemModel> getTranscodeFormatModel() { return _transcodingOutputFormatModel; }
|
std::shared_ptr<Wt::WAbstractItemModel> getTranscodingOutputFormatModel() { return _transcodingOutputFormatModel; }
|
||||||
std::shared_ptr<ReplayGainModeModel> getReplayGainModeModel() { return _replayGainModeModel; }
|
std::shared_ptr<ReplayGainModeModel> getReplayGainModeModel() { return _replayGainModeModel; }
|
||||||
std::shared_ptr<Wt::WAbstractItemModel> getSubsonicArtistListModeModel() { return _subsonicArtistListModeModel; }
|
std::shared_ptr<Wt::WAbstractItemModel> getSubsonicArtistListModeModel() { return _subsonicArtistListModeModel; }
|
||||||
std::shared_ptr<FeedbackBackendModel> getFeedbackBackendModel() { return _feedbackBackendModel; }
|
std::shared_ptr<FeedbackBackendModel> getFeedbackBackendModel() { return _feedbackBackendModel; }
|
||||||
@@ -139,17 +139,17 @@ namespace UserInterface {
|
|||||||
{
|
{
|
||||||
MediaPlayer::Settings settings;
|
MediaPlayer::Settings settings;
|
||||||
|
|
||||||
auto transcodeModeRow{ _transcodingModeModeModel->getRowFromString(valueText(TranscodeModeField)) };
|
auto transcodingModeRow{ _transcodingModeModeModel->getRowFromString(valueText(TranscodingModeField)) };
|
||||||
if (transcodeModeRow)
|
if (transcodingModeRow)
|
||||||
settings.transcode.mode = _transcodingModeModeModel->getValue(*transcodeModeRow);
|
settings.transcoding.mode = _transcodingModeModeModel->getValue(*transcodingModeRow);
|
||||||
|
|
||||||
auto transcodeFormatRow{ _transcodingOutputFormatModel->getRowFromString(valueText(TranscodeFormatField)) };
|
auto transcodingOutputFormatRow{ _transcodingOutputFormatModel->getRowFromString(valueText(TranscodeFormatField)) };
|
||||||
if (transcodeFormatRow)
|
if (transcodingOutputFormatRow)
|
||||||
settings.transcode.format = _transcodingOutputFormatModel->getValue(*transcodeFormatRow);
|
settings.transcoding.format = _transcodingOutputFormatModel->getValue(*transcodingOutputFormatRow);
|
||||||
|
|
||||||
auto transcodeBitrateRow{ _transcodingOutputBitrateModel->getRowFromString(valueText(TranscodeBitrateField)) };
|
auto transcodingOutputBitrateRow{ _transcodingOutputBitrateModel->getRowFromString(valueText(TranscodeBitrateField)) };
|
||||||
if (transcodeBitrateRow)
|
if (transcodingOutputBitrateRow)
|
||||||
settings.transcode.bitrate = _transcodingOutputBitrateModel->getValue(*transcodeBitrateRow);
|
settings.transcoding.bitrate = _transcodingOutputBitrateModel->getValue(*transcodingOutputBitrateRow);
|
||||||
|
|
||||||
auto replayGainModeRow{ _replayGainModeModel->getRowFromString(valueText(ReplayGainModeField)) };
|
auto replayGainModeRow{ _replayGainModeModel->getRowFromString(valueText(ReplayGainModeField)) };
|
||||||
if (replayGainModeRow)
|
if (replayGainModeRow)
|
||||||
@@ -205,22 +205,22 @@ namespace UserInterface {
|
|||||||
{
|
{
|
||||||
const auto settings{ *LmsApp->getMediaPlayer().getSettings() };
|
const auto settings{ *LmsApp->getMediaPlayer().getSettings() };
|
||||||
|
|
||||||
auto transcodeModeRow{ _transcodingModeModeModel->getRowFromValue(settings.transcode.mode) };
|
auto transcodingModeRow{ _transcodingModeModeModel->getRowFromValue(settings.transcoding.mode) };
|
||||||
if (transcodeModeRow)
|
if (transcodingModeRow)
|
||||||
setValue(TranscodeModeField, _transcodingModeModeModel->getString(*transcodeModeRow));
|
setValue(TranscodingModeField, _transcodingModeModeModel->getString(*transcodingModeRow));
|
||||||
|
|
||||||
auto transcodeFormatRow{ _transcodingOutputFormatModel->getRowFromValue(settings.transcode.format) };
|
auto transcodingOutputFormatRow{ _transcodingOutputFormatModel->getRowFromValue(settings.transcoding.format) };
|
||||||
if (transcodeFormatRow)
|
if (transcodingOutputFormatRow)
|
||||||
setValue(TranscodeFormatField, _transcodingOutputFormatModel->getString(*transcodeFormatRow));
|
setValue(TranscodeFormatField, _transcodingOutputFormatModel->getString(*transcodingOutputFormatRow));
|
||||||
|
|
||||||
auto transcodeBitrateRow{ _transcodingOutputBitrateModel->getRowFromValue(settings.transcode.bitrate) };
|
auto transcodingOutputBitrateRow{ _transcodingOutputBitrateModel->getRowFromValue(settings.transcoding.bitrate) };
|
||||||
if (transcodeBitrateRow)
|
if (transcodingOutputBitrateRow)
|
||||||
setValue(TranscodeBitrateField, _transcodingOutputBitrateModel->getString(*transcodeBitrateRow));
|
setValue(TranscodeBitrateField, _transcodingOutputBitrateModel->getString(*transcodingOutputBitrateRow));
|
||||||
|
|
||||||
{
|
{
|
||||||
const bool usesTranscode{ settings.transcode.mode != MediaPlayer::Settings::Transcode::Mode::Never };
|
const bool useTranscoding{ settings.transcoding.mode != MediaPlayer::Settings::Transcoding::Mode::Never };
|
||||||
setReadOnly(SettingsModel::TranscodeFormatField, !usesTranscode);
|
setReadOnly(SettingsModel::TranscodeFormatField, !useTranscoding);
|
||||||
setReadOnly(SettingsModel::TranscodeBitrateField, !usesTranscode);
|
setReadOnly(SettingsModel::TranscodeBitrateField, !useTranscoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto replayGainModeRow{ _replayGainModeModel->getRowFromValue(settings.replayGain.mode) };
|
auto replayGainModeRow{ _replayGainModeModel->getRowFromValue(settings.replayGain.mode) };
|
||||||
@@ -316,9 +316,9 @@ namespace UserInterface {
|
|||||||
void initializeModels()
|
void initializeModels()
|
||||||
{
|
{
|
||||||
_transcodingModeModeModel = std::make_shared<TranscodingModeModel>();
|
_transcodingModeModeModel = std::make_shared<TranscodingModeModel>();
|
||||||
_transcodingModeModeModel->add(Wt::WString::tr("Lms.Settings.transcode-mode.always"), MediaPlayer::Settings::Transcode::Mode::Always);
|
_transcodingModeModeModel->add(Wt::WString::tr("Lms.Settings.transcoding-mode.always"), MediaPlayer::Settings::Transcoding::Mode::Always);
|
||||||
_transcodingModeModeModel->add(Wt::WString::tr("Lms.Settings.transcode-mode.never"), MediaPlayer::Settings::Transcode::Mode::Never);
|
_transcodingModeModeModel->add(Wt::WString::tr("Lms.Settings.transcoding-mode.never"), MediaPlayer::Settings::Transcoding::Mode::Never);
|
||||||
_transcodingModeModeModel->add(Wt::WString::tr("Lms.Settings.transcode-mode.if-format-not-supported"), MediaPlayer::Settings::Transcode::Mode::IfFormatNotSupported);
|
_transcodingModeModeModel->add(Wt::WString::tr("Lms.Settings.transcoding-mode.if-format-not-supported"), MediaPlayer::Settings::Transcoding::Mode::IfFormatNotSupported);
|
||||||
|
|
||||||
_transcodingOutputBitrateModel = std::make_shared<ValueStringModel<Bitrate>>();
|
_transcodingOutputBitrateModel = std::make_shared<ValueStringModel<Bitrate>>();
|
||||||
visitAllowedAudioBitrates([&](const Bitrate bitrate)
|
visitAllowedAudioBitrates([&](const Bitrate bitrate)
|
||||||
@@ -327,11 +327,11 @@ namespace UserInterface {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_transcodingOutputFormatModel = std::make_shared<ValueStringModel<TranscodingOutputFormat>>();
|
_transcodingOutputFormatModel = std::make_shared<ValueStringModel<TranscodingOutputFormat>>();
|
||||||
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcode-format.mp3"), TranscodingOutputFormat::MP3);
|
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcoding-output-format.mp3"), TranscodingOutputFormat::MP3);
|
||||||
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcode-format.ogg_opus"), TranscodingOutputFormat::OGG_OPUS);
|
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcoding-output-format.ogg_opus"), TranscodingOutputFormat::OGG_OPUS);
|
||||||
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcode-format.matroska_opus"), TranscodingOutputFormat::MATROSKA_OPUS);
|
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcoding-output-format.matroska_opus"), TranscodingOutputFormat::MATROSKA_OPUS);
|
||||||
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcode-format.ogg_vorbis"), TranscodingOutputFormat::OGG_VORBIS);
|
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcoding-output-format.ogg_vorbis"), TranscodingOutputFormat::OGG_VORBIS);
|
||||||
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcode-format.webm_vorbis"), TranscodingOutputFormat::WEBM_VORBIS);
|
_transcodingOutputFormatModel->add(Wt::WString::tr("Lms.Settings.transcoding-output-format.webm_vorbis"), TranscodingOutputFormat::WEBM_VORBIS);
|
||||||
|
|
||||||
_replayGainModeModel = std::make_shared<ReplayGainModeModel>();
|
_replayGainModeModel = std::make_shared<ReplayGainModeModel>();
|
||||||
_replayGainModeModel->add(Wt::WString::tr("Lms.Settings.replaygain-mode.none"), MediaPlayer::Settings::ReplayGain::Mode::None);
|
_replayGainModeModel->add(Wt::WString::tr("Lms.Settings.replaygain-mode.none"), MediaPlayer::Settings::ReplayGain::Mode::None);
|
||||||
@@ -431,24 +431,24 @@ namespace UserInterface {
|
|||||||
// Audio
|
// Audio
|
||||||
{
|
{
|
||||||
// Transcode
|
// Transcode
|
||||||
auto transcodeMode{ std::make_unique<Wt::WComboBox>() };
|
auto transcodingMode{ std::make_unique<Wt::WComboBox>() };
|
||||||
auto* transcodeModeRaw{ transcodeMode.get() };
|
auto* transcodingModeRaw{ transcodingMode.get() };
|
||||||
transcodeMode->setModel(model->getTranscodingModeModel());
|
transcodingMode->setModel(model->getTranscodingModeModel());
|
||||||
t->setFormWidget(SettingsModel::TranscodeModeField, std::move(transcodeMode));
|
t->setFormWidget(SettingsModel::TranscodingModeField, std::move(transcodingMode));
|
||||||
|
|
||||||
// Format
|
// Format
|
||||||
auto transcodeFormat{ std::make_unique<Wt::WComboBox>() };
|
auto transcodingOutputFormat{ std::make_unique<Wt::WComboBox>() };
|
||||||
transcodeFormat->setModel(model->getTranscodeFormatModel());
|
transcodingOutputFormat->setModel(model->getTranscodingOutputFormatModel());
|
||||||
t->setFormWidget(SettingsModel::TranscodeFormatField, std::move(transcodeFormat));
|
t->setFormWidget(SettingsModel::TranscodeFormatField, std::move(transcodingOutputFormat));
|
||||||
|
|
||||||
// Bitrate
|
// Bitrate
|
||||||
auto transcodeBitrate{ std::make_unique<Wt::WComboBox>() };
|
auto transcodingOutputBitrate{ std::make_unique<Wt::WComboBox>() };
|
||||||
transcodeBitrate->setModel(model->getTranscodingOutputBitrateModel());
|
transcodingOutputBitrate->setModel(model->getTranscodingOutputBitrateModel());
|
||||||
t->setFormWidget(SettingsModel::TranscodeBitrateField, std::move(transcodeBitrate));
|
t->setFormWidget(SettingsModel::TranscodeBitrateField, std::move(transcodingOutputBitrate));
|
||||||
|
|
||||||
transcodeModeRaw->activated().connect([=](int row)
|
transcodingModeRaw->activated().connect([=](int row)
|
||||||
{
|
{
|
||||||
const bool enable{ model->getTranscodingModeModel()->getValue(row) != MediaPlayer::Settings::Transcode::Mode::Never };
|
const bool enable{ model->getTranscodingModeModel()->getValue(row) != MediaPlayer::Settings::Transcoding::Mode::Never };
|
||||||
model->setReadOnly(SettingsModel::TranscodeFormatField, !enable);
|
model->setReadOnly(SettingsModel::TranscodeFormatField, !enable);
|
||||||
model->setReadOnly(SettingsModel::TranscodeBitrateField, !enable);
|
model->setReadOnly(SettingsModel::TranscodeBitrateField, !enable);
|
||||||
t->updateModel(model.get());
|
t->updateModel(model.get());
|
||||||
@@ -491,14 +491,14 @@ namespace UserInterface {
|
|||||||
t->setCondition("if-has-subsonic-api", Service<IConfig>::get()->getBool("api-subsonic", true));
|
t->setCondition("if-has-subsonic-api", Service<IConfig>::get()->getBool("api-subsonic", true));
|
||||||
|
|
||||||
// Format
|
// Format
|
||||||
auto transcodeFormat{ std::make_unique<Wt::WComboBox>() };
|
auto transcodingOutputFormat{ std::make_unique<Wt::WComboBox>() };
|
||||||
transcodeFormat->setModel(model->getTranscodeFormatModel());
|
transcodingOutputFormat->setModel(model->getTranscodingOutputFormatModel());
|
||||||
t->setFormWidget(SettingsModel::SubsonicTranscodingOutputFormatField, std::move(transcodeFormat));
|
t->setFormWidget(SettingsModel::SubsonicTranscodingOutputFormatField, std::move(transcodingOutputFormat));
|
||||||
|
|
||||||
// Bitrate
|
// Bitrate
|
||||||
auto transcodeBitrate{ std::make_unique<Wt::WComboBox>() };
|
auto transcodingOutputBitrate{ std::make_unique<Wt::WComboBox>() };
|
||||||
transcodeBitrate->setModel(model->getTranscodingOutputBitrateModel());
|
transcodingOutputBitrate->setModel(model->getTranscodingOutputBitrateModel());
|
||||||
t->setFormWidget(SettingsModel::SubsonicTranscodingOutputBitrateField, std::move(transcodeBitrate));
|
t->setFormWidget(SettingsModel::SubsonicTranscodingOutputBitrateField, std::move(transcodingOutputBitrate));
|
||||||
|
|
||||||
// Artist list mode
|
// Artist list mode
|
||||||
auto artistListMode{ std::make_unique<Wt::WComboBox>() };
|
auto artistListMode{ std::make_unique<Wt::WComboBox>() };
|
||||||
|
|||||||
+4
-4
@@ -17,7 +17,7 @@
|
|||||||
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AudioTranscodeResource.hpp"
|
#include "AudioTranscodingResource.hpp"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <Wt/Http/Response.h>
|
#include <Wt/Http/Response.h>
|
||||||
@@ -159,17 +159,17 @@ namespace UserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioTranscodeResource:: ~AudioTranscodeResource()
|
AudioTranscodingResource:: ~AudioTranscodingResource()
|
||||||
{
|
{
|
||||||
beingDeleted();
|
beingDeleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AudioTranscodeResource::getUrl(Database::TrackId trackId) const
|
std::string AudioTranscodingResource::getUrl(Database::TrackId trackId) const
|
||||||
{
|
{
|
||||||
return url() + "&trackid=" + trackId.toString();
|
return url() + "&trackid=" + trackId.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioTranscodeResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response)
|
void AudioTranscodingResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response)
|
||||||
{
|
{
|
||||||
std::shared_ptr<IResourceHandler> resourceHandler;
|
std::shared_ptr<IResourceHandler> resourceHandler;
|
||||||
|
|
||||||
+2
-2
@@ -31,10 +31,10 @@ namespace Database
|
|||||||
|
|
||||||
namespace UserInterface
|
namespace UserInterface
|
||||||
{
|
{
|
||||||
class AudioTranscodeResource : public Wt::WResource
|
class AudioTranscodingResource : public Wt::WResource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~AudioTranscodeResource();
|
~AudioTranscodingResource();
|
||||||
|
|
||||||
// Url depends on the user since settings are used in parameters
|
// Url depends on the user since settings are used in parameters
|
||||||
std::string getUrl(Database::TrackId trackId) const;
|
std::string getUrl(Database::TrackId trackId) const;
|
||||||
Reference in New Issue
Block a user