@@ -541,4 +516,8 @@
+
+ ${shuffle} ${repeat} ${playlist} ${prev} ${play-pause} ${next} ${cover} ${artist} ${track} ${release} ${curtime} ${seekbar} ${duration} ${volume}
+
+
diff --git a/docroot/images/unknown-cover.jpg b/docroot/images/unknown-cover.jpg
old mode 100755
new mode 100644
diff --git a/src/Makefile.am b/src/Makefile.am
index f70f3293..7cc1077c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,6 +24,7 @@ lms_SOURCES = \
$(srcdir)/service/DatabaseUpdateService.cpp \
$(srcdir)/ui/LmsApplication.cpp \
$(srcdir)/ui/auth/LmsAuth.cpp \
+ $(srcdir)/ui/audio/AudioPlayer.cpp \
$(srcdir)/ui/audio/desktop/DesktopAudio.cpp \
$(srcdir)/ui/audio/desktop/AudioMediaPlayer.cpp \
$(srcdir)/ui/audio/desktop/FilterChain.cpp \
@@ -33,11 +34,11 @@ lms_SOURCES = \
$(srcdir)/ui/audio/desktop/TrackView.cpp \
$(srcdir)/ui/audio/mobile/ArtistSearch.cpp \
$(srcdir)/ui/audio/mobile/MobileAudio.cpp \
- $(srcdir)/ui/audio/mobile/MobileAudioMediaPlayer.cpp \
$(srcdir)/ui/audio/mobile/ReleaseSearch.cpp \
$(srcdir)/ui/audio/mobile/TrackReleaseView.cpp \
$(srcdir)/ui/audio/mobile/TrackSearch.cpp \
$(srcdir)/ui/common/DirectoryValidator.cpp \
+ $(srcdir)/ui/common/InputRange.cpp \
$(srcdir)/ui/common/LineEdit.cpp \
$(srcdir)/ui/resource/AvConvTranscodeStreamResource.cpp \
$(srcdir)/ui/resource/CoverResource.cpp \
diff --git a/src/av/AvTranscoder.cpp b/src/av/AvTranscoder.cpp
index 94e0a4e2..67ee92b6 100644
--- a/src/av/AvTranscoder.cpp
+++ b/src/av/AvTranscoder.cpp
@@ -264,25 +264,6 @@ Transcoder::start()
args.push_back("m4v");
break;
- case Encoding::FLV:
- args.push_back("-acodec");
- args.push_back("libmp3lame");
- args.push_back("-ac");
- args.push_back("2");
- args.push_back("-ar");
- args.push_back("44100");
- args.push_back("-vcodec");
- args.push_back("libx264");
- args.push_back("-f");
- args.push_back("flv");
- break;
-
- case Encoding::FLA:
- args.push_back("-acodec");
- args.push_back("libmp3lame");
- args.push_back("-f");
- args.push_back("flv");
- break;
default:
return false;
}
diff --git a/src/av/AvTranscoder.hpp b/src/av/AvTranscoder.hpp
index 7289715a..5706ea94 100644
--- a/src/av/AvTranscoder.hpp
+++ b/src/av/AvTranscoder.hpp
@@ -40,8 +40,6 @@ enum class Encoding
MP3,
WEBMA,
WEBMV,
- FLA,
- FLV,
M4A,
M4V,
};
diff --git a/src/database/User.cpp b/src/database/User.cpp
index 21aa8310..d25410c3 100644
--- a/src/database/User.cpp
+++ b/src/database/User.cpp
@@ -55,7 +55,6 @@ User::audioEncodings =
AudioEncoding::MP3,
AudioEncoding::OGA,
AudioEncoding::WEBMA,
- AudioEncoding::FLA,
};
const std::vector
diff --git a/src/database/User.hpp b/src/database/User.hpp
index 2450aa1f..0bf1138a 100644
--- a/src/database/User.hpp
+++ b/src/database/User.hpp
@@ -39,7 +39,6 @@ enum class AudioEncoding
MP3,
OGA,
WEBMA,
- FLA,
};
enum class VideoEncoding
diff --git a/src/ui/LmsApplication.cpp b/src/ui/LmsApplication.cpp
index 0011ed78..cdf5c7e7 100644
--- a/src/ui/LmsApplication.cpp
+++ b/src/ui/LmsApplication.cpp
@@ -100,6 +100,7 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnecti
setTheme(bootstrapTheme);
useStyleSheet("css/lms.css");
+ useStyleSheet("resources/font-awesome/css/font-awesome.min.css");
// Add a resource bundle
messageResourceBundle().use(appRoot() + "templates");
@@ -142,6 +143,16 @@ Database::User::pointer CurrentUser()
return DbHandler().getCurrentUser();
}
+CoverResource* SessionCoverResource()
+{
+ return LmsApplication::instance()->getCoverResource();
+}
+
+TranscodeResource* SessionTranscodeResource()
+{
+ return LmsApplication::instance()->getTranscodeResource();
+}
+
void
LmsApplication::createFirstConnectionUI()
{
@@ -155,6 +166,8 @@ void
LmsApplication::createLmsUI()
{
_coverResource = new CoverResource(_db, root());
+ _transcodeResource = new TranscodeResource(_db, root());
+
DbHandler().getLogin().changed().connect(this, &LmsApplication::handleAuthEvent);
LmsAuth *authWidget = new LmsAuth();
diff --git a/src/ui/LmsApplication.hpp b/src/ui/LmsApplication.hpp
index b2946991..447c1db3 100644
--- a/src/ui/LmsApplication.hpp
+++ b/src/ui/LmsApplication.hpp
@@ -27,6 +27,7 @@
#include "database/DatabaseHandler.hpp"
#include "resource/CoverResource.hpp"
+#include "resource/TranscodeResource.hpp"
namespace UserInterface {
@@ -40,6 +41,7 @@ class LmsApplication : public Wt::WApplication
// Session application data
CoverResource* getCoverResource() { return _coverResource; }
+ TranscodeResource* getTranscodeResource() { return _transcodeResource; }
Database::Handler& getDbHandler() { return _db;}
private:
@@ -50,6 +52,7 @@ class LmsApplication : public Wt::WApplication
Database::Handler _db;
CoverResource* _coverResource;
+ TranscodeResource* _transcodeResource;
};
// Helpers to get session data
@@ -59,6 +62,9 @@ Wt::Dbo::Session& DboSession();
const Wt::Auth::User& CurrentAuthUser();
Database::User::pointer CurrentUser();
+CoverResource *SessionCoverResource();
+TranscodeResource *SessionTranscodeResource();
+
} // namespace UserInterface
#endif
diff --git a/src/ui/audio/AudioPlayer.cpp b/src/ui/audio/AudioPlayer.cpp
new file mode 100644
index 00000000..9b3d6196
--- /dev/null
+++ b/src/ui/audio/AudioPlayer.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2015 Emeric Poupon
+ *
+ * This file is part of LMS.
+ *
+ * LMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LMS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LMS. If not, see .
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+
+#include "common/InputRange.hpp"
+
+#include "LmsApplication.hpp"
+
+#include "AudioPlayer.hpp"
+
+namespace UserInterface {
+
+void
+AudioPlayer::loadTrack(Database::Track::id_type trackId)
+{
+ Wt::Dbo::Transaction transaction(DboSession());
+
+ Database::Track::pointer track = Database::Track::getById(DboSession(), trackId);
+ if (!track)
+ {
+ std::cerr << "no track for this id!" << std::endl;
+ return;
+ }
+
+ _trackName->setText(Wt::WString::fromUTF8(track->getName()));
+ _artistName->setText( Wt::WString::fromUTF8(track->getArtist()->getName()));
+ _releaseName->setText( Wt::WString::fromUTF8(track->getRelease()->getName()));
+ _cover->setImageLink(SessionCoverResource()->getTrackUrl(trackId, 64));
+ _trackDuration->setText( boost::posix_time::to_simple_string( track->getDuration() ));
+
+ // Analyse track, select the best media stream
+ Av::MediaFile mediaFile(track->getPath());
+
+ if (!mediaFile.open() || !mediaFile.scan())
+ {
+ std::cerr << "cannot open file '" << track->getPath() << std::endl;
+ return;
+ }
+
+
+ int audioBestStreamId = mediaFile.getBestStreamId(Av::Stream::Type::Audio);
+ std::vector streams;
+ if (audioBestStreamId != -1)
+ streams.push_back(audioBestStreamId);
+
+ this->doJavaScript("\
+ document.lms.audio.state = \"loaded\";\
+ document.lms.audio.seekbar.min = " + std::to_string(0) + ";\
+ document.lms.audio.seekbar.max = " + std::to_string(track->getDuration().total_seconds()) + ";\
+ document.lms.audio.seekbar.value = 0;\
+ document.lms.audio.seekbar.disabled = false;\
+ document.lms.audio.offset = 0;\
+ document.lms.audio.curTime = 0;\
+ ");
+
+ //TODO, try to load everything in JS in order to prevent the WriteError bug?
+ _audio->pause();
+ _audio->clearSources();
+ //TODOencoding
+ _audio->addSource(SessionTranscodeResource()->getUrl(trackId, Av::Encoding::MP3, 0, streams));
+ _audio->play();
+}
+
+AudioPlayer::AudioPlayer(Wt::WContainerWidget *parent)
+: Wt::WContainerWidget(parent)
+{
+ Wt::WTemplate *t = new Wt::WTemplate(this);
+ t->setTemplateText(Wt::WString::tr("wa-audio-player"));
+
+ _audio = new Wt::WAudio(this);
+
+ _cover = new Wt::WImage();
+ t->bindWidget("cover", _cover);
+ _cover->setImageLink(SessionCoverResource()->getUnknownTrackUrl(64));
+
+ InputRange *seekbar = new InputRange();
+ t->bindWidget("seekbar", seekbar);
+
+ _trackName = new Wt::WText();
+ t->bindWidget("track", _trackName);
+
+ _artistName = new Wt::WText();
+ t->bindWidget("artist", _artistName);
+
+ _releaseName = new Wt::WText();
+ t->bindWidget("release", _releaseName);
+
+ InputRange *volumeSlider = new InputRange();
+ t->bindWidget("volume", volumeSlider);
+
+ Wt::WPushButton *playlistBtn = new Wt::WPushButton("", Wt::XHTMLText);
+ t->bindWidget("playlist", playlistBtn);
+
+ Wt::WPushButton *repeatBtn = new Wt::WPushButton("", Wt::XHTMLText);
+ t->bindWidget("repeat", repeatBtn);
+
+ Wt::WPushButton *shuffleBtn = new Wt::WPushButton("", Wt::XHTMLText);
+ t->bindWidget("shuffle", shuffleBtn);
+
+ Wt::WPushButton *prevBtn = new Wt::WPushButton("", Wt::XHTMLText);
+ t->bindWidget("prev", prevBtn);
+
+ Wt::WPushButton *nextBtn = new Wt::WPushButton("", Wt::XHTMLText);
+ t->bindWidget("next", nextBtn);
+
+ Wt::WPushButton *playPauseBtn = new Wt::WPushButton("", Wt::XHTMLText);
+ t->bindWidget("play-pause", playPauseBtn);
+
+ Wt::WText *trackCurrentTime = new Wt::WText("00:00");
+ t->bindWidget("curtime", trackCurrentTime);
+
+ _trackDuration = new Wt::WText("00:00");
+ t->bindWidget("duration", _trackDuration);
+
+ this->doJavaScript(
+ "\
+ document.lms = {};\
+ document.lms.audio = {};\
+ document.lms.audio.audio = " + _audio->jsRef() + ";\
+ document.lms.audio.seekbar = " + seekbar->jsRef() +";\
+ document.lms.audio.volumeSlider = " + volumeSlider->jsRef() + ";\
+ document.lms.audio.curTimeText = " + trackCurrentTime->jsRef() + ";\
+ document.lms.audio.playPause = " + playPauseBtn->jsRef() + ";\
+ \
+ document.lms.audio.offset = 0;\
+ document.lms.audio.curTime = 0;\
+ document.lms.audio.state = \"init\";\
+ document.lms.audio.volume = 1;\
+ \
+ document.lms.audio.seekbar.value = 0;\
+ document.lms.audio.seekbar.disabled = true;\
+ \
+ document.lms.audio.volumeSlider.min = 0;\
+ document.lms.audio.volumeSlider.max = 100;\
+ document.lms.audio.volumeSlider.value = 100;\
+ \
+ function updateUI() {\
+ document.lms.audio.curTimeText.innerHTML = document.lms.audio.curTime;\
+ document.lms.audio.seekbar.value = document.lms.audio.curTime;\
+ }\
+ \
+ var mouseDown = 0;\
+ function seekMouseDown(e) {\
+ ++mouseDown;\
+ }\
+ function seekMouseUp(e) {\
+ --mouseDown;\
+ }\
+ \
+ function seeking(e) {\
+ if (document.lms.audio.state == \"init\")\
+ return;\
+ \
+ document.lms.audio.curTimeText.innerHTML = document.lms.audio.seekbar.value;\
+ }\
+ \
+ function seek(e) {\
+ if (document.lms.audio.state == \"init\")\
+ return;\
+ \
+ document.lms.audio.audio.pause(); \
+ document.lms.audio.offset = parseInt(document.lms.audio.seekbar.value);\
+ document.lms.audio.curTime = document.lms.audio.seekbar.value;\
+ var audioSource = document.lms.audio.audio.getElementsByTagName(\"source\")[0];\
+ var src = audioSource.src;\
+ src = src.slice(0, src.lastIndexOf(\"=\") + 1);\
+ audioSource.src = src + document.lms.audio.seekbar.value;\
+ document.lms.audio.audio.load(); \
+ document.lms.audio.audio.play(); \
+ document.lms.audio.curTimeText.innerHTML = ~~document.lms.audio.curTime + \" \";\
+ }\
+ \
+ function volumeChanged() {\
+ document.lms.audio.audio.volume = document.lms.audio.volumeSlider.value / 100;\
+ }\
+ \
+ function updateCurTime() {\
+ document.lms.audio.curTime = document.lms.audio.offset + ~~document.lms.audio.audio.currentTime; \
+ if (mouseDown == 0)\
+ updateUI();\
+ } \
+ \
+ function playPause() {\
+ if (document.lms.audio.state == \"init\") \
+ return;\
+ \
+ if (document.lms.audio.audio.paused)\
+ document.lms.audio.audio.play();\
+ else\
+ document.lms.audio.audio.pause();\
+ \
+ }\
+ \
+ document.lms.audio.audio.addEventListener('timeupdate', updateCurTime); \
+ document.lms.audio.seekbar.addEventListener('change', seek);\
+ document.lms.audio.seekbar.addEventListener('input', seeking);\
+ document.lms.audio.seekbar.addEventListener('mousedown', seekMouseDown);\
+ document.lms.audio.seekbar.addEventListener('mouseup', seekMouseUp);\
+ document.lms.audio.volumeSlider.addEventListener('input', volumeChanged);\
+ document.lms.audio.playPause.addEventListener('click', playPause);\
+ "
+ );
+}
+
+
+} // namespaceUserInterface
diff --git a/src/ui/audio/mobile/MobileAudioMediaPlayer.hpp b/src/ui/audio/AudioPlayer.hpp
similarity index 50%
rename from src/ui/audio/mobile/MobileAudioMediaPlayer.hpp
rename to src/ui/audio/AudioPlayer.hpp
index cf970073..f202e93e 100644
--- a/src/ui/audio/mobile/MobileAudioMediaPlayer.hpp
+++ b/src/ui/audio/AudioPlayer.hpp
@@ -17,43 +17,31 @@
* along with LMS. If not, see .
*/
-#ifndef UI_AUDIO_MOBILE_MEDIA_PLAYER_HPP
-#define UI_AUDIO_MOBILE_MEDIA_PLAYER_HPP
+#pragma once
-#include
-#include
-#include
-
-#include "database/DatabaseHandler.hpp"
-#include "av/AvTranscoder.hpp"
+#include "common/InputRange.hpp"
+#include "database/Types.hpp"
namespace UserInterface {
-namespace Mobile {
-class AudioMediaPlayer : public Wt::WContainerWidget
+class AudioPlayer : public Wt::WContainerWidget
{
public:
- static Wt::WMediaPlayer::Encoding getBestEncoding();
+ AudioPlayer(Wt::WContainerWidget *parent = 0);
- AudioMediaPlayer(Wt::WMediaPlayer::Encoding encoding, Wt::WContainerWidget *parent = 0);
+ void loadTrack(Database::Track::id_type trackId);
- void play(Database::Track::id_type trackId, Av::TranscodeParameters parameters);
-
- Wt::WMediaPlayer::Encoding getEncoding() const { return _encoding; }
+ // Slots
private:
- Wt::WMediaPlayer* _player;
- Wt::WMediaPlayer::Encoding _encoding;
-
- Wt::WImage* _cover;
- Wt::WText* _track;
- Wt::WText* _artistRelease;
-
+ Wt::WAudio* _audio;
+ Wt::WText* _trackDuration;
+ Wt::WText* _trackName;
+ Wt::WText* _artistName;
+ Wt::WText* _releaseName;
+ Wt::WImage* _cover;
};
} // namespace UserInterface
-} // namespace Mobile
-
-#endif
diff --git a/src/ui/audio/desktop/AudioMediaPlayer.cpp b/src/ui/audio/desktop/AudioMediaPlayer.cpp
index 39462fdb..42d9e6cb 100644
--- a/src/ui/audio/desktop/AudioMediaPlayer.cpp
+++ b/src/ui/audio/desktop/AudioMediaPlayer.cpp
@@ -20,7 +20,6 @@
#include
#include
#include
-#include
#include
#include
@@ -57,7 +56,6 @@ AudioMediaPlayer::AudioMediaPlayer(Wt::WContainerWidget *parent)
case Database::AudioEncoding::MP3: _encoding = Wt::WMediaPlayer::MP3; break;
case Database::AudioEncoding::WEBMA: _encoding = Wt::WMediaPlayer::WEBMA; break;
case Database::AudioEncoding::OGA: _encoding = Wt::WMediaPlayer::OGA; break;
- case Database::AudioEncoding::FLA: _encoding = Wt::WMediaPlayer::FLA; break;
case Database::AudioEncoding::AUTO:
default:
_encoding = getBestEncoding();
@@ -237,7 +235,6 @@ AudioMediaPlayer::load(Database::Track::id_type trackId)
switch (_encoding)
{
case Wt::WMediaPlayer::MP3: encoding = Av::Encoding::MP3; break;
- case Wt::WMediaPlayer::FLA: encoding = Av::Encoding::FLA; break;
case Wt::WMediaPlayer::OGA: encoding = Av::Encoding::OGA; break;
case Wt::WMediaPlayer::WEBMA: encoding = Av::Encoding::WEBMA; break;
default:
diff --git a/src/ui/audio/mobile/MobileAudio.cpp b/src/ui/audio/mobile/MobileAudio.cpp
index 750f0973..2a4eb065 100644
--- a/src/ui/audio/mobile/MobileAudio.cpp
+++ b/src/ui/audio/mobile/MobileAudio.cpp
@@ -27,14 +27,13 @@
#include "logger/Logger.hpp"
#include "utils/Utils.hpp"
+#include "audio/AudioPlayer.hpp"
#include "LmsApplication.hpp"
#include "ArtistSearch.hpp"
#include "ReleaseSearch.hpp"
#include "TrackSearch.hpp"
-
#include "TrackReleaseView.hpp"
-#include "MobileAudioMediaPlayer.hpp"
#include "MobileAudio.hpp"
@@ -45,36 +44,16 @@ namespace Mobile {
using namespace Database;
-static void playTrack(AudioMediaPlayer *mediaPlayer, Database::Track::id_type trackId)
+static void playTrack(AudioPlayer *audioPlayer, Database::Track::id_type trackId)
{
LMS_LOG(UI, DEBUG) << "Playing track id " << trackId;
- // TODO reduce transaction scope here
+
Wt::Dbo::Transaction transaction(DboSession());
Track::pointer track = Track::getById(DboSession(), trackId);
if (track)
- {
- Av::TranscodeParameters parameters;
-
- // Determine the output format using the encoding of the player
- Av::Encoding encoding;
- switch(mediaPlayer->getEncoding())
- {
- case Wt::WMediaPlayer::MP3: encoding = Av::Encoding::MP3; break;
- case Wt::WMediaPlayer::FLA: encoding = Av::Encoding::FLA; break;
- case Wt::WMediaPlayer::OGA: encoding = Av::Encoding::OGA; break;
- case Wt::WMediaPlayer::WEBMA: encoding = Av::Encoding::WEBMA; break;
- default:
- encoding = Av::Encoding::MP3;
- }
- parameters.setEncoding(encoding);
-
- // TODO compute parameters using user's profile
- parameters.setBitrate(Av::Stream::Type::Audio, 96000);
-
- mediaPlayer->play(track.id(), parameters);
- }
+ audioPlayer->loadTrack(track.id());
}
Audio::Audio(Wt::WContainerWidget *parent)
@@ -103,26 +82,8 @@ Audio::Audio(Wt::WContainerWidget *parent)
Wt::WTemplate* footer = new Wt::WTemplate(this);
footer->setTemplateText(Wt::WString::tr("mobile-audio-footer"));
- // Determine the encoding to be used
- Wt::WMediaPlayer::Encoding encoding;
-
- {
- Wt::Dbo::Transaction transaction (DboSession());
-
- switch (CurrentUser()->getAudioEncoding())
- {
- case AudioEncoding::MP3: encoding = Wt::WMediaPlayer::MP3; break;
- case AudioEncoding::WEBMA: encoding = Wt::WMediaPlayer::WEBMA; break;
- case AudioEncoding::OGA: encoding = Wt::WMediaPlayer::OGA; break;
- case AudioEncoding::FLA: encoding = Wt::WMediaPlayer::FLA; break;
- case AudioEncoding::AUTO:
- default:
- encoding = AudioMediaPlayer::getBestEncoding();
- }
- }
-
- AudioMediaPlayer* mediaPlayer = new AudioMediaPlayer(encoding);
- footer->bindWidget("player", mediaPlayer);
+ AudioPlayer* audioPlayer = new AudioPlayer();
+ footer->bindWidget("player", audioPlayer);
edit->changed().connect(std::bind([=] ()
{
@@ -188,12 +149,12 @@ Audio::Audio(Wt::WContainerWidget *parent)
trackSearch->trackPlay().connect(std::bind([=] (Track::id_type id)
{
- playTrack(mediaPlayer, id);
+ playTrack(audioPlayer, id);
}, std::placeholders::_1));
trackReleaseView->trackPlay().connect(std::bind([=] (Track::id_type id)
{
- playTrack(mediaPlayer, id);
+ playTrack(audioPlayer, id);
}, std::placeholders::_1));
// Initially, populate the widgets using an empty search
diff --git a/src/ui/audio/mobile/MobileAudioMediaPlayer.cpp b/src/ui/audio/mobile/MobileAudioMediaPlayer.cpp
deleted file mode 100644
index 2127567d..00000000
--- a/src/ui/audio/mobile/MobileAudioMediaPlayer.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2015 Emeric Poupon
- *
- * This file is part of LMS.
- *
- * LMS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * LMS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with LMS. If not, see .
- */
-
-#include
-#include
-#include
-#include
-#include
-
-#include "LmsApplication.hpp"
-
-#include "MobileAudioMediaPlayer.hpp"
-
-#include "resource/AvConvTranscodeStreamResource.hpp"
-
-namespace UserInterface {
-namespace Mobile {
-
-Wt::WMediaPlayer::Encoding
-AudioMediaPlayer::getBestEncoding()
-{
- // MP3 seems to be better supported everywhere
- return Wt::WMediaPlayer::MP3;
-}
-
-AudioMediaPlayer::AudioMediaPlayer(Wt::WMediaPlayer::Encoding encoding, Wt::WContainerWidget *parent)
-:
- Wt::WContainerWidget(parent),
-_player(nullptr),
-_encoding(encoding)
-{
- Wt::WTemplate* container = new Wt::WTemplate(this);
- container->setTemplateText(Wt::WString::tr("mobile-audio-player"));
-
- Wt::WPushButton *play = new Wt::WPushButton("Play");
- play->setStyleClass("btn-sm");
- play->setWidth(52);
- container->bindWidget("play", play);
-
- Wt::WPushButton *pause = new Wt::WPushButton("Pause");
- pause->setStyleClass("btn-sm");
- pause->setWidth(52);
- container->bindWidget("pause", pause);
-
- _track = new Wt::WText("", Wt::PlainText);
- _track->setStyleClass("mobile-track");
- container->bindWidget("track", _track);
-
- _artistRelease = new Wt::WText("", Wt::PlainText);
- _artistRelease->setStyleClass("mobile-artist");
- container->bindWidget("artist", _artistRelease);
-
- _cover = new Wt::WImage();
- container->bindWidget("cover", _cover);
- _cover->setStyleClass("mobile-audio-player-cover");
-
-
- _player = new Wt::WMediaPlayer(Wt::WMediaPlayer::Audio, this);
- _player->addSource( _encoding, "" );
- _player->setControlsWidget( 0 );
- _player->setButton(Wt::WMediaPlayer::Play, play);
- _player->setButton(Wt::WMediaPlayer::Pause, pause);
-
-}
-
-void
-AudioMediaPlayer::play(Database::Track::id_type trackId, Av::TranscodeParameters parameters)
-{
- boost::filesystem::path path;
-
- {
- Wt::Dbo::Transaction transaction(DboSession());
-
- Database::Track::pointer track = Database::Track::getById(DboSession(), trackId);
-
- _track->setText( Wt::WString::fromUTF8(track->getName() ));
- _artistRelease->setText( Wt::WString::fromUTF8(track->getArtist()->getName()) );
- path = track->getPath();
- }
-
- // FIXME memleak here
- AvConvTranscodeStreamResource *resource = new AvConvTranscodeStreamResource( path, parameters, this );
-
- _player->clearSources();
- _player->addSource( _encoding, Wt::WLink(resource));
-
- _player->play();
-
- _cover->setImageLink( Wt::WLink (LmsApplication::instance()->getCoverResource()->getTrackUrl(trackId, 48)));
-
-}
-
-} // namespace UserInterface
-} // namespace Mobile
diff --git a/src/ui/common/InputRange.cpp b/src/ui/common/InputRange.cpp
new file mode 100644
index 00000000..3ff0da7b
--- /dev/null
+++ b/src/ui/common/InputRange.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Emeric Poupon
+ *
+ * This file is part of LMS.
+ *
+ * LMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LMS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LMS. If not, see .
+ */
+
+#include
+
+#if WT_VERSION < 0X03030500
+#include
+#endif
+
+#include "InputRange.hpp"
+
+InputRange::InputRange(Wt::WContainerWidget *parent)
+: Wt::WWebWidget(parent)
+{
+ //TODO woraround for older Wt versions
+#if WT_VERSION >= 0X03030500
+ setHtmlTagName("input");
+ setAttributeValue("type", "range");
+#else
+ Wt::WTemplate *t = new Wt::WTemplate("", parent);
+#endif
+}
+
+
+std::string
+InputRange::jsRef(void) const
+{
+#if WT_VERSION >= 0X03030500
+ return Wt::WWebWidget::jsRef();
+#else
+ return this->jsRef() + ".getElementsByTagName(\"input\")[0]";
+#endif
+}
diff --git a/src/ui/common/InputRange.hpp b/src/ui/common/InputRange.hpp
new file mode 100644
index 00000000..7f03abb4
--- /dev/null
+++ b/src/ui/common/InputRange.hpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 Emeric Poupon
+ *
+ * This file is part of LMS.
+ *
+ * LMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LMS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LMS. If not, see .
+ */
+
+#pragma once
+
+#include
+#include
+
+class InputRange : public Wt::WWebWidget
+{
+ public:
+ InputRange(Wt::WContainerWidget *parent = 0);
+
+ Wt::DomElementType domElementType() const
+ {
+ return Wt::DomElement_INPUT;
+ }
+
+ std::string jsRef() const;
+};
+
diff --git a/src/ui/resource/TranscodeResource.cpp b/src/ui/resource/TranscodeResource.cpp
index 3573bfbc..16478a5f 100644
--- a/src/ui/resource/TranscodeResource.cpp
+++ b/src/ui/resource/TranscodeResource.cpp
@@ -71,11 +71,11 @@ TranscodeResource::handleRequest(const Wt::Http::Request& request,
Wt::Http::ResponseContinuation *continuation = request.continuation();
if (continuation)
{
- LMS_LOG(UI, DEBUG) << "Continuation!";
+ LMS_LOG(UI, DEBUG) << "Continuation! " << continuation ;
transcoder = boost::any_cast >(continuation->data());
if (!transcoder)
{
- LMS_LOG(UI, DEBUG) << "No transcoder set -> abort!";
+ LMS_LOG(UI, ERROR) << "No transcoder set -> abort!";
return;
}
}
@@ -101,18 +101,23 @@ TranscodeResource::handleRequest(const Wt::Http::Request& request,
Database::User::pointer user = _db.getCurrentUser();
Database::Track::pointer track = Database::Track::getById(_db.getSession(), trackId);
- if (!track/* || !user */)
+ if (!track)
{
- LMS_LOG(UI, ERROR) << "Missing track or user";
+ LMS_LOG(UI, ERROR) << "Missing track";
+ return;
+ }
+
+ if (!user)
+ {
+ LMS_LOG(UI, ERROR) << "Missing user";
return;
}
Av::TranscodeParameters parameters;
- // TODO
parameters.setOffset(boost::posix_time::seconds(std::stol(*offsetStr)));
parameters.setEncoding(Av::encoding_from_int(std::stol(*encodingStr)));
- parameters.setBitrate(Av::Stream::Type::Audio, 96000);
+ parameters.setBitrate(Av::Stream::Type::Audio, user->getAudioBitrate() );
for (std::string strStream: streams)
{
LMS_LOG(UI, DEBUG) << "Added stream " << std::stol(strStream);
@@ -135,18 +140,14 @@ TranscodeResource::handleRequest(const Wt::Http::Request& request,
LMS_LOG(UI, DEBUG) << "Transcoder started";
}
- LMS_LOG(UI, DEBUG) << "processing data?";
-
if (!transcoder->isComplete())
{
std::vector data;
data.reserve(_bufferSize);
- LMS_LOG(UI, DEBUG) << "Processing data from transcoder...";
+ LMS_LOG(UI, DEBUG) << "Reading data from transcoder";
transcoder->process(data, _bufferSize);
- LMS_LOG(UI, DEBUG) << "Processing data from transcoder DONE";
- // Give the client all the output data
response.out().write(reinterpret_cast(&data[0]), data.size());
LMS_LOG(UI, DEBUG) << "Written " << data.size() << " bytes! complete = " << std::boolalpha << transcoder->isComplete();
diff --git a/src/ui/settings/SettingsAudioFormView.cpp b/src/ui/settings/SettingsAudioFormView.cpp
index d92312f0..1af1fc18 100644
--- a/src/ui/settings/SettingsAudioFormView.cpp
+++ b/src/ui/settings/SettingsAudioFormView.cpp
@@ -41,7 +41,6 @@ std::string encodingToString(Database::AudioEncoding encoding)
case Database::AudioEncoding::MP3: return "MP3";
case Database::AudioEncoding::OGA: return "OGG";
case Database::AudioEncoding::WEBMA: return "WebM";
- case Database::AudioEncoding::FLA: return "Flash";
}
return "?";