Rename EngineBase
This commit is contained in:
parent
c3534affdb
commit
e9f3281694
|
@ -58,10 +58,10 @@ set(SOURCES
|
|||
utilities/coverutils.cpp
|
||||
utilities/screenutils.cpp
|
||||
|
||||
engine/enginetype.cpp
|
||||
engine/enginebase.cpp
|
||||
engine/devicefinders.cpp
|
||||
engine/devicefinder.cpp
|
||||
engine/enginemetadata.cpp
|
||||
|
||||
analyzer/fht.cpp
|
||||
analyzer/analyzerbase.cpp
|
||||
|
|
|
@ -108,8 +108,8 @@ void Analyzer::Base::paintEvent(QPaintEvent *e) {
|
|||
p.fillRect(e->rect(), palette().color(QPalette::Window));
|
||||
|
||||
switch (engine_->state()) {
|
||||
case Engine::State::Playing: {
|
||||
const Engine::Scope &thescope = engine_->scope(timeout_);
|
||||
case EngineBase::State::Playing: {
|
||||
const EngineBase::Scope &thescope = engine_->scope(timeout_);
|
||||
int i = 0;
|
||||
|
||||
// convert to mono here - our built in analyzers need mono, but the engines provide interleaved pcm
|
||||
|
@ -126,7 +126,7 @@ void Analyzer::Base::paintEvent(QPaintEvent *e) {
|
|||
|
||||
break;
|
||||
}
|
||||
case Engine::State::Paused:
|
||||
case EngineBase::State::Paused:
|
||||
is_playing_ = false;
|
||||
analyze(p, lastscope_, new_frame_);
|
||||
break;
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <QPainter>
|
||||
|
||||
#include "analyzer/fht.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
|
||||
class QHideEvent;
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
|
||||
#include "core/logging.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginetype.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
|
@ -104,7 +103,7 @@ AnalyzerContainer::AnalyzerContainer(QWidget *parent)
|
|||
|
||||
void AnalyzerContainer::mouseReleaseEvent(QMouseEvent *e) {
|
||||
|
||||
if (engine_->type() != Engine::EngineType::GStreamer) {
|
||||
if (engine_->type() != EngineBase::Type::GStreamer) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <QAction>
|
||||
#include <QActionGroup>
|
||||
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
|
||||
class QTimer;
|
||||
class QMouseEvent;
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include <QPalette>
|
||||
#include <QColor>
|
||||
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "fht.h"
|
||||
#include "analyzerbase.h"
|
||||
|
@ -110,7 +109,7 @@ void BoomAnalyzer::transform(Scope &s) {
|
|||
|
||||
void BoomAnalyzer::analyze(QPainter &p, const Scope &scope, const bool new_frame) {
|
||||
|
||||
if (!new_frame || engine_->state() == Engine::State::Paused) {
|
||||
if (!new_frame || engine_->state() == EngineBase::State::Paused) {
|
||||
p.drawPixmap(0, 0, canvas_);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <QPainter>
|
||||
#include <QResizeEvent>
|
||||
|
||||
#include "engine/enginebase.h"
|
||||
|
||||
#include "sonogram.h"
|
||||
|
||||
const char *Sonogram::kName = QT_TRANSLATE_NOOP("AnalyzerContainer", "Sonogram");
|
||||
|
@ -42,7 +44,7 @@ void Sonogram::resizeEvent(QResizeEvent *e) {
|
|||
|
||||
void Sonogram::analyze(QPainter &p, const Analyzer::Scope &s, bool new_frame) {
|
||||
|
||||
if (!new_frame || engine_->state() == Engine::State::Paused) {
|
||||
if (!new_frame || engine_->state() == EngineBase::State::Paused) {
|
||||
p.drawPixmap(0, 0, canvas_);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -55,9 +55,7 @@
|
|||
#include "utilities/strutils.h"
|
||||
#include "utilities/timeutils.h"
|
||||
#include "widgets/resizabletextedit.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/devicefinders.h"
|
||||
#include "engine/devicefinder.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
|
@ -544,12 +542,12 @@ void ContextView::SetSong() {
|
|||
|
||||
if (action_show_output_->isChecked()) {
|
||||
widget_play_output_->show();
|
||||
Engine::EngineType enginetype(Engine::EngineType::None);
|
||||
EngineBase::Type enginetype = EngineBase::Type::None;
|
||||
if (app_->player()->engine()) enginetype = app_->player()->engine()->type();
|
||||
QIcon icon_engine = IconLoader::Load(EngineName(enginetype), true, 32);
|
||||
QIcon icon_engine = IconLoader::Load(EngineBase::Name(enginetype), true, 32);
|
||||
|
||||
label_engine_icon_->setPixmap(icon_engine.pixmap(QSize(32, 32)));
|
||||
label_engine_->setText(EngineDescription(enginetype));
|
||||
label_engine_->setText(EngineBase::Description(enginetype));
|
||||
spacer_play_output_->changeSize(20, 20, QSizePolicy::Fixed);
|
||||
|
||||
DeviceFinder::Device device;
|
||||
|
|
|
@ -103,9 +103,7 @@
|
|||
#include "utilities/filemanagerutils.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "utilities/screenutils.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "dialogs/errordialog.h"
|
||||
#include "dialogs/about.h"
|
||||
#include "dialogs/console.h"
|
||||
|
@ -1246,7 +1244,7 @@ void MainWindow::Exit() {
|
|||
if (app_->player()->engine()->is_fadeout_enabled()) {
|
||||
// To shut down the application when fadeout will be finished
|
||||
QObject::connect(app_->player()->engine(), &EngineBase::FadeoutFinishedSignal, this, &MainWindow::DoExit);
|
||||
if (app_->player()->GetState() == Engine::State::Playing) {
|
||||
if (app_->player()->GetState() == EngineBase::State::Playing) {
|
||||
app_->player()->Stop();
|
||||
ignore_close_ = true;
|
||||
close();
|
||||
|
@ -1275,11 +1273,11 @@ void MainWindow::ExitFinished() {
|
|||
|
||||
}
|
||||
|
||||
void MainWindow::EngineChanged(Engine::EngineType enginetype) {
|
||||
void MainWindow::EngineChanged(const EngineBase::Type enginetype) {
|
||||
|
||||
ui_->action_equalizer->setEnabled(enginetype == Engine::EngineType::GStreamer);
|
||||
ui_->action_equalizer->setEnabled(enginetype == EngineBase::Type::GStreamer);
|
||||
#if defined(HAVE_AUDIOCD) && !defined(Q_OS_WIN)
|
||||
ui_->action_open_cd->setEnabled(enginetype == Engine::EngineType::GStreamer);
|
||||
ui_->action_open_cd->setEnabled(enginetype == EngineBase::Type::GStreamer);
|
||||
#else
|
||||
ui_->action_open_cd->setEnabled(false);
|
||||
ui_->action_open_cd->setVisible(false);
|
||||
|
@ -1460,7 +1458,7 @@ void MainWindow::SavePlaybackStatus() {
|
|||
|
||||
s.beginGroup(Player::kSettingsGroup);
|
||||
s.setValue("playback_state", static_cast<int>(app_->player()->GetState()));
|
||||
if (app_->player()->GetState() == Engine::State::Playing || app_->player()->GetState() == Engine::State::Paused) {
|
||||
if (app_->player()->GetState() == EngineBase::State::Playing || app_->player()->GetState() == EngineBase::State::Paused) {
|
||||
s.setValue("playback_playlist", app_->playlist_manager()->active()->id());
|
||||
s.setValue("playback_position", app_->player()->engine()->position_nanosec() / kNsecPerSec);
|
||||
}
|
||||
|
@ -1482,10 +1480,10 @@ void MainWindow::LoadPlaybackStatus() {
|
|||
s.endGroup();
|
||||
|
||||
s.beginGroup(Player::kSettingsGroup);
|
||||
const Engine::State playback_state = static_cast<Engine::State>(s.value("playback_state", static_cast<int>(Engine::State::Empty)).toInt());
|
||||
const EngineBase::State playback_state = static_cast<EngineBase::State>(s.value("playback_state", static_cast<int>(EngineBase::State::Empty)).toInt());
|
||||
s.endGroup();
|
||||
|
||||
if (resume_playback && playback_state != Engine::State::Empty && playback_state != Engine::State::Idle) {
|
||||
if (resume_playback && playback_state != EngineBase::State::Empty && playback_state != EngineBase::State::Idle) {
|
||||
std::shared_ptr<QMetaObject::Connection> connection = std::make_shared<QMetaObject::Connection>();
|
||||
*connection = QObject::connect(app_->playlist_manager(), &PlaylistManager::AllPlaylistsLoaded, this, [this, connection]() {
|
||||
QObject::disconnect(*connection);
|
||||
|
@ -1501,7 +1499,7 @@ void MainWindow::ResumePlayback() {
|
|||
|
||||
QSettings s;
|
||||
s.beginGroup(Player::kSettingsGroup);
|
||||
const Engine::State playback_state = static_cast<Engine::State>(s.value("playback_state", static_cast<int>(Engine::State::Empty)).toInt());
|
||||
const EngineBase::State playback_state = static_cast<EngineBase::State>(s.value("playback_state", static_cast<int>(EngineBase::State::Empty)).toInt());
|
||||
int playback_playlist = s.value("playback_playlist", -1).toInt();
|
||||
int playback_position = s.value("playback_position", 0).toInt();
|
||||
s.endGroup();
|
||||
|
@ -1509,7 +1507,7 @@ void MainWindow::ResumePlayback() {
|
|||
if (playback_playlist == app_->playlist_manager()->current()->id()) {
|
||||
// Set active to current to resume playback on correct playlist.
|
||||
app_->playlist_manager()->SetActiveToCurrent();
|
||||
if (playback_state == Engine::State::Paused) {
|
||||
if (playback_state == EngineBase::State::Paused) {
|
||||
std::shared_ptr<QMetaObject::Connection> connection = std::make_shared<QMetaObject::Connection>();
|
||||
*connection = QObject::connect(app_->player(), &Player::Playing, app_->player(), [this, connection]() {
|
||||
QObject::disconnect(*connection);
|
||||
|
@ -1521,7 +1519,7 @@ void MainWindow::ResumePlayback() {
|
|||
|
||||
// Reset saved playback status so we don't resume again from the same position.
|
||||
s.beginGroup(Player::kSettingsGroup);
|
||||
s.setValue("playback_state", static_cast<int>(Engine::State::Empty));
|
||||
s.setValue("playback_state", static_cast<int>(EngineBase::State::Empty));
|
||||
s.setValue("playback_playlist", -1);
|
||||
s.setValue("playback_position", 0);
|
||||
s.endGroup();
|
||||
|
@ -1539,7 +1537,7 @@ void MainWindow::PlayIndex(const QModelIndex &idx, Playlist::AutoScroll autoscro
|
|||
}
|
||||
|
||||
app_->playlist_manager()->SetActiveToCurrent();
|
||||
app_->player()->PlayAt(row, 0, Engine::TrackChangeType::Manual, autoscroll, true);
|
||||
app_->player()->PlayAt(row, 0, EngineBase::TrackChangeType::Manual, autoscroll, true);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1556,14 +1554,14 @@ void MainWindow::PlaylistDoubleClick(const QModelIndex &idx) {
|
|||
switch (doubleclick_playlist_addmode_) {
|
||||
case BehaviourSettingsPage::PlaylistAddBehaviour::Play:
|
||||
app_->playlist_manager()->SetActiveToCurrent();
|
||||
app_->player()->PlayAt(source_idx.row(), 0, Engine::TrackChangeType::Manual, Playlist::AutoScroll::Never, true, true);
|
||||
app_->player()->PlayAt(source_idx.row(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true, true);
|
||||
break;
|
||||
|
||||
case BehaviourSettingsPage::PlaylistAddBehaviour::Enqueue:
|
||||
app_->playlist_manager()->current()->queue()->ToggleTracks(QModelIndexList() << source_idx);
|
||||
if (app_->player()->GetState() != Engine::State::Playing) {
|
||||
if (app_->player()->GetState() != EngineBase::State::Playing) {
|
||||
app_->playlist_manager()->SetActiveToCurrent();
|
||||
app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), 0, Engine::TrackChangeType::Manual, Playlist::AutoScroll::Never, true);
|
||||
app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1749,7 +1747,7 @@ void MainWindow::ApplyPlayBehaviour(const BehaviourSettingsPage::PlayBehaviour b
|
|||
break;
|
||||
|
||||
case BehaviourSettingsPage::PlayBehaviour::IfStopped:
|
||||
mimedata->play_now_ = !(app_->player()->GetState() == Engine::State::Playing);
|
||||
mimedata->play_now_ = !(app_->player()->GetState() == EngineBase::State::Playing);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1835,7 +1833,7 @@ void MainWindow::PlaylistRightClick(const QPoint global_pos, const QModelIndex &
|
|||
playlist_menu_index_ = source_index;
|
||||
|
||||
// Is this song currently playing?
|
||||
if (app_->playlist_manager()->current()->current_row() == source_index.row() && app_->player()->GetState() == Engine::State::Playing) {
|
||||
if (app_->playlist_manager()->current()->current_row() == source_index.row() && app_->player()->GetState() == EngineBase::State::Playing) {
|
||||
playlist_play_pause_->setText(tr("Pause"));
|
||||
playlist_play_pause_->setIcon(IconLoader::Load("media-playback-pause"));
|
||||
}
|
||||
|
@ -2480,7 +2478,7 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) {
|
|||
app_->player()->SeekTo(app_->player()->engine()->position_nanosec() / kNsecPerSec + options.seek_by());
|
||||
}
|
||||
|
||||
if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), 0, Engine::TrackChangeType::Manual, Playlist::AutoScroll::Maybe, true);
|
||||
if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Maybe, true);
|
||||
|
||||
if (options.show_osd()) app_->player()->ShowOSD();
|
||||
|
||||
|
@ -3189,13 +3187,13 @@ void MainWindow::PlaylistDelete() {
|
|||
|
||||
if (DeleteConfirmationDialog::warning(files) != QDialogButtonBox::Yes) return;
|
||||
|
||||
if (app_->player()->GetState() == Engine::State::Playing && app_->playlist_manager()->current()->rowCount() == selected_songs.count()) {
|
||||
if (app_->player()->GetState() == EngineBase::State::Playing && app_->playlist_manager()->current()->rowCount() == selected_songs.count()) {
|
||||
app_->player()->Stop();
|
||||
}
|
||||
|
||||
ui_->playlist->view()->RemoveSelected();
|
||||
|
||||
if (app_->player()->GetState() == Engine::State::Playing && is_current_item) {
|
||||
if (app_->player()->GetState() == EngineBase::State::Playing && is_current_item) {
|
||||
app_->player()->Next();
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,7 @@
|
|||
#include "platforminterface.h"
|
||||
#include "song.h"
|
||||
#include "tagreaderclient.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "osd/osdbase.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
#include "playlist/playlist.h"
|
||||
|
@ -142,7 +141,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
|||
private slots:
|
||||
void FilePathChanged(const QString &path);
|
||||
|
||||
void EngineChanged(Engine::EngineType enginetype);
|
||||
void EngineChanged(const EngineBase::Type enginetype);
|
||||
void MediaStopped();
|
||||
void MediaPaused();
|
||||
void MediaPlaying();
|
||||
|
|
|
@ -47,9 +47,8 @@
|
|||
|
||||
#include "song.h"
|
||||
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/enginemetadata.h"
|
||||
#ifdef HAVE_GSTREAMER
|
||||
# include "engine/gstenginepipeline.h"
|
||||
#endif
|
||||
|
@ -103,11 +102,11 @@ void RegisterMetaTypes() {
|
|||
qRegisterMetaType<SongMap>("SongMap");
|
||||
qRegisterMetaType<Song::Source>("Song::Source");
|
||||
qRegisterMetaType<Song::FileType>("Song::FileType");
|
||||
qRegisterMetaType<Engine::EngineType>("Engine::EngineType");
|
||||
qRegisterMetaType<Engine::SimpleMetaBundle>("Engine::SimpleMetaBundle");
|
||||
qRegisterMetaType<Engine::State>("Engine::State");
|
||||
qRegisterMetaType<Engine::TrackChangeFlags>("Engine::TrackChangeFlags");
|
||||
qRegisterMetaType<EngineBase::Type>("EngineBase::Type");
|
||||
qRegisterMetaType<EngineBase::State>("EngineBase::State");
|
||||
qRegisterMetaType<EngineBase::TrackChangeFlags>("EngineBase::TrackChangeFlags");
|
||||
qRegisterMetaType<EngineBase::OutputDetails>("EngineBase::OutputDetails");
|
||||
qRegisterMetaType<EngineMetadata>("EngineMetadata");
|
||||
#ifdef HAVE_GSTREAMER
|
||||
qRegisterMetaType<GstBuffer*>("GstBuffer*");
|
||||
qRegisterMetaType<GstElement*>("GstElement*");
|
||||
|
|
|
@ -162,9 +162,9 @@ void Mpris2::PlaylistManagerInitialized() {
|
|||
QObject::connect(app_->playlist_manager()->sequence(), &PlaylistSequence::RepeatModeChanged, this, &Mpris2::RepeatModeChanged);
|
||||
}
|
||||
|
||||
void Mpris2::EngineStateChanged(Engine::State newState) {
|
||||
void Mpris2::EngineStateChanged(EngineBase::State newState) {
|
||||
|
||||
if (newState != Engine::State::Playing && newState != Engine::State::Paused) {
|
||||
if (newState != EngineBase::State::Playing && newState != EngineBase::State::Paused) {
|
||||
last_metadata_ = QVariantMap();
|
||||
EmitNotification("Metadata");
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ void Mpris2::EngineStateChanged(Engine::State newState) {
|
|||
EmitNotification("CanPlay");
|
||||
EmitNotification("CanPause");
|
||||
EmitNotification("PlaybackStatus", PlaybackStatus(newState));
|
||||
if (newState == Engine::State::Playing) EmitNotification("CanSeek", CanSeek(newState));
|
||||
if (newState == EngineBase::State::Playing) EmitNotification("CanSeek", CanSeek(newState));
|
||||
|
||||
}
|
||||
|
||||
|
@ -304,11 +304,11 @@ QString Mpris2::PlaybackStatus() const {
|
|||
return PlaybackStatus(app_->player()->GetState());
|
||||
}
|
||||
|
||||
QString Mpris2::PlaybackStatus(Engine::State state) const {
|
||||
QString Mpris2::PlaybackStatus(EngineBase::State state) const {
|
||||
|
||||
switch (state) {
|
||||
case Engine::State::Playing: return "Playing";
|
||||
case Engine::State::Paused: return "Paused";
|
||||
case EngineBase::State::Playing: return "Playing";
|
||||
case EngineBase::State::Paused: return "Paused";
|
||||
default: return "Stopped";
|
||||
}
|
||||
|
||||
|
@ -449,13 +449,13 @@ bool Mpris2::CanPlay() const {
|
|||
|
||||
// This one's a bit different than MPRIS 1 - we want this to be true even when the song is already paused or stopped.
|
||||
bool Mpris2::CanPause() const {
|
||||
return (app_->player()->GetCurrentItem() && app_->player()->GetState() == Engine::State::Playing && !(app_->player()->GetCurrentItem()->options() & PlaylistItem::Option::PauseDisabled)) || PlaybackStatus() == "Paused" || PlaybackStatus() == "Stopped";
|
||||
return (app_->player()->GetCurrentItem() && app_->player()->GetState() == EngineBase::State::Playing && !(app_->player()->GetCurrentItem()->options() & PlaylistItem::Option::PauseDisabled)) || PlaybackStatus() == "Paused" || PlaybackStatus() == "Stopped";
|
||||
}
|
||||
|
||||
bool Mpris2::CanSeek() const { return CanSeek(app_->player()->GetState()); }
|
||||
|
||||
bool Mpris2::CanSeek(Engine::State state) const {
|
||||
return app_->player()->GetCurrentItem() && state != Engine::State::Empty && !app_->player()->GetCurrentItem()->Metadata().is_stream();
|
||||
bool Mpris2::CanSeek(EngineBase::State state) const {
|
||||
return app_->player()->GetCurrentItem() && state != EngineBase::State::Empty && !app_->player()->GetCurrentItem()->Metadata().is_stream();
|
||||
}
|
||||
|
||||
bool Mpris2::CanControl() const { return true; }
|
||||
|
@ -473,7 +473,7 @@ void Mpris2::Previous() {
|
|||
}
|
||||
|
||||
void Mpris2::Pause() {
|
||||
if (CanPause() && app_->player()->GetState() != Engine::State::Paused) {
|
||||
if (CanPause() && app_->player()->GetState() != EngineBase::State::Paused) {
|
||||
app_->player()->Pause();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <qdbusextratypes.h>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
|
||||
class Application;
|
||||
|
@ -203,7 +203,7 @@ class Mpris2 : public QObject {
|
|||
|
||||
private slots:
|
||||
void AlbumCoverLoaded(const Song &song, AlbumCoverLoaderResultPtr result = AlbumCoverLoaderResultPtr());
|
||||
void EngineStateChanged(Engine::State newState);
|
||||
void EngineStateChanged(EngineBase::State newState);
|
||||
void VolumeChanged();
|
||||
|
||||
void PlaylistManagerInitialized();
|
||||
|
@ -218,11 +218,11 @@ class Mpris2 : public QObject {
|
|||
void EmitNotification(const QString &name, const QVariant &value);
|
||||
void EmitNotification(const QString &name, const QVariant &value, const QString &mprisEntity);
|
||||
|
||||
QString PlaybackStatus(Engine::State state) const;
|
||||
QString PlaybackStatus(EngineBase::State state) const;
|
||||
|
||||
QString current_track_id() const;
|
||||
|
||||
bool CanSeek(Engine::State state) const;
|
||||
bool CanSeek(EngineBase::State state) const;
|
||||
|
||||
QString DesktopEntryAbsolutePath() const;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "application.h"
|
||||
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/enginemetadata.h"
|
||||
|
||||
#ifdef HAVE_GSTREAMER
|
||||
# include "engine/gstengine.h"
|
||||
|
@ -79,9 +79,9 @@ Player::Player(Application *app, QObject *parent)
|
|||
#endif
|
||||
analyzer_(nullptr),
|
||||
equalizer_(nullptr),
|
||||
stream_change_type_(Engine::TrackChangeType::First),
|
||||
stream_change_type_(EngineBase::TrackChangeType::First),
|
||||
autoscroll_(Playlist::AutoScroll::Maybe),
|
||||
last_state_(Engine::State::Empty),
|
||||
last_state_(EngineBase::State::Empty),
|
||||
nb_errors_received_(0),
|
||||
volume_(100),
|
||||
volume_before_mute_(100),
|
||||
|
@ -94,23 +94,23 @@ Player::Player(Application *app, QObject *parent)
|
|||
|
||||
QSettings s;
|
||||
s.beginGroup(BackendSettingsPage::kSettingsGroup);
|
||||
Engine::EngineType enginetype = Engine::EngineTypeFromName(s.value("engine", EngineName(Engine::EngineType::GStreamer)).toString().toLower());
|
||||
EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower());
|
||||
s.endGroup();
|
||||
|
||||
CreateEngine(enginetype);
|
||||
|
||||
}
|
||||
|
||||
Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) {
|
||||
EngineBase::Type Player::CreateEngine(EngineBase::Type enginetype) {
|
||||
|
||||
Engine::EngineType use_enginetype(Engine::EngineType::None);
|
||||
EngineBase::Type use_enginetype = EngineBase::Type::None;
|
||||
|
||||
for (int i = 0; use_enginetype == Engine::EngineType::None; i++) {
|
||||
for (int i = 0; use_enginetype == EngineBase::Type::None; i++) {
|
||||
switch (enginetype) {
|
||||
case Engine::EngineType::None:
|
||||
case EngineBase::Type::None:
|
||||
#ifdef HAVE_GSTREAMER
|
||||
case Engine::EngineType::GStreamer:{
|
||||
use_enginetype=Engine::EngineType::GStreamer;
|
||||
case EngineBase::Type::GStreamer:{
|
||||
use_enginetype=EngineBase::Type::GStreamer;
|
||||
std::unique_ptr<GstEngine> gst_engine(new GstEngine(app_->task_manager()));
|
||||
gst_engine->SetStartup(gst_startup_);
|
||||
engine_.reset(gst_engine.release());
|
||||
|
@ -118,8 +118,8 @@ Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) {
|
|||
}
|
||||
#endif
|
||||
#ifdef HAVE_VLC
|
||||
case Engine::EngineType::VLC:
|
||||
use_enginetype = Engine::EngineType::VLC;
|
||||
case EngineBase::Type::VLC:
|
||||
use_enginetype = EngineBase::Type::VLC;
|
||||
engine_ = std::make_shared<VLCEngine>(app_->task_manager());
|
||||
break;
|
||||
#endif
|
||||
|
@ -127,7 +127,7 @@ Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) {
|
|||
if (i > 0) {
|
||||
qFatal("No engine available!");
|
||||
}
|
||||
enginetype = Engine::EngineType::None;
|
||||
enginetype = EngineBase::Type::None;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ Engine::EngineType Player::CreateEngine(Engine::EngineType enginetype) {
|
|||
if (use_enginetype != enginetype) { // Engine was set to something else. Reset output and device.
|
||||
QSettings s;
|
||||
s.beginGroup(BackendSettingsPage::kSettingsGroup);
|
||||
s.setValue("engine", EngineName(use_enginetype));
|
||||
s.setValue("engine", EngineBase::Name(use_enginetype));
|
||||
s.setValue("output", engine_->DefaultOutput());
|
||||
s.setValue("device", QVariant());
|
||||
s.endGroup();
|
||||
|
@ -157,7 +157,7 @@ void Player::Init() {
|
|||
|
||||
if (!engine_) {
|
||||
s.beginGroup(BackendSettingsPage::kSettingsGroup);
|
||||
Engine::EngineType enginetype = Engine::EngineTypeFromName(s.value("engine", EngineName(Engine::EngineType::GStreamer)).toString().toLower());
|
||||
EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::GStreamer)).toString().toLower());
|
||||
s.endGroup();
|
||||
CreateEngine(enginetype);
|
||||
}
|
||||
|
@ -363,9 +363,9 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) {
|
|||
|
||||
}
|
||||
|
||||
void Player::Next() { NextInternal(Engine::TrackChangeType::Manual, Playlist::AutoScroll::Always); }
|
||||
void Player::Next() { NextInternal(EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Always); }
|
||||
|
||||
void Player::NextInternal(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) {
|
||||
void Player::NextInternal(const EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) {
|
||||
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = 0;
|
||||
|
@ -376,7 +376,7 @@ void Player::NextInternal(const Engine::TrackChangeFlags change, const Playlist:
|
|||
|
||||
}
|
||||
|
||||
void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) {
|
||||
void Player::NextItem(const EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) {
|
||||
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = 0;
|
||||
|
@ -384,7 +384,7 @@ void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::Aut
|
|||
Playlist *active_playlist = app_->playlist_manager()->active();
|
||||
|
||||
// If we received too many errors in auto change, with repeat enabled, we stop
|
||||
if (change == Engine::TrackChangeType::Auto) {
|
||||
if (change == EngineBase::TrackChangeType::Auto) {
|
||||
const PlaylistSequence::RepeatMode repeat_mode = active_playlist->sequence()->repeat_mode();
|
||||
if (repeat_mode != PlaylistSequence::RepeatMode::Off) {
|
||||
if ((repeat_mode == PlaylistSequence::RepeatMode::Track && nb_errors_received_ >= 3) || (nb_errors_received_ >= app_->playlist_manager()->active()->filter()->rowCount())) {
|
||||
|
@ -397,7 +397,7 @@ void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::Aut
|
|||
}
|
||||
|
||||
// Manual track changes override "Repeat track"
|
||||
const bool ignore_repeat_track = change & Engine::TrackChangeType::Manual;
|
||||
const bool ignore_repeat_track = change & EngineBase::TrackChangeType::Manual;
|
||||
|
||||
int i = active_playlist->next_row(ignore_repeat_track);
|
||||
if (i == -1) {
|
||||
|
@ -413,10 +413,10 @@ void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::Aut
|
|||
}
|
||||
|
||||
void Player::PlayPlaylist(const QString &playlist_name) {
|
||||
PlayPlaylistInternal(Engine::TrackChangeType::Manual, Playlist::AutoScroll::Always, playlist_name);
|
||||
PlayPlaylistInternal(EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Always, playlist_name);
|
||||
}
|
||||
|
||||
void Player::PlayPlaylistInternal(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const QString &playlist_name) {
|
||||
void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const QString &playlist_name) {
|
||||
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = 0;
|
||||
|
@ -474,19 +474,19 @@ void Player::TrackEnded() {
|
|||
|
||||
if (HandleStopAfter(Playlist::AutoScroll::Maybe)) return;
|
||||
|
||||
NextInternal(Engine::TrackChangeType::Auto, Playlist::AutoScroll::Maybe);
|
||||
NextInternal(EngineBase::TrackChangeType::Auto, Playlist::AutoScroll::Maybe);
|
||||
|
||||
}
|
||||
|
||||
void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll autoscroll) {
|
||||
|
||||
switch (engine_->state()) {
|
||||
case Engine::State::Paused:
|
||||
case EngineBase::State::Paused:
|
||||
UnPause();
|
||||
emit Resumed();
|
||||
break;
|
||||
|
||||
case Engine::State::Playing: {
|
||||
case EngineBase::State::Playing: {
|
||||
if (current_item_->options() & PlaylistItem::Option::PauseDisabled) {
|
||||
Stop();
|
||||
}
|
||||
|
@ -498,9 +498,9 @@ void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll
|
|||
break;
|
||||
}
|
||||
|
||||
case Engine::State::Empty:
|
||||
case Engine::State::Error:
|
||||
case Engine::State::Idle: {
|
||||
case EngineBase::State::Empty:
|
||||
case EngineBase::State::Error:
|
||||
case EngineBase::State::Idle: {
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = offset_nanosec;
|
||||
app_->playlist_manager()->SetActivePlaylist(app_->playlist_manager()->current_id());
|
||||
|
@ -508,7 +508,7 @@ void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll
|
|||
int i = app_->playlist_manager()->active()->current_row();
|
||||
if (i == -1) i = app_->playlist_manager()->active()->last_played_row();
|
||||
if (i == -1) i = 0;
|
||||
PlayAt(i, offset_nanosec, Engine::TrackChangeType::First, autoscroll, true);
|
||||
PlayAt(i, offset_nanosec, EngineBase::TrackChangeType::First, autoscroll, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -572,14 +572,14 @@ bool Player::PreviousWouldRestartTrack() const {
|
|||
|
||||
}
|
||||
|
||||
void Player::Previous() { PreviousItem(Engine::TrackChangeType::Manual); }
|
||||
void Player::Previous() { PreviousItem(EngineBase::TrackChangeType::Manual); }
|
||||
|
||||
void Player::PreviousItem(const Engine::TrackChangeFlags change) {
|
||||
void Player::PreviousItem(const EngineBase::TrackChangeFlags change) {
|
||||
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = 0;
|
||||
|
||||
const bool ignore_repeat_track = change & Engine::TrackChangeType::Manual;
|
||||
const bool ignore_repeat_track = change & EngineBase::TrackChangeType::Manual;
|
||||
|
||||
if (menu_previousmode_ == BehaviourSettingsPage::PreviousBehaviour::Restart) {
|
||||
// Check if it has been over two seconds since previous button was pressed
|
||||
|
@ -604,9 +604,9 @@ void Player::PreviousItem(const Engine::TrackChangeFlags change) {
|
|||
|
||||
}
|
||||
|
||||
void Player::EngineStateChanged(const Engine::State state) {
|
||||
void Player::EngineStateChanged(const EngineBase::State state) {
|
||||
|
||||
if (state == Engine::State::Error) {
|
||||
if (state == EngineBase::State::Error) {
|
||||
nb_errors_received_++;
|
||||
}
|
||||
else {
|
||||
|
@ -614,21 +614,21 @@ void Player::EngineStateChanged(const Engine::State state) {
|
|||
}
|
||||
|
||||
switch (state) {
|
||||
case Engine::State::Paused:
|
||||
case EngineBase::State::Paused:
|
||||
pause_time_ = QDateTime::currentDateTime();
|
||||
play_offset_nanosec_ = engine_->position_nanosec();
|
||||
emit Paused();
|
||||
break;
|
||||
case Engine::State::Playing:
|
||||
case EngineBase::State::Playing:
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = 0;
|
||||
emit Playing();
|
||||
break;
|
||||
case Engine::State::Error:
|
||||
case EngineBase::State::Error:
|
||||
emit Error();
|
||||
[[fallthrough]];
|
||||
case Engine::State::Empty:
|
||||
case Engine::State::Idle:
|
||||
case EngineBase::State::Empty:
|
||||
case EngineBase::State::Idle:
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = 0;
|
||||
emit Stopped();
|
||||
|
@ -695,17 +695,17 @@ void Player::VolumeDown() {
|
|||
|
||||
}
|
||||
|
||||
void Player::PlayAt(const int index, const quint64 offset_nanosec, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform) {
|
||||
void Player::PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform) {
|
||||
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = offset_nanosec;
|
||||
|
||||
if (current_item_ && change == Engine::TrackChangeType::Manual && engine_->position_nanosec() != engine_->length_nanosec()) {
|
||||
if (current_item_ && change == EngineBase::TrackChangeType::Manual && engine_->position_nanosec() != engine_->length_nanosec()) {
|
||||
emit TrackSkipped(current_item_);
|
||||
}
|
||||
|
||||
if (current_item_ && app_->playlist_manager()->active()->has_item_at(index) && current_item_->Metadata().IsOnSameAlbum(app_->playlist_manager()->active()->item_at(index)->Metadata())) {
|
||||
change |= Engine::TrackChangeType::SameAlbum;
|
||||
change |= EngineBase::TrackChangeType::SameAlbum;
|
||||
}
|
||||
|
||||
if (reshuffle) app_->playlist_manager()->active()->ReshuffleIndices();
|
||||
|
@ -774,25 +774,25 @@ void Player::SeekBackward() {
|
|||
SeekTo(engine()->position_nanosec() / kNsecPerSec - seek_step_sec_);
|
||||
}
|
||||
|
||||
void Player::EngineMetadataReceived(const Engine::SimpleMetaBundle &bundle) {
|
||||
void Player::EngineMetadataReceived(const EngineMetadata &engine_metadata) {
|
||||
|
||||
if (bundle.type == Engine::SimpleMetaBundle::Type::Any || bundle.type == Engine::SimpleMetaBundle::Type::Current) {
|
||||
if (engine_metadata.type == EngineMetadata::Type::Any || engine_metadata.type == EngineMetadata::Type::Current) {
|
||||
PlaylistItemPtr item = app_->playlist_manager()->active()->current_item();
|
||||
if (item && bundle.media_url == item->Url()) {
|
||||
if (item && engine_metadata.media_url == item->Url()) {
|
||||
Song song = item->Metadata();
|
||||
bool minor = song.MergeFromSimpleMetaBundle(bundle);
|
||||
bool minor = song.MergeFromEngineMetadata(engine_metadata);
|
||||
app_->playlist_manager()->active()->SetStreamMetadata(item->Url(), song, minor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (bundle.type == Engine::SimpleMetaBundle::Type::Any || bundle.type == Engine::SimpleMetaBundle::Type::Next) {
|
||||
if (engine_metadata.type == EngineMetadata::Type::Any || engine_metadata.type == EngineMetadata::Type::Next) {
|
||||
int next_row = app_->playlist_manager()->active()->next_row();
|
||||
if (next_row != -1) {
|
||||
PlaylistItemPtr next_item = app_->playlist_manager()->active()->item_at(next_row);
|
||||
if (bundle.media_url == next_item->Url()) {
|
||||
if (engine_metadata.media_url == next_item->Url()) {
|
||||
Song song = next_item->Metadata();
|
||||
song.MergeFromSimpleMetaBundle(bundle);
|
||||
song.MergeFromEngineMetadata(engine_metadata);
|
||||
next_item->SetTemporaryMetadata(song);
|
||||
app_->playlist_manager()->active()->ItemChanged(next_row);
|
||||
}
|
||||
|
@ -828,10 +828,10 @@ void Player::Pause() { engine_->Pause(); }
|
|||
void Player::Play(const quint64 offset_nanosec) {
|
||||
|
||||
switch (GetState()) {
|
||||
case Engine::State::Playing:
|
||||
case EngineBase::State::Playing:
|
||||
SeekTo(offset_nanosec);
|
||||
break;
|
||||
case Engine::State::Paused:
|
||||
case EngineBase::State::Paused:
|
||||
UnPause();
|
||||
break;
|
||||
default:
|
||||
|
@ -929,7 +929,7 @@ void Player::InvalidSongRequested(const QUrl &url) {
|
|||
return;
|
||||
}
|
||||
|
||||
NextItem(Engine::TrackChangeType::Auto, Playlist::AutoScroll::Maybe);
|
||||
NextItem(EngineBase::TrackChangeType::Auto, Playlist::AutoScroll::Maybe);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
#include <QUrl>
|
||||
|
||||
#include "urlhandler.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginemetadata.h"
|
||||
#include "playlist/playlist.h"
|
||||
#include "playlist/playlistitem.h"
|
||||
#include "settings/behavioursettingspage.h"
|
||||
|
@ -48,10 +48,6 @@ class Equalizer;
|
|||
class GstStartup;
|
||||
#endif
|
||||
|
||||
namespace Engine {
|
||||
struct SimpleMetaBundle;
|
||||
} // namespace Engine
|
||||
|
||||
class PlayerInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -59,7 +55,7 @@ class PlayerInterface : public QObject {
|
|||
explicit PlayerInterface(QObject *parent = nullptr) : QObject(parent) {}
|
||||
|
||||
virtual EngineBase *engine() const = 0;
|
||||
virtual Engine::State GetState() const = 0;
|
||||
virtual EngineBase::State GetState() const = 0;
|
||||
virtual uint GetVolume() const = 0;
|
||||
|
||||
virtual PlaylistItemPtr GetCurrentItem() const = 0;
|
||||
|
@ -74,7 +70,7 @@ class PlayerInterface : public QObject {
|
|||
virtual void SaveVolume() = 0;
|
||||
|
||||
// Manual track change to the specified track
|
||||
virtual void PlayAt(const int index, const quint64 offset_nanosec, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0;
|
||||
virtual void PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0;
|
||||
|
||||
// If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist
|
||||
virtual void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) = 0;
|
||||
|
@ -138,11 +134,11 @@ class Player : public PlayerInterface {
|
|||
|
||||
static const char *kSettingsGroup;
|
||||
|
||||
Engine::EngineType CreateEngine(Engine::EngineType enginetype);
|
||||
EngineBase::Type CreateEngine(EngineBase::Type Type);
|
||||
void Init();
|
||||
|
||||
EngineBase *engine() const override { return engine_.get(); }
|
||||
Engine::State GetState() const override { return last_state_; }
|
||||
EngineBase::State GetState() const override { return last_state_; }
|
||||
uint GetVolume() const override;
|
||||
|
||||
PlaylistItemPtr GetCurrentItem() const override { return current_item_; }
|
||||
|
@ -163,7 +159,7 @@ class Player : public PlayerInterface {
|
|||
void LoadVolume() override;
|
||||
void SaveVolume() override;
|
||||
|
||||
void PlayAt(const int index, const quint64 offset_nanosec, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) override;
|
||||
void PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) override;
|
||||
void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) override;
|
||||
void PlayPauseHelper() override { PlayPause(play_offset_nanosec_); }
|
||||
void RestartOrPrevious() override;
|
||||
|
@ -193,19 +189,19 @@ class Player : public PlayerInterface {
|
|||
void HandleAuthentication();
|
||||
|
||||
signals:
|
||||
void EngineChanged(const Engine::EngineType enginetype);
|
||||
void EngineChanged(const EngineBase::Type Type);
|
||||
|
||||
private slots:
|
||||
void EngineStateChanged(const Engine::State);
|
||||
void EngineMetadataReceived(const Engine::SimpleMetaBundle &bundle);
|
||||
void EngineStateChanged(const EngineBase::State);
|
||||
void EngineMetadataReceived(const EngineMetadata &engine_metadata);
|
||||
void TrackAboutToEnd();
|
||||
void TrackEnded();
|
||||
// Play the next item on the playlist - disregarding radio stations like last.fm that might have more tracks.
|
||||
void NextItem(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll);
|
||||
void PreviousItem(const Engine::TrackChangeFlags change);
|
||||
void NextItem(const EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll);
|
||||
void PreviousItem(const EngineBase::TrackChangeFlags change);
|
||||
|
||||
void NextInternal(const Engine::TrackChangeFlags, const Playlist::AutoScroll autoscroll);
|
||||
void PlayPlaylistInternal(const Engine::TrackChangeFlags, const Playlist::AutoScroll autoscroll, const QString &playlist_name);
|
||||
void NextInternal(const EngineBase::TrackChangeFlags, const Playlist::AutoScroll autoscroll);
|
||||
void PlayPlaylistInternal(const EngineBase::TrackChangeFlags, const Playlist::AutoScroll autoscroll, const QString &playlist_name);
|
||||
|
||||
void FatalError();
|
||||
void ValidSongRequested(const QUrl&);
|
||||
|
@ -231,9 +227,9 @@ class Player : public PlayerInterface {
|
|||
|
||||
PlaylistItemPtr current_item_;
|
||||
|
||||
Engine::TrackChangeFlags stream_change_type_;
|
||||
EngineBase::TrackChangeFlags stream_change_type_;
|
||||
Playlist::AutoScroll autoscroll_;
|
||||
Engine::State last_state_;
|
||||
EngineBase::State last_state_;
|
||||
int nb_errors_received_;
|
||||
|
||||
QMap<QString, UrlHandler*> url_handlers_;
|
||||
|
|
|
@ -48,8 +48,7 @@
|
|||
#include <QStandardPaths>
|
||||
|
||||
#include "core/iconloader.h"
|
||||
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginemetadata.h"
|
||||
#include "utilities/strutils.h"
|
||||
#include "utilities/timeutils.h"
|
||||
#include "utilities/coverutils.h"
|
||||
|
@ -1386,7 +1385,7 @@ void Song::ToMTP(LIBMTP_track_t *track) const {
|
|||
}
|
||||
#endif
|
||||
|
||||
bool Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) {
|
||||
bool Song::MergeFromEngineMetadata(const EngineMetadata &engine_metadata) {
|
||||
|
||||
d->valid_ = true;
|
||||
|
||||
|
@ -1394,47 +1393,47 @@ bool Song::MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle) {
|
|||
|
||||
if (d->init_from_file_ || is_collection_song() || d->url_.isLocalFile()) {
|
||||
// This Song was already loaded using taglib. Our tags are probably better than the engine's.
|
||||
if (title() != bundle.title && title().isEmpty() && !bundle.title.isEmpty()) {
|
||||
set_title(bundle.title);
|
||||
if (title() != engine_metadata.title && title().isEmpty() && !engine_metadata.title.isEmpty()) {
|
||||
set_title(engine_metadata.title);
|
||||
minor = false;
|
||||
}
|
||||
if (artist() != bundle.artist && artist().isEmpty() && !bundle.artist.isEmpty()) {
|
||||
set_artist(bundle.artist);
|
||||
if (artist() != engine_metadata.artist && artist().isEmpty() && !engine_metadata.artist.isEmpty()) {
|
||||
set_artist(engine_metadata.artist);
|
||||
minor = false;
|
||||
}
|
||||
if (album() != bundle.album && album().isEmpty() && !bundle.album.isEmpty()) {
|
||||
set_album(bundle.album);
|
||||
if (album() != engine_metadata.album && album().isEmpty() && !engine_metadata.album.isEmpty()) {
|
||||
set_album(engine_metadata.album);
|
||||
minor = false;
|
||||
}
|
||||
if (comment().isEmpty() && !bundle.comment.isEmpty()) set_comment(bundle.comment);
|
||||
if (genre().isEmpty() && !bundle.genre.isEmpty()) set_genre(bundle.genre);
|
||||
if (lyrics().isEmpty() && !bundle.lyrics.isEmpty()) set_lyrics(bundle.lyrics);
|
||||
if (comment().isEmpty() && !engine_metadata.comment.isEmpty()) set_comment(engine_metadata.comment);
|
||||
if (genre().isEmpty() && !engine_metadata.genre.isEmpty()) set_genre(engine_metadata.genre);
|
||||
if (lyrics().isEmpty() && !engine_metadata.lyrics.isEmpty()) set_lyrics(engine_metadata.lyrics);
|
||||
}
|
||||
else {
|
||||
if (title() != bundle.title && !bundle.title.isEmpty()) {
|
||||
set_title(bundle.title);
|
||||
if (title() != engine_metadata.title && !engine_metadata.title.isEmpty()) {
|
||||
set_title(engine_metadata.title);
|
||||
minor = false;
|
||||
}
|
||||
if (artist() != bundle.artist && !bundle.artist.isEmpty()) {
|
||||
set_artist(bundle.artist);
|
||||
if (artist() != engine_metadata.artist && !engine_metadata.artist.isEmpty()) {
|
||||
set_artist(engine_metadata.artist);
|
||||
minor = false;
|
||||
}
|
||||
if (album() != bundle.album && !bundle.album.isEmpty()) {
|
||||
set_album(bundle.album);
|
||||
if (album() != engine_metadata.album && !engine_metadata.album.isEmpty()) {
|
||||
set_album(engine_metadata.album);
|
||||
minor = false;
|
||||
}
|
||||
if (!bundle.comment.isEmpty()) set_comment(bundle.comment);
|
||||
if (!bundle.genre.isEmpty()) set_genre(bundle.genre);
|
||||
if (!bundle.lyrics.isEmpty()) set_lyrics(bundle.lyrics);
|
||||
if (!engine_metadata.comment.isEmpty()) set_comment(engine_metadata.comment);
|
||||
if (!engine_metadata.genre.isEmpty()) set_genre(engine_metadata.genre);
|
||||
if (!engine_metadata.lyrics.isEmpty()) set_lyrics(engine_metadata.lyrics);
|
||||
}
|
||||
|
||||
if (bundle.length > 0) set_length_nanosec(bundle.length);
|
||||
if (bundle.year > 0) d->year_ = bundle.year;
|
||||
if (bundle.track > 0) d->track_ = bundle.track;
|
||||
if (bundle.filetype != FileType::Unknown) d->filetype_ = bundle.filetype;
|
||||
if (bundle.samplerate > 0) d->samplerate_ = bundle.samplerate;
|
||||
if (bundle.bitdepth > 0) d->bitdepth_ = bundle.bitdepth;
|
||||
if (bundle.bitrate > 0) d->bitrate_ = bundle.bitrate;
|
||||
if (engine_metadata.length > 0) set_length_nanosec(engine_metadata.length);
|
||||
if (engine_metadata.year > 0) d->year_ = engine_metadata.year;
|
||||
if (engine_metadata.track > 0) d->track_ = engine_metadata.track;
|
||||
if (engine_metadata.filetype != FileType::Unknown) d->filetype_ = engine_metadata.filetype;
|
||||
if (engine_metadata.samplerate > 0) d->samplerate_ = engine_metadata.samplerate;
|
||||
if (engine_metadata.bitdepth > 0) d->bitdepth_ = engine_metadata.bitdepth;
|
||||
if (engine_metadata.bitrate > 0) d->bitrate_ = engine_metadata.bitrate;
|
||||
|
||||
return minor;
|
||||
|
||||
|
|
|
@ -41,9 +41,7 @@
|
|||
|
||||
class SqlQuery;
|
||||
|
||||
namespace Engine {
|
||||
struct SimpleMetaBundle;
|
||||
} // namespace Engine
|
||||
class EngineMetadata;
|
||||
|
||||
namespace spb {
|
||||
namespace tagreader {
|
||||
|
@ -172,7 +170,7 @@ class Song {
|
|||
void InitArtManual();
|
||||
void InitArtAutomatic();
|
||||
|
||||
bool MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle);
|
||||
bool MergeFromEngineMetadata(const EngineMetadata &engine_metadata);
|
||||
|
||||
#ifdef HAVE_LIBGPOD
|
||||
void InitFromItdb(_Itdb_Track *track, const QString &prefix);
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
#include "tagreaderclient.h"
|
||||
#include "database.h"
|
||||
#include "sqlrow.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectionquery.h"
|
||||
|
@ -125,7 +124,7 @@ SongLoader::Result SongLoader::Load(const QUrl &url) {
|
|||
return Result::Success;
|
||||
}
|
||||
|
||||
if (player_->engine()->type() == Engine::EngineType::GStreamer) {
|
||||
if (player_->engine()->type() == EngineBase::Type::GStreamer) {
|
||||
#ifdef HAVE_GSTREAMER
|
||||
preload_func_ = std::bind(&SongLoader::LoadRemote, this);
|
||||
return Result::BlockingLoadRequired;
|
||||
|
@ -190,7 +189,7 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) {
|
|||
SongLoader::Result SongLoader::LoadAudioCD() {
|
||||
|
||||
#if defined(HAVE_AUDIOCD) && defined(HAVE_GSTREAMER)
|
||||
if (player_->engine()->type() == Engine::EngineType::GStreamer) {
|
||||
if (player_->engine()->type() == EngineBase::Type::GStreamer) {
|
||||
CddaSongLoader *cdda_song_loader = new CddaSongLoader(QUrl(), this);
|
||||
QObject::connect(cdda_song_loader, &CddaSongLoader::SongsDurationLoaded, this, &SongLoader::AudioCDTracksLoadFinishedSlot);
|
||||
QObject::connect(cdda_song_loader, &CddaSongLoader::SongsMetadataLoaded, this, &SongLoader::AudioCDTracksTagsLoaded);
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
#ifndef ENGINE_FWD_H
|
||||
#define ENGINE_FWD_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
/// Used by eg engineobserver.h, and thus we reduce header dependencies on enginebase.h
|
||||
|
||||
namespace Engine {
|
||||
|
||||
struct SimpleMetaBundle;
|
||||
class Base;
|
||||
|
||||
/**
|
||||
* You should return:
|
||||
* Playing when playing,
|
||||
* Paused when paused
|
||||
* Idle when you still have a URL loaded (ie you have not been told to stop())
|
||||
* Empty when you have been told to stop(),
|
||||
* Error when an error occurred and you stopped yourself
|
||||
*
|
||||
* It is vital to be Idle just after the track has ended!
|
||||
*/
|
||||
enum class State {
|
||||
Empty,
|
||||
Idle,
|
||||
Playing,
|
||||
Paused,
|
||||
Error
|
||||
};
|
||||
|
||||
enum TrackChangeType {
|
||||
// One of:
|
||||
First = 0x01,
|
||||
Manual = 0x02,
|
||||
Auto = 0x04,
|
||||
Intro = 0x08,
|
||||
|
||||
// Any of:
|
||||
SameAlbum = 0x10
|
||||
};
|
||||
|
||||
Q_DECLARE_FLAGS(TrackChangeFlags, TrackChangeType)
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
using EngineBase = Engine::Base;
|
||||
|
||||
Q_DECLARE_METATYPE(Engine::State)
|
||||
Q_DECLARE_METATYPE(Engine::TrackChangeType)
|
||||
|
||||
#endif // ENGINE_FWD_H
|
|
@ -33,14 +33,12 @@
|
|||
#include "utilities/envutils.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "core/networkproxyfactory.h"
|
||||
#include "engine_fwd.h"
|
||||
#include "enginebase.h"
|
||||
#include "settings/backendsettingspage.h"
|
||||
#include "settings/networkproxysettingspage.h"
|
||||
|
||||
Engine::Base::Base(const EngineType type, QObject *parent)
|
||||
EngineBase::EngineBase(QObject *parent)
|
||||
: QObject(parent),
|
||||
type_(type),
|
||||
volume_control_(true),
|
||||
volume_(100),
|
||||
beginning_nanosec_(0),
|
||||
|
@ -73,9 +71,40 @@ Engine::Base::Base(const EngineType type, QObject *parent)
|
|||
strict_ssl_enabled_(false),
|
||||
about_to_end_emitted_(false) {}
|
||||
|
||||
Engine::Base::~Base() = default;
|
||||
EngineBase::~EngineBase() = default;
|
||||
|
||||
bool Engine::Base::Load(const QUrl &media_url, const QUrl &stream_url, const TrackChangeFlags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) {
|
||||
EngineBase::Type EngineBase::TypeFromName(const QString &name) {
|
||||
|
||||
if (name.compare("gstreamer", Qt::CaseInsensitive) == 0) return Type::GStreamer;
|
||||
if (name.compare("vlc", Qt::CaseInsensitive) == 0) return Type::VLC;
|
||||
|
||||
return Type::None;
|
||||
|
||||
}
|
||||
|
||||
QString EngineBase::Name(const Type type) {
|
||||
|
||||
switch (type) {
|
||||
case Type::GStreamer: return QString("gstreamer");
|
||||
case Type::VLC: return QString("vlc");
|
||||
case Type::None:
|
||||
default: return QString("None");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString EngineBase::Description(const Type type) {
|
||||
|
||||
switch (type) {
|
||||
case Type::GStreamer: return QString("GStreamer");
|
||||
case Type::VLC: return QString("VLC");
|
||||
case Type::None:
|
||||
default: return QString("None");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool EngineBase::Load(const QUrl &media_url, const QUrl &stream_url, const TrackChangeFlags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) {
|
||||
|
||||
Q_UNUSED(force_stop_at_end);
|
||||
|
||||
|
@ -90,7 +119,7 @@ bool Engine::Base::Load(const QUrl &media_url, const QUrl &stream_url, const Tra
|
|||
|
||||
}
|
||||
|
||||
bool Engine::Base::Play(const QUrl &media_url, const QUrl &stream_url, const TrackChangeFlags flags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec, const quint64 offset_nanosec) {
|
||||
bool EngineBase::Play(const QUrl &media_url, const QUrl &stream_url, const TrackChangeFlags flags, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec, const quint64 offset_nanosec) {
|
||||
|
||||
if (!Load(media_url, stream_url, flags, force_stop_at_end, beginning_nanosec, end_nanosec)) {
|
||||
return false;
|
||||
|
@ -100,21 +129,21 @@ bool Engine::Base::Play(const QUrl &media_url, const QUrl &stream_url, const Tra
|
|||
|
||||
}
|
||||
|
||||
void Engine::Base::UpdateVolume(const uint volume) {
|
||||
void EngineBase::UpdateVolume(const uint volume) {
|
||||
|
||||
volume_ = volume;
|
||||
emit VolumeChanged(volume);
|
||||
|
||||
}
|
||||
|
||||
void Engine::Base::SetVolume(const uint volume) {
|
||||
void EngineBase::SetVolume(const uint volume) {
|
||||
|
||||
volume_ = volume;
|
||||
SetVolumeSW(volume);
|
||||
|
||||
}
|
||||
|
||||
void Engine::Base::ReloadSettings() {
|
||||
void EngineBase::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
|
||||
|
@ -190,7 +219,7 @@ void Engine::Base::ReloadSettings() {
|
|||
|
||||
}
|
||||
|
||||
void Engine::Base::EmitAboutToFinish() {
|
||||
void EngineBase::EmitAboutToFinish() {
|
||||
|
||||
if (about_to_end_emitted_) {
|
||||
return;
|
||||
|
@ -202,7 +231,7 @@ void Engine::Base::EmitAboutToFinish() {
|
|||
|
||||
}
|
||||
|
||||
bool Engine::Base::ValidOutput(const QString &output) {
|
||||
bool EngineBase::ValidOutput(const QString &output) {
|
||||
|
||||
Q_UNUSED(output);
|
||||
|
||||
|
|
|
@ -38,25 +38,54 @@
|
|||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include "engine_fwd.h"
|
||||
#include "enginetype.h"
|
||||
#include "devicefinders.h"
|
||||
#include "enginemetadata.h"
|
||||
#include "core/song.h"
|
||||
|
||||
namespace Engine {
|
||||
|
||||
struct SimpleMetaBundle;
|
||||
|
||||
using Scope = std::vector<int16_t>;
|
||||
|
||||
class Base : public QObject {
|
||||
class EngineBase : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
Base(const EngineType type = EngineType::None, QObject *parent = nullptr);
|
||||
EngineBase(QObject *parent = nullptr);
|
||||
|
||||
public:
|
||||
~Base() override;
|
||||
~EngineBase() override;
|
||||
|
||||
enum class Type {
|
||||
None,
|
||||
GStreamer,
|
||||
VLC,
|
||||
Xine
|
||||
};
|
||||
|
||||
// State:
|
||||
// Playing when playing,
|
||||
// Paused when paused
|
||||
// Idle when you still have a URL loaded (ie you have not been told to stop())
|
||||
// Empty when you have been told to stop(),
|
||||
// Error when an error occurred and you stopped yourself
|
||||
//
|
||||
// It is vital to be Idle just after the track has ended!
|
||||
|
||||
enum class State {
|
||||
Empty,
|
||||
Idle,
|
||||
Playing,
|
||||
Paused,
|
||||
Error
|
||||
};
|
||||
|
||||
enum TrackChangeType {
|
||||
// One of:
|
||||
First = 0x01,
|
||||
Manual = 0x02,
|
||||
Auto = 0x04,
|
||||
Intro = 0x08,
|
||||
|
||||
// Any of:
|
||||
SameAlbum = 0x10
|
||||
};
|
||||
Q_DECLARE_FLAGS(TrackChangeFlags, TrackChangeType)
|
||||
|
||||
struct OutputDetails {
|
||||
QString name;
|
||||
|
@ -65,6 +94,13 @@ class Base : public QObject {
|
|||
};
|
||||
using OutputDetailsList = QList<OutputDetails>;
|
||||
|
||||
using Scope = std::vector<int16_t>;
|
||||
|
||||
static Type TypeFromName(const QString &name);
|
||||
static QString Name(const Type type);
|
||||
static QString Description(const Type type);
|
||||
|
||||
virtual Type type() const = 0;
|
||||
virtual bool Init() = 0;
|
||||
virtual State state() const = 0;
|
||||
virtual void StartPreloading(const QUrl&, const QUrl&, const bool, const qint64, const qint64) {}
|
||||
|
@ -105,9 +141,7 @@ class Base : public QObject {
|
|||
void EmitAboutToFinish();
|
||||
|
||||
public:
|
||||
|
||||
// Simple accessors
|
||||
EngineType type() const { return type_; }
|
||||
bool volume_control() const { return volume_control_; }
|
||||
inline uint volume() const { return volume_; }
|
||||
|
||||
|
@ -145,16 +179,15 @@ class Base : public QObject {
|
|||
// Emitted when Engine successfully started playing a song with the given QUrl.
|
||||
void ValidSongRequested(const QUrl &url);
|
||||
|
||||
void MetaData(const Engine::SimpleMetaBundle &bundle);
|
||||
void MetaData(const EngineMetadata &metadata);
|
||||
|
||||
// Signals that the engine's state has changed (a stream was stopped for example).
|
||||
// Always use the state from event, because it's not guaranteed that immediate subsequent call to state() won't return a stale value.
|
||||
void StateChanged(const Engine::State state);
|
||||
void StateChanged(const State state);
|
||||
|
||||
void VolumeChanged(const uint volume);
|
||||
|
||||
protected:
|
||||
EngineType type_;
|
||||
bool volume_control_;
|
||||
uint volume_;
|
||||
quint64 beginning_nanosec_;
|
||||
|
@ -208,38 +241,13 @@ class Base : public QObject {
|
|||
bool strict_ssl_enabled_;
|
||||
|
||||
bool about_to_end_emitted_;
|
||||
Q_DISABLE_COPY(Base)
|
||||
|
||||
Q_DISABLE_COPY(EngineBase)
|
||||
};
|
||||
|
||||
struct SimpleMetaBundle {
|
||||
SimpleMetaBundle() : type(Type::Any), length(-1), year(-1), track(-1), filetype(Song::FileType::Unknown), samplerate(-1), bitdepth(-1), bitrate(-1) {}
|
||||
enum class Type {
|
||||
Any,
|
||||
Current,
|
||||
Next
|
||||
};
|
||||
Type type;
|
||||
QUrl media_url;
|
||||
QUrl stream_url;
|
||||
QString title;
|
||||
QString artist;
|
||||
QString album;
|
||||
QString comment;
|
||||
QString genre;
|
||||
qint64 length;
|
||||
int year;
|
||||
int track;
|
||||
Song::FileType filetype;
|
||||
int samplerate;
|
||||
int bitdepth;
|
||||
int bitrate;
|
||||
QString lyrics;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
Q_DECLARE_METATYPE(EngineBase::Type);
|
||||
Q_DECLARE_METATYPE(EngineBase::State)
|
||||
Q_DECLARE_METATYPE(EngineBase::TrackChangeType)
|
||||
Q_DECLARE_METATYPE(EngineBase::OutputDetails)
|
||||
Q_DECLARE_METATYPE(Engine::SimpleMetaBundle)
|
||||
|
||||
#endif // ENGINEBASE_H
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "enginemetadata.h"
|
||||
#include "core/song.h"
|
||||
|
||||
EngineMetadata::EngineMetadata()
|
||||
: type(Type::Any),
|
||||
length(-1),
|
||||
year(-1),
|
||||
track(-1),
|
||||
filetype(Song::FileType::Unknown),
|
||||
samplerate(-1),
|
||||
bitdepth(-1),
|
||||
bitrate(-1) {}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2018-2023, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ENGINEMETADATA_H
|
||||
#define ENGINEMETADATA_H
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include "core/song.h"
|
||||
|
||||
class EngineMetadata {
|
||||
public:
|
||||
EngineMetadata();
|
||||
enum class Type {
|
||||
Any,
|
||||
Current,
|
||||
Next
|
||||
};
|
||||
Type type;
|
||||
QUrl media_url;
|
||||
QUrl stream_url;
|
||||
QString title;
|
||||
QString artist;
|
||||
QString album;
|
||||
QString comment;
|
||||
QString genre;
|
||||
qint64 length;
|
||||
int year;
|
||||
int track;
|
||||
Song::FileType filetype;
|
||||
int samplerate;
|
||||
int bitdepth;
|
||||
int bitrate;
|
||||
QString lyrics;
|
||||
};
|
||||
Q_DECLARE_METATYPE(EngineMetadata)
|
||||
|
||||
#endif // ENGINEMETADATA_H
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2013-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "enginetype.h"
|
||||
|
||||
namespace Engine {
|
||||
|
||||
Engine::EngineType EngineTypeFromName(const QString &enginename) {
|
||||
QString lower = enginename.toLower();
|
||||
if (lower == "gstreamer") return Engine::EngineType::GStreamer;
|
||||
else if (lower == "vlc") return Engine::EngineType::VLC;
|
||||
else return Engine::EngineType::None;
|
||||
}
|
||||
|
||||
QString EngineName(const Engine::EngineType enginetype) {
|
||||
switch (enginetype) {
|
||||
case Engine::EngineType::GStreamer: return QString("gstreamer");
|
||||
case Engine::EngineType::VLC: return QString("vlc");
|
||||
case Engine::EngineType::None:
|
||||
default: return QString("None");
|
||||
}
|
||||
}
|
||||
|
||||
QString EngineDescription(Engine::EngineType enginetype) {
|
||||
switch (enginetype) {
|
||||
case Engine::EngineType::GStreamer: return QString("GStreamer");
|
||||
case Engine::EngineType::VLC: return QString("VLC");
|
||||
case Engine::EngineType::None:
|
||||
default: return QString("None");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Engine
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2013-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ENGINETYPE_H
|
||||
#define ENGINETYPE_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
enum class EngineType {
|
||||
None,
|
||||
GStreamer,
|
||||
VLC,
|
||||
Xine
|
||||
};
|
||||
|
||||
Engine::EngineType EngineTypeFromName(const QString &enginename);
|
||||
QString EngineName(const Engine::EngineType enginetype);
|
||||
QString EngineDescription(const Engine::EngineType enginetype);
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
Q_DECLARE_METATYPE(Engine::EngineType)
|
||||
|
||||
#endif // ENGINETYPE_H
|
|
@ -52,10 +52,10 @@
|
|||
#include "core/signalchecker.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "enginebase.h"
|
||||
#include "enginetype.h"
|
||||
#include "gstengine.h"
|
||||
#include "gstenginepipeline.h"
|
||||
#include "gstbufferconsumer.h"
|
||||
#include "enginemetadata.h"
|
||||
|
||||
const char *GstEngine::kAutoSink = "autoaudiosink";
|
||||
const char *GstEngine::kALSASink = "alsasink";
|
||||
|
@ -75,7 +75,7 @@ const qint64 GstEngine::kPreloadGapNanosec = 8000 * kNsecPerMsec; // 8s
|
|||
const qint64 GstEngine::kSeekDelayNanosec = 100 * kNsecPerMsec; // 100msec
|
||||
|
||||
GstEngine::GstEngine(TaskManager *task_manager, QObject *parent)
|
||||
: Engine::Base(Engine::EngineType::GStreamer, parent),
|
||||
: EngineBase(parent),
|
||||
task_manager_(task_manager),
|
||||
gst_startup_(nullptr),
|
||||
discoverer_(nullptr),
|
||||
|
@ -138,21 +138,21 @@ bool GstEngine::Init() {
|
|||
|
||||
}
|
||||
|
||||
Engine::State GstEngine::state() const {
|
||||
EngineBase::State GstEngine::state() const {
|
||||
|
||||
if (!current_pipeline_) return stream_url_.isEmpty() ? Engine::State::Empty : Engine::State::Idle;
|
||||
if (!current_pipeline_) return stream_url_.isEmpty() ? EngineBase::State::Empty : EngineBase::State::Idle;
|
||||
|
||||
switch (current_pipeline_->state()) {
|
||||
case GST_STATE_NULL:
|
||||
return Engine::State::Empty;
|
||||
return EngineBase::State::Empty;
|
||||
case GST_STATE_READY:
|
||||
return Engine::State::Idle;
|
||||
return EngineBase::State::Idle;
|
||||
case GST_STATE_PLAYING:
|
||||
return Engine::State::Playing;
|
||||
return EngineBase::State::Playing;
|
||||
case GST_STATE_PAUSED:
|
||||
return Engine::State::Paused;
|
||||
return EngineBase::State::Paused;
|
||||
default:
|
||||
return Engine::State::Empty;
|
||||
return EngineBase::State::Empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -176,21 +176,21 @@ void GstEngine::StartPreloading(const QUrl &media_url, const QUrl &stream_url, c
|
|||
|
||||
}
|
||||
|
||||
bool GstEngine::Load(const QUrl &media_url, const QUrl &stream_url, const Engine::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) {
|
||||
bool GstEngine::Load(const QUrl &media_url, const QUrl &stream_url, const EngineBase::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) {
|
||||
|
||||
EnsureInitialized();
|
||||
|
||||
Engine::Base::Load(stream_url, media_url, change, force_stop_at_end, beginning_nanosec, end_nanosec);
|
||||
EngineBase::Load(stream_url, media_url, change, force_stop_at_end, beginning_nanosec, end_nanosec);
|
||||
|
||||
const QByteArray gst_url = FixupUrl(stream_url);
|
||||
|
||||
bool crossfade = current_pipeline_ && ((crossfade_enabled_ && change & Engine::TrackChangeType::Manual) || (autocrossfade_enabled_ && change & Engine::TrackChangeType::Auto) || ((crossfade_enabled_ || autocrossfade_enabled_) && change & Engine::TrackChangeType::Intro));
|
||||
bool crossfade = current_pipeline_ && ((crossfade_enabled_ && change & EngineBase::TrackChangeType::Manual) || (autocrossfade_enabled_ && change & EngineBase::TrackChangeType::Auto) || ((crossfade_enabled_ || autocrossfade_enabled_) && change & EngineBase::TrackChangeType::Intro));
|
||||
|
||||
if (change & Engine::TrackChangeType::Auto && change & Engine::TrackChangeType::SameAlbum && !crossfade_same_album_) {
|
||||
if (change & EngineBase::TrackChangeType::Auto && change & EngineBase::TrackChangeType::SameAlbum && !crossfade_same_album_) {
|
||||
crossfade = false;
|
||||
}
|
||||
|
||||
if (!crossfade && current_pipeline_ && current_pipeline_->stream_url() == stream_url && change & Engine::TrackChangeType::Auto) {
|
||||
if (!crossfade && current_pipeline_ && current_pipeline_->stream_url() == stream_url && change & EngineBase::TrackChangeType::Auto) {
|
||||
// We're not crossfading, and the pipeline is already playing the URI we want, so just do nothing.
|
||||
return true;
|
||||
}
|
||||
|
@ -279,7 +279,7 @@ void GstEngine::Stop(const bool stop_after) {
|
|||
|
||||
current_pipeline_.reset();
|
||||
BufferingFinished();
|
||||
emit StateChanged(Engine::State::Empty);
|
||||
emit StateChanged(EngineBase::State::Empty);
|
||||
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,7 @@ void GstEngine::Pause() {
|
|||
current_pipeline_->StartFader(fadeout_pause_duration_nanosec_, QTimeLine::Forward, QEasingCurve::InOutQuad, false);
|
||||
is_fading_out_to_pause_ = false;
|
||||
has_faded_out_ = false;
|
||||
emit StateChanged(Engine::State::Playing);
|
||||
emit StateChanged(EngineBase::State::Playing);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -303,7 +303,7 @@ void GstEngine::Pause() {
|
|||
}
|
||||
else {
|
||||
current_pipeline_->SetState(GST_STATE_PAUSED);
|
||||
emit StateChanged(Engine::State::Paused);
|
||||
emit StateChanged(EngineBase::State::Paused);
|
||||
StopTimers();
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ void GstEngine::Unpause() {
|
|||
has_faded_out_ = false;
|
||||
}
|
||||
|
||||
emit StateChanged(Engine::State::Playing);
|
||||
emit StateChanged(EngineBase::State::Playing);
|
||||
|
||||
StartTimers();
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ qint64 GstEngine::length_nanosec() const {
|
|||
|
||||
}
|
||||
|
||||
const Engine::Scope &GstEngine::scope(const int chunk_length) {
|
||||
const EngineBase::Scope &GstEngine::scope(const int chunk_length) {
|
||||
|
||||
// The new buffer could have a different size
|
||||
if (have_new_buffer_) {
|
||||
|
@ -448,7 +448,7 @@ bool GstEngine::ALSADeviceSupport(const QString &output) {
|
|||
|
||||
void GstEngine::ReloadSettings() {
|
||||
|
||||
Engine::Base::ReloadSettings();
|
||||
EngineBase::ReloadSettings();
|
||||
|
||||
if (output_.isEmpty()) output_ = kAutoSink;
|
||||
|
||||
|
@ -553,7 +553,7 @@ void GstEngine::HandlePipelineError(const int pipeline_id, const int domain, con
|
|||
|
||||
current_pipeline_.reset();
|
||||
BufferingFinished();
|
||||
emit StateChanged(Engine::State::Error);
|
||||
emit StateChanged(EngineBase::State::Error);
|
||||
|
||||
if (
|
||||
(domain == static_cast<int>(GST_RESOURCE_ERROR) && (
|
||||
|
@ -574,10 +574,10 @@ void GstEngine::HandlePipelineError(const int pipeline_id, const int domain, con
|
|||
|
||||
}
|
||||
|
||||
void GstEngine::NewMetaData(const int pipeline_id, const Engine::SimpleMetaBundle &bundle) {
|
||||
void GstEngine::NewMetaData(const int pipeline_id, const EngineMetadata &engine_metadata) {
|
||||
|
||||
if (!current_pipeline_|| current_pipeline_->id() != pipeline_id) return;
|
||||
emit MetaData(bundle);
|
||||
emit MetaData(engine_metadata);
|
||||
|
||||
}
|
||||
|
||||
|
@ -609,7 +609,7 @@ void GstEngine::FadeoutPauseFinished() {
|
|||
|
||||
fadeout_pause_pipeline_->SetState(GST_STATE_PAUSED);
|
||||
current_pipeline_->SetState(GST_STATE_PAUSED);
|
||||
emit StateChanged(Engine::State::Paused);
|
||||
emit StateChanged(EngineBase::State::Paused);
|
||||
StopTimers();
|
||||
|
||||
is_fading_out_to_pause_ = false;
|
||||
|
@ -664,7 +664,7 @@ void GstEngine::PlayDone(const GstStateChangeReturn ret, const quint64 offset_na
|
|||
Seek(offset_nanosec);
|
||||
}
|
||||
|
||||
emit StateChanged(Engine::State::Playing);
|
||||
emit StateChanged(EngineBase::State::Playing);
|
||||
// We've successfully started playing a media stream with this url
|
||||
emit ValidSongRequested(stream_url_);
|
||||
|
||||
|
@ -819,7 +819,7 @@ std::shared_ptr<GstEnginePipeline> GstEngine::CreatePipeline(const QUrl &media_u
|
|||
if (!ret->InitFromUrl(media_url, stream_url, gst_url, end_nanosec, error)) {
|
||||
ret.reset();
|
||||
emit Error(error);
|
||||
emit StateChanged(Engine::State::Error);
|
||||
emit StateChanged(EngineBase::State::Error);
|
||||
emit FatalError();
|
||||
}
|
||||
|
||||
|
@ -829,7 +829,7 @@ std::shared_ptr<GstEnginePipeline> GstEngine::CreatePipeline(const QUrl &media_u
|
|||
|
||||
void GstEngine::UpdateScope(const int chunk_length) {
|
||||
|
||||
using sample_type = Engine::Scope::value_type;
|
||||
using sample_type = EngineBase::Scope::value_type;
|
||||
|
||||
// Prevent dbz or invalid chunk size
|
||||
if (!GST_CLOCK_TIME_IS_VALID(GST_BUFFER_DURATION(latest_buffer_))) return;
|
||||
|
@ -858,10 +858,10 @@ void GstEngine::UpdateScope(const int chunk_length) {
|
|||
|
||||
// Make sure we don't go beyond the end of the buffer
|
||||
if (scope_chunk_ == scope_chunks_ - 1) {
|
||||
bytes = qMin(static_cast<Engine::Scope::size_type>(map.size - (chunk_size * scope_chunk_)), scope_.size() * sizeof(sample_type));
|
||||
bytes = qMin(static_cast<EngineBase::Scope::size_type>(map.size - (chunk_size * scope_chunk_)), scope_.size() * sizeof(sample_type));
|
||||
}
|
||||
else {
|
||||
bytes = qMin(static_cast<Engine::Scope::size_type>(chunk_size), scope_.size() * sizeof(sample_type));
|
||||
bytes = qMin(static_cast<EngineBase::Scope::size_type>(chunk_size), scope_.size() * sizeof(sample_type));
|
||||
}
|
||||
|
||||
scope_chunk_++;
|
||||
|
@ -908,20 +908,20 @@ void GstEngine::StreamDiscovered(GstDiscoverer*, GstDiscovererInfo *info, GError
|
|||
|
||||
GstDiscovererStreamInfo *stream_info = reinterpret_cast<GstDiscovererStreamInfo*>(g_list_first(audio_streams)->data);
|
||||
|
||||
Engine::SimpleMetaBundle bundle;
|
||||
EngineMetadata engine_metadata;
|
||||
if (discovered_url == instance->current_pipeline_->gst_url()) {
|
||||
bundle.type = Engine::SimpleMetaBundle::Type::Current;
|
||||
bundle.media_url = instance->current_pipeline_->media_url();
|
||||
bundle.stream_url = instance->current_pipeline_->stream_url();
|
||||
engine_metadata.type = EngineMetadata::Type::Current;
|
||||
engine_metadata.media_url = instance->current_pipeline_->media_url();
|
||||
engine_metadata.stream_url = instance->current_pipeline_->stream_url();
|
||||
}
|
||||
else if (discovered_url == instance->current_pipeline_->next_gst_url()) {
|
||||
bundle.type = Engine::SimpleMetaBundle::Type::Next;
|
||||
bundle.media_url = instance->current_pipeline_->next_media_url();
|
||||
bundle.stream_url = instance->current_pipeline_->next_stream_url();
|
||||
engine_metadata.type = EngineMetadata::Type::Next;
|
||||
engine_metadata.media_url = instance->current_pipeline_->next_media_url();
|
||||
engine_metadata.stream_url = instance->current_pipeline_->next_stream_url();
|
||||
}
|
||||
bundle.samplerate = static_cast<int>(gst_discoverer_audio_info_get_sample_rate(GST_DISCOVERER_AUDIO_INFO(stream_info)));
|
||||
bundle.bitdepth = static_cast<int>(gst_discoverer_audio_info_get_depth(GST_DISCOVERER_AUDIO_INFO(stream_info)));
|
||||
bundle.bitrate = static_cast<int>(gst_discoverer_audio_info_get_bitrate(GST_DISCOVERER_AUDIO_INFO(stream_info)) / 1000);
|
||||
engine_metadata.samplerate = static_cast<int>(gst_discoverer_audio_info_get_sample_rate(GST_DISCOVERER_AUDIO_INFO(stream_info)));
|
||||
engine_metadata.bitdepth = static_cast<int>(gst_discoverer_audio_info_get_depth(GST_DISCOVERER_AUDIO_INFO(stream_info)));
|
||||
engine_metadata.bitrate = static_cast<int>(gst_discoverer_audio_info_get_bitrate(GST_DISCOVERER_AUDIO_INFO(stream_info)) / 1000);
|
||||
|
||||
GstCaps *caps = gst_discoverer_stream_info_get_caps(stream_info);
|
||||
|
||||
|
@ -931,20 +931,20 @@ void GstEngine::StreamDiscovered(GstDiscoverer*, GstDiscovererInfo *info, GError
|
|||
if (!gst_structure) continue;
|
||||
QString mimetype = gst_structure_get_name(gst_structure);
|
||||
if (!mimetype.isEmpty() && mimetype != "audio/mpeg") {
|
||||
bundle.filetype = Song::FiletypeByMimetype(mimetype);
|
||||
if (bundle.filetype == Song::FileType::Unknown) {
|
||||
engine_metadata.filetype = Song::FiletypeByMimetype(mimetype);
|
||||
if (engine_metadata.filetype == Song::FileType::Unknown) {
|
||||
qLog(Error) << "Unknown mimetype" << mimetype;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bundle.filetype == Song::FileType::Unknown) {
|
||||
if (engine_metadata.filetype == Song::FileType::Unknown) {
|
||||
gchar *codec_description = gst_pb_utils_get_codec_description(caps);
|
||||
QString filetype_description = (codec_description ? QString(codec_description) : QString());
|
||||
g_free(codec_description);
|
||||
if (!filetype_description.isEmpty()) {
|
||||
bundle.filetype = Song::FiletypeByDescription(filetype_description);
|
||||
if (bundle.filetype == Song::FileType::Unknown) {
|
||||
engine_metadata.filetype = Song::FiletypeByDescription(filetype_description);
|
||||
if (engine_metadata.filetype == Song::FileType::Unknown) {
|
||||
qLog(Error) << "Unknown filetype" << filetype_description;
|
||||
}
|
||||
}
|
||||
|
@ -953,9 +953,9 @@ void GstEngine::StreamDiscovered(GstDiscoverer*, GstDiscovererInfo *info, GError
|
|||
gst_caps_unref(caps);
|
||||
gst_discoverer_stream_info_list_free(audio_streams);
|
||||
|
||||
qLog(Debug) << "Got stream info for" << discovered_url + ":" << Song::TextForFiletype(bundle.filetype);
|
||||
qLog(Debug) << "Got stream info for" << discovered_url + ":" << Song::TextForFiletype(engine_metadata.filetype);
|
||||
|
||||
emit instance->MetaData(bundle);
|
||||
emit instance->MetaData(engine_metadata);
|
||||
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <QUrl>
|
||||
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "engine_fwd.h"
|
||||
#include "enginebase.h"
|
||||
#include "gststartup.h"
|
||||
#include "gstbufferconsumer.h"
|
||||
|
@ -49,7 +48,7 @@ class QTimerEvent;
|
|||
class TaskManager;
|
||||
class GstEnginePipeline;
|
||||
|
||||
class GstEngine : public Engine::Base, public GstBufferConsumer {
|
||||
class GstEngine : public EngineBase, public GstBufferConsumer {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -58,10 +57,11 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
|
|||
|
||||
static const char *kAutoSink;
|
||||
|
||||
Type type() const override { return Type::GStreamer; }
|
||||
bool Init() override;
|
||||
Engine::State state() const override;
|
||||
EngineBase::State state() const override;
|
||||
void StartPreloading(const QUrl &media_url, const QUrl &stream_url, const bool force_stop_at_end, const qint64 beginning_nanosec, const qint64 end_nanosec) override;
|
||||
bool Load(const QUrl &media_url, const QUrl &stream_url, const Engine::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) override;
|
||||
bool Load(const QUrl &media_url, const QUrl &stream_url, const EngineBase::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) override;
|
||||
bool Play(const quint64 offset_nanosec) override;
|
||||
void Stop(const bool stop_after = false) override;
|
||||
void Pause() override;
|
||||
|
@ -74,7 +74,7 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
|
|||
public:
|
||||
qint64 position_nanosec() const override;
|
||||
qint64 length_nanosec() const override;
|
||||
const Engine::Scope &scope(const int chunk_length) override;
|
||||
const EngineBase::Scope &scope(const int chunk_length) override;
|
||||
|
||||
OutputDetailsList GetOutputsList() const override;
|
||||
bool ValidOutput(const QString &output) override;
|
||||
|
@ -111,7 +111,7 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
|
|||
private slots:
|
||||
void EndOfStreamReached(const int pipeline_id, const bool has_next_track);
|
||||
void HandlePipelineError(const int pipeline_id, const int domain, const int error_code, const QString &message, const QString &debugstr);
|
||||
void NewMetaData(const int pipeline_id, const Engine::SimpleMetaBundle &bundle);
|
||||
void NewMetaData(const int pipeline_id, const EngineMetadata &engine_metadata);
|
||||
void AddBufferToScope(GstBuffer *buf, const int pipeline_id, const QString &format);
|
||||
void FadeoutFinished();
|
||||
void FadeoutPauseFinished();
|
||||
|
|
|
@ -1307,24 +1307,24 @@ void GstEnginePipeline::TagMessageReceived(GstMessage *msg) {
|
|||
GstTagList *taglist = nullptr;
|
||||
gst_message_parse_tag(msg, &taglist);
|
||||
|
||||
Engine::SimpleMetaBundle bundle;
|
||||
bundle.type = Engine::SimpleMetaBundle::Type::Current;
|
||||
bundle.media_url = media_url_;
|
||||
bundle.stream_url = stream_url_;
|
||||
bundle.title = ParseStrTag(taglist, GST_TAG_TITLE);
|
||||
bundle.artist = ParseStrTag(taglist, GST_TAG_ARTIST);
|
||||
bundle.comment = ParseStrTag(taglist, GST_TAG_COMMENT);
|
||||
bundle.album = ParseStrTag(taglist, GST_TAG_ALBUM);
|
||||
bundle.bitrate = static_cast<int>(ParseUIntTag(taglist, GST_TAG_BITRATE) / 1000);
|
||||
bundle.lyrics = ParseStrTag(taglist, GST_TAG_LYRICS);
|
||||
EngineMetadata engine_metadata;
|
||||
engine_metadata.type = EngineMetadata::Type::Current;
|
||||
engine_metadata.media_url = media_url_;
|
||||
engine_metadata.stream_url = stream_url_;
|
||||
engine_metadata.title = ParseStrTag(taglist, GST_TAG_TITLE);
|
||||
engine_metadata.artist = ParseStrTag(taglist, GST_TAG_ARTIST);
|
||||
engine_metadata.comment = ParseStrTag(taglist, GST_TAG_COMMENT);
|
||||
engine_metadata.album = ParseStrTag(taglist, GST_TAG_ALBUM);
|
||||
engine_metadata.bitrate = static_cast<int>(ParseUIntTag(taglist, GST_TAG_BITRATE) / 1000);
|
||||
engine_metadata.lyrics = ParseStrTag(taglist, GST_TAG_LYRICS);
|
||||
|
||||
if (!bundle.title.isEmpty() && bundle.artist.isEmpty() && bundle.album.isEmpty()) {
|
||||
if (!engine_metadata.title.isEmpty() && engine_metadata.artist.isEmpty() && engine_metadata.album.isEmpty()) {
|
||||
QStringList title_splitted;
|
||||
if (bundle.title.contains(" - ")) {
|
||||
title_splitted = bundle.title.split(" - ");
|
||||
if (engine_metadata.title.contains(" - ")) {
|
||||
title_splitted = engine_metadata.title.split(" - ");
|
||||
}
|
||||
else if (bundle.title.contains('~')) {
|
||||
title_splitted = bundle.title.split('~');
|
||||
else if (engine_metadata.title.contains('~')) {
|
||||
title_splitted = engine_metadata.title.split('~');
|
||||
}
|
||||
if (!title_splitted.isEmpty() && title_splitted.count() >= 2) {
|
||||
int i = 0;
|
||||
|
@ -1332,13 +1332,13 @@ void GstEnginePipeline::TagMessageReceived(GstMessage *msg) {
|
|||
++i;
|
||||
switch (i) {
|
||||
case 1:
|
||||
bundle.artist = title_part.trimmed();
|
||||
engine_metadata.artist = title_part.trimmed();
|
||||
break;
|
||||
case 2:
|
||||
bundle.title = title_part.trimmed();
|
||||
engine_metadata.title = title_part.trimmed();
|
||||
break;
|
||||
case 3:
|
||||
bundle.album = title_part.trimmed();
|
||||
engine_metadata.album = title_part.trimmed();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1349,7 +1349,7 @@ void GstEnginePipeline::TagMessageReceived(GstMessage *msg) {
|
|||
|
||||
gst_tag_list_unref(taglist);
|
||||
|
||||
emit MetadataFound(id(), bundle);
|
||||
emit MetadataFound(id(), engine_metadata);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -44,12 +44,10 @@
|
|||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include "enginemetadata.h"
|
||||
|
||||
class QTimerEvent;
|
||||
class GstBufferConsumer;
|
||||
|
||||
namespace Engine {
|
||||
struct SimpleMetaBundle;
|
||||
} // namespace Engine
|
||||
struct GstPlayBin;
|
||||
|
||||
class GstEnginePipeline : public QObject {
|
||||
|
@ -132,7 +130,7 @@ class GstEnginePipeline : public QObject {
|
|||
void Error(const int pipeline_id, const int domain, const int error_code, const QString &message, const QString &debug);
|
||||
|
||||
void EndOfStreamReached(const int pipeline_id, const bool has_next_track);
|
||||
void MetadataFound(const int pipeline_id, const Engine::SimpleMetaBundle &bundle);
|
||||
void MetadataFound(const int pipeline_id, const EngineMetadata &bundle);
|
||||
|
||||
void VolumeChanged(const uint volume);
|
||||
void FaderFinished();
|
||||
|
|
|
@ -32,17 +32,15 @@
|
|||
#include "core/taskmanager.h"
|
||||
#include "core/logging.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "engine_fwd.h"
|
||||
#include "enginebase.h"
|
||||
#include "enginetype.h"
|
||||
#include "vlcengine.h"
|
||||
#include "vlcscopedref.h"
|
||||
|
||||
VLCEngine::VLCEngine(TaskManager *task_manager, QObject *parent)
|
||||
: Engine::Base(Engine::EngineType::VLC, parent),
|
||||
: EngineBase(parent),
|
||||
instance_(nullptr),
|
||||
player_(nullptr),
|
||||
state_(Engine::State::Empty) {
|
||||
state_(State::Empty) {
|
||||
|
||||
Q_UNUSED(task_manager);
|
||||
|
||||
|
@ -52,7 +50,7 @@ VLCEngine::VLCEngine(TaskManager *task_manager, QObject *parent)
|
|||
|
||||
VLCEngine::~VLCEngine() {
|
||||
|
||||
if (state_ == Engine::State::Playing || state_ == Engine::State::Paused) {
|
||||
if (state_ == State::Playing || state_ == State::Paused) {
|
||||
libvlc_media_player_stop(player_);
|
||||
}
|
||||
|
||||
|
@ -100,7 +98,7 @@ bool VLCEngine::Init() {
|
|||
|
||||
}
|
||||
|
||||
bool VLCEngine::Load(const QUrl &media_url, const QUrl &stream_url, const Engine::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) {
|
||||
bool VLCEngine::Load(const QUrl &media_url, const QUrl &stream_url, const EngineBase::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) {
|
||||
|
||||
Q_UNUSED(media_url);
|
||||
Q_UNUSED(change);
|
||||
|
@ -197,7 +195,7 @@ void VLCEngine::SetVolumeSW(const uint percent) {
|
|||
|
||||
qint64 VLCEngine::position_nanosec() const {
|
||||
|
||||
if (state_ == Engine::State::Empty) return 0;
|
||||
if (state_ == State::Empty) return 0;
|
||||
const qint64 result = (position() * kNsecPerMsec);
|
||||
return qMax(0LL, result);
|
||||
|
||||
|
@ -205,7 +203,7 @@ qint64 VLCEngine::position_nanosec() const {
|
|||
|
||||
qint64 VLCEngine::length_nanosec() const {
|
||||
|
||||
if (state_ == Engine::State::Empty) return 0;
|
||||
if (state_ == State::Empty) return 0;
|
||||
const qint64 result = (end_nanosec_ - static_cast<qint64>(beginning_nanosec_));
|
||||
if (result > 0) {
|
||||
return result;
|
||||
|
@ -297,32 +295,32 @@ void VLCEngine::StateChangedCallback(const libvlc_event_t *e, void *data) {
|
|||
break;
|
||||
|
||||
case libvlc_MediaPlayerStopped:{
|
||||
const Engine::State state = engine->state_;
|
||||
engine->state_ = Engine::State::Empty;
|
||||
if (state == Engine::State::Playing) {
|
||||
const EngineBase::State state = engine->state_;
|
||||
engine->state_ = EngineBase::State::Empty;
|
||||
if (state == EngineBase::State::Playing) {
|
||||
emit engine->StateChanged(engine->state_);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case libvlc_MediaPlayerEncounteredError:
|
||||
engine->state_ = Engine::State::Error;
|
||||
engine->state_ = EngineBase::State::Error;
|
||||
emit engine->StateChanged(engine->state_);
|
||||
emit engine->FatalError();
|
||||
break;
|
||||
|
||||
case libvlc_MediaPlayerPlaying:
|
||||
engine->state_ = Engine::State::Playing;
|
||||
engine->state_ = EngineBase::State::Playing;
|
||||
emit engine->StateChanged(engine->state_);
|
||||
break;
|
||||
|
||||
case libvlc_MediaPlayerPaused:
|
||||
engine->state_ = Engine::State::Paused;
|
||||
engine->state_ = EngineBase::State::Paused;
|
||||
emit engine->StateChanged(engine->state_);
|
||||
break;
|
||||
|
||||
case libvlc_MediaPlayerEndReached:
|
||||
engine->state_ = Engine::State::Idle;
|
||||
engine->state_ = EngineBase::State::Idle;
|
||||
emit engine->TrackEnded();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -31,23 +31,23 @@
|
|||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include "engine_fwd.h"
|
||||
#include "enginebase.h"
|
||||
|
||||
struct libvlc_event_t;
|
||||
|
||||
class TaskManager;
|
||||
|
||||
class VLCEngine : public Engine::Base {
|
||||
class VLCEngine : public EngineBase {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VLCEngine(TaskManager *task_manager, QObject *parent = nullptr);
|
||||
~VLCEngine() override;
|
||||
|
||||
Type type() const override { return Type::VLC; }
|
||||
bool Init() override;
|
||||
Engine::State state() const override { return state_; }
|
||||
bool Load(const QUrl &media_url, const QUrl &stream_url, const Engine::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) override;
|
||||
EngineBase::State state() const override { return state_; }
|
||||
bool Load(const QUrl &media_url, const QUrl &stream_url, const EngineBase::TrackChangeFlags change, const bool force_stop_at_end, const quint64 beginning_nanosec, const qint64 end_nanosec) override;
|
||||
bool Play(const quint64 offset_nanosec) override;
|
||||
void Stop(const bool stop_after = false) override;
|
||||
void Pause() override;
|
||||
|
@ -70,7 +70,7 @@ class VLCEngine : public Engine::Base {
|
|||
private:
|
||||
libvlc_instance_t *instance_;
|
||||
libvlc_media_player_t *player_;
|
||||
Engine::State state_;
|
||||
State state_;
|
||||
|
||||
bool Initialized() const { return (instance_ && player_); }
|
||||
uint position() const;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "core/application.h"
|
||||
#include "core/player.h"
|
||||
#include "core/song.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "settings/moodbarsettingspage.h"
|
||||
#include "playlist/playlistmanager.h"
|
||||
|
||||
|
@ -94,9 +94,9 @@ void MoodbarController::AsyncLoadComplete(MoodbarPipeline *pipeline, const QUrl
|
|||
}
|
||||
// Did we stop the song?
|
||||
switch (app_->player()->GetState()) {
|
||||
case Engine::State::Error:
|
||||
case Engine::State::Empty:
|
||||
case Engine::State::Idle:
|
||||
case EngineBase::State::Error:
|
||||
case EngineBase::State::Empty:
|
||||
case EngineBase::State::Idle:
|
||||
return;
|
||||
|
||||
default:
|
||||
|
|
|
@ -43,10 +43,8 @@
|
|||
#include "core/iconloader.h"
|
||||
#include "core/player.h"
|
||||
#include "core/logging.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/devicefinders.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/devicefinder.h"
|
||||
#include "widgets/lineedit.h"
|
||||
#include "widgets/stickyslider.h"
|
||||
|
@ -67,7 +65,7 @@ BackendSettingsPage::BackendSettingsPage(SettingsDialog *dialog, QWidget *parent
|
|||
ui_(new Ui_BackendSettingsPage),
|
||||
configloaded_(false),
|
||||
engineloaded_(false),
|
||||
enginetype_current_(Engine::EngineType::None) {
|
||||
enginetype_current_(EngineBase::Type::None) {
|
||||
|
||||
ui_->setupUi(this);
|
||||
setWindowIcon(IconLoader::Load("soundcard", true, 0, 32));
|
||||
|
@ -113,15 +111,15 @@ void BackendSettingsPage::Load() {
|
|||
QSettings s;
|
||||
s.beginGroup(kSettingsGroup);
|
||||
|
||||
Engine::EngineType enginetype = Engine::EngineTypeFromName(s.value("engine", EngineName(Engine::EngineType::None)).toString());
|
||||
if (enginetype == Engine::EngineType::None && engine()) enginetype = engine()->type();
|
||||
EngineBase::Type enginetype = EngineBase::TypeFromName(s.value("engine", EngineBase::Name(EngineBase::Type::None)).toString());
|
||||
if (enginetype == EngineBase::Type::None && engine()) enginetype = engine()->type();
|
||||
|
||||
ui_->combobox_engine->clear();
|
||||
#ifdef HAVE_GSTREAMER
|
||||
ui_->combobox_engine->addItem(IconLoader::Load("gstreamer"), EngineDescription(Engine::EngineType::GStreamer), static_cast<int>(Engine::EngineType::GStreamer));
|
||||
ui_->combobox_engine->addItem(IconLoader::Load("gstreamer"), EngineBase::Description(EngineBase::Type::GStreamer), static_cast<int>(EngineBase::Type::GStreamer));
|
||||
#endif
|
||||
#ifdef HAVE_VLC
|
||||
ui_->combobox_engine->addItem(IconLoader::Load("vlc"), EngineDescription(Engine::EngineType::VLC), static_cast<int>(Engine::EngineType::VLC));
|
||||
ui_->combobox_engine->addItem(IconLoader::Load("vlc"), EngineBase::Description(EngineBase::Type::VLC), static_cast<int>(EngineBase::Type::VLC));
|
||||
#endif
|
||||
|
||||
enginetype_current_ = enginetype;
|
||||
|
@ -189,7 +187,7 @@ void BackendSettingsPage::Load() {
|
|||
|
||||
if (!EngineInitialized()) return;
|
||||
|
||||
if (engine()->state() == Engine::State::Empty) {
|
||||
if (engine()->state() == EngineBase::State::Empty) {
|
||||
if (ui_->combobox_engine->count() > 1) ui_->combobox_engine->setEnabled(true);
|
||||
else ui_->combobox_engine->setEnabled(false);
|
||||
}
|
||||
|
@ -208,7 +206,7 @@ void BackendSettingsPage::Load() {
|
|||
|
||||
// Check if engine, output or device is set to a different setting than the configured to force saving settings.
|
||||
|
||||
enginetype = ui_->combobox_engine->itemData(ui_->combobox_engine->currentIndex()).value<Engine::EngineType>();
|
||||
enginetype = ui_->combobox_engine->itemData(ui_->combobox_engine->currentIndex()).value<EngineBase::Type>();
|
||||
QString output_name;
|
||||
if (ui_->combobox_output->currentText().isEmpty()) {
|
||||
output_name = engine()->DefaultOutput();
|
||||
|
@ -232,7 +230,7 @@ void BackendSettingsPage::Load() {
|
|||
|
||||
bool BackendSettingsPage::EngineInitialized() {
|
||||
|
||||
if (!engine() || engine()->type() == Engine::EngineType::None) {
|
||||
if (!engine() || engine()->type() == EngineBase::Type::None) {
|
||||
errordialog_.ShowMessage("Engine is not initialized! Please restart.");
|
||||
return false;
|
||||
}
|
||||
|
@ -240,7 +238,7 @@ bool BackendSettingsPage::EngineInitialized() {
|
|||
|
||||
}
|
||||
|
||||
void BackendSettingsPage::Load_Engine(const Engine::EngineType enginetype) {
|
||||
void BackendSettingsPage::Load_Engine(const EngineBase::Type enginetype) {
|
||||
|
||||
if (!EngineInitialized()) return;
|
||||
|
||||
|
@ -260,7 +258,7 @@ void BackendSettingsPage::Load_Engine(const Engine::EngineType enginetype) {
|
|||
|
||||
if (engine()->type() != enginetype) {
|
||||
qLog(Debug) << "Switching engine.";
|
||||
Engine::EngineType new_enginetype = dialog()->app()->player()->CreateEngine(enginetype);
|
||||
EngineBase::Type new_enginetype = dialog()->app()->player()->CreateEngine(enginetype);
|
||||
dialog()->app()->player()->Init();
|
||||
if (new_enginetype != enginetype) {
|
||||
ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast<int>(engine()->type())));
|
||||
|
@ -307,7 +305,7 @@ void BackendSettingsPage::Load_Output(QString output, QVariant device) {
|
|||
}
|
||||
}
|
||||
|
||||
if (engine()->type() == Engine::EngineType::GStreamer) {
|
||||
if (engine()->type() == EngineBase::Type::GStreamer) {
|
||||
ui_->groupbox_buffer->setEnabled(true);
|
||||
ui_->groupbox_replaygain->setEnabled(true);
|
||||
}
|
||||
|
@ -333,7 +331,7 @@ void BackendSettingsPage::Load_Device(const QString &output, const QVariant &dev
|
|||
ui_->lineedit_device->clear();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
if (engine()->type() != Engine::EngineType::GStreamer)
|
||||
if (engine()->type() != EngineBase::Type::GStreamer)
|
||||
#endif
|
||||
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), kOutputAutomaticallySelect, QVariant());
|
||||
|
||||
|
@ -436,7 +434,7 @@ void BackendSettingsPage::Save() {
|
|||
if (!EngineInitialized()) return;
|
||||
|
||||
QVariant enginetype_v = ui_->combobox_engine->itemData(ui_->combobox_engine->currentIndex());
|
||||
Engine::EngineType enginetype = enginetype_v.value<Engine::EngineType>();
|
||||
EngineBase::Type enginetype = enginetype_v.value<EngineBase::Type>();
|
||||
QString output_name;
|
||||
QVariant device_value;
|
||||
|
||||
|
@ -455,7 +453,7 @@ void BackendSettingsPage::Save() {
|
|||
QSettings s;
|
||||
s.beginGroup(kSettingsGroup);
|
||||
|
||||
s.setValue("engine", EngineName(enginetype));
|
||||
s.setValue("engine", EngineBase::Name(enginetype));
|
||||
s.setValue("output", output_name);
|
||||
s.setValue("device", device_value);
|
||||
|
||||
|
@ -512,11 +510,11 @@ void BackendSettingsPage::EngineChanged(const int index) {
|
|||
if (!configloaded_ || !EngineInitialized()) return;
|
||||
|
||||
QVariant v = ui_->combobox_engine->itemData(index);
|
||||
Engine::EngineType enginetype = v.value<Engine::EngineType>();
|
||||
EngineBase::Type enginetype = v.value<EngineBase::Type>();
|
||||
|
||||
if (engine()->type() == enginetype) return;
|
||||
|
||||
if (engine()->state() != Engine::State::Empty) {
|
||||
if (engine()->state() != EngineBase::State::Empty) {
|
||||
errordialog_.ShowMessage("Can't switch engine while playing!");
|
||||
ui_->combobox_engine->setCurrentIndex(ui_->combobox_engine->findData(static_cast<int>(engine()->type())));
|
||||
return;
|
||||
|
@ -797,7 +795,7 @@ void BackendSettingsPage::FadingOptionsChanged() {
|
|||
if (!configloaded_ || !EngineInitialized()) return;
|
||||
|
||||
EngineBase::OutputDetails output = ui_->combobox_output->itemData(ui_->combobox_output->currentIndex()).value<EngineBase::OutputDetails>();
|
||||
if (engine()->type() == Engine::EngineType::GStreamer &&
|
||||
if (engine()->type() == EngineBase::Type::GStreamer &&
|
||||
!(engine()->ALSADeviceSupport(output.name) && !ui_->lineedit_device->text().isEmpty() && (ui_->lineedit_device->text().contains(QRegularExpression("^hw:.*")) || ui_->lineedit_device->text().contains(QRegularExpression("^plughw:.*"))))) {
|
||||
ui_->groupbox_fading->setEnabled(true);
|
||||
}
|
||||
|
|
|
@ -26,13 +26,11 @@
|
|||
#include <QVariant>
|
||||
#include <QString>
|
||||
|
||||
#include "engine/enginetype.h"
|
||||
#include "dialogs/errordialog.h"
|
||||
#include "settingspage.h"
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/player.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "dialogs/errordialog.h"
|
||||
#include "settingspage.h"
|
||||
|
||||
class SettingsDialog;
|
||||
class Ui_BackendSettingsPage;
|
||||
|
@ -80,7 +78,7 @@ class BackendSettingsPage : public SettingsPage {
|
|||
|
||||
bool EngineInitialized();
|
||||
|
||||
void Load_Engine(Engine::EngineType enginetype);
|
||||
void Load_Engine(const EngineBase::Type enginetype);
|
||||
void Load_Output(QString output, QVariant device);
|
||||
void Load_Device(const QString &output, const QVariant &device);
|
||||
#ifdef HAVE_ALSA
|
||||
|
@ -97,7 +95,7 @@ class BackendSettingsPage : public SettingsPage {
|
|||
bool engineloaded_;
|
||||
ErrorDialog errordialog_;
|
||||
|
||||
Engine::EngineType enginetype_current_;
|
||||
EngineBase::Type enginetype_current_;
|
||||
QString output_current_;
|
||||
QVariant device_current_;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <QString>
|
||||
#include <QSettings>
|
||||
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "osd/osdbase.h"
|
||||
|
||||
class QMainWindow;
|
||||
|
|
Loading…
Reference in New Issue