1 /*
2  * Copyright (C) 2018 Emeric Poupon
3  *
4  * This file is part of LMS.
5  *
6  * LMS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * LMS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with LMS.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #pragma once
21 
22 #include <chrono>
23 #include <optional>
24 
25 #include <Wt/WAnchor.h>
26 #include <Wt/WJavaScript.h>
27 #include <Wt/WTemplate.h>
28 #include <Wt/WText.h>
29 
30 #include "database/Types.hpp"
31 
32 namespace UserInterface {
33 
34 class AudioFileResource;
35 class AudioTranscodeResource;
36 
37 class MediaPlayer : public Wt::WTemplate
38 {
39 	public:
40 		using Bitrate = Database::Bitrate;
41 		using Format = Database::AudioFormat;
42 		using Gain = float;
43 
44 		// Do not change enum values as they may be stored locally in browser
45 		// Keep it sync with LMS.mediaplayer js
46 
47 		struct Settings
48 		{
49 			struct Transcode
50 			{
51 				enum class Mode
52 				{
53 					Never			= 0,
54 					Always			= 1,
55 					IfFormatNotSupported	= 2,
56 				};
57 				static inline constexpr Mode defaultMode {Mode::IfFormatNotSupported};
58 				static inline constexpr Format defaultFormat {Format::OGG_OPUS};
59 				static inline constexpr Bitrate defaultBitrate {128000};
60 
61 				Mode		mode {defaultMode};
62 				Format		format {defaultFormat};
63 				Bitrate		bitrate {defaultBitrate};
64 			};
65 
66 			struct ReplayGain
67 			{
68 				enum class Mode
69 				{
70 					None			= 0,
71 					Auto			= 1,
72 					Track			= 2,
73 					Release			= 3,
74 				};
75 
76 				static inline constexpr Mode			defaultMode {Mode::None};
77 				static inline constexpr Gain			defaultPreAmpGain {};
78 				static inline constexpr Gain			minPreAmpGain {-15};
79 				static inline constexpr Gain			maxPreAmpGain {15};
80 
81 				Mode			mode {defaultMode};
82 				Gain			preAmpGain {defaultPreAmpGain};
83 				Gain			preAmpGainIfNoInfo {defaultPreAmpGain};
84 			};
85 
86 			Transcode transcode;
87 			ReplayGain replayGain;
88 		};
89 
90 		MediaPlayer();
91 
92 		MediaPlayer(const MediaPlayer&) = delete;
93 		MediaPlayer(MediaPlayer&&) = delete;
94 		MediaPlayer& operator=(const MediaPlayer&) = delete;
95 		MediaPlayer& operator=(MediaPlayer&&) = delete;
96 
getTrackLoaded() const97 		std::optional<Database::IdType> getTrackLoaded() const { return _trackIdLoaded; }
98 
99 		void loadTrack(Database::IdType trackId, bool play, float replayGain);
100 		void stop();
101 
getSettings() const102 		std::optional<Settings>	getSettings() const { return _settings; }
103 		void			setSettings(const Settings& settings);
104 
105 		// Signals
106 		Wt::JSignal<> 			playPrevious;
107 		Wt::JSignal<> 			playNext;
108 		Wt::Signal<Database::IdType>	trackLoaded;
109 		Wt::Signal<>			settingsLoaded;
110 
111 		Wt::JSignal<Database::IdType>				scrobbleListenNow;
112 		Wt::JSignal<Database::IdType, unsigned /* ms */>		scrobbleListenFinished;
113 
114 		Wt::JSignal<>			playbackEnded;
115 
116 	private:
117 		std::unique_ptr<AudioFileResource>		_audioFileResource;
118 		std::unique_ptr<AudioTranscodeResource>	_audioTranscodeResource;
119 
120 		std::optional<Database::IdType> _trackIdLoaded;
121 		std::optional<Settings>		_settings;
122 
123 		Wt::JSignal<std::string> 	_settingsLoaded;
124 
125 		Wt::WText*		_title {};
126 		Wt::WAnchor*	_release {};
127 		Wt::WAnchor*	_artist {};
128 };
129 
130 } // namespace UserInterface
131 
132