From 9eadeddfd9e216122b24903be331cd8472f3fca7 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Fri, 19 Oct 2018 19:15:33 +0200 Subject: [PATCH] Fixup and finish deezer engine --- src/core/player.cpp | 10 ++++--- src/core/player.h | 2 +- src/engine/deezerengine.cpp | 60 ++++++++++++++----------------------- src/engine/deezerengine.h | 5 ++++ 4 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/core/player.cpp b/src/core/player.cpp index 9da140d2c..b29608fc2 100644 --- a/src/core/player.cpp +++ b/src/core/player.cpp @@ -288,7 +288,7 @@ void Player::NextInternal(Engine::TrackChangeFlags change) { if (app_->playlist_manager()->active()->current_item()) { const QUrl url = app_->playlist_manager()->active()->current_item()->Url(); - if (url_handlers_.contains(url.scheme())) { + if (url_handlers_.contains(url.scheme()) && !(engine_->type() == Engine::Deezer && url.scheme() == "dzmedia")) { // The next track is already being loaded if (url == loading_async_) return; @@ -349,6 +349,7 @@ bool Player::HandleStopAfter() { return true; } return false; + } void Player::TrackEnded() { @@ -360,6 +361,7 @@ void Player::TrackEnded() { } NextInternal(Engine::Auto); + } void Player::PlayPause() { @@ -496,7 +498,7 @@ void Player::PlayAt(int index, Engine::TrackChangeFlags change, bool reshuffle) if (change == Engine::Manual && engine_->position_nanosec() != engine_->length_nanosec()) { emit TrackSkipped(current_item_); const QUrl &url = current_item_->Url(); - if (url_handlers_.contains(url.scheme())) { + if (url_handlers_.contains(url.scheme()) && !(engine_->type() == Engine::Deezer && url.scheme() == "dzmedia")) { url_handlers_[url.scheme()]->TrackSkipped(); } } @@ -647,7 +649,7 @@ void Player::TrackAboutToEnd() { // We don't want to preload (and scrobble) the next item in the playlist if it's just going to be stopped again immediately after. if (app_->playlist_manager()->active()->current_item()) { const QUrl url = app_->playlist_manager()->active()->current_item()->Url(); - if (url_handlers_.contains(url.scheme())) { + if (url_handlers_.contains(url.scheme()) && !(engine_->type() == Engine::Deezer && url.scheme() == "dzmedia")) { url_handlers_[url.scheme()]->TrackAboutToEnd(); return; } @@ -680,7 +682,7 @@ void Player::TrackAboutToEnd() { QUrl url = next_item->Url(); // Get the actual track URL rather than the stream URL. - if (url_handlers_.contains(url.scheme())) { + if (url_handlers_.contains(url.scheme()) && !(engine_->type() == Engine::Deezer && url.scheme() == "dzmedia")) { UrlHandler::LoadResult result = url_handlers_[url.scheme()]->LoadNext(url); switch (result.type_) { case UrlHandler::LoadResult::NoMoreTracks: diff --git a/src/core/player.h b/src/core/player.h index 85e6ddca0..8151aa8d2 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -179,7 +179,7 @@ class Player : public PlayerInterface { void Play(); void ShowOSD(); void TogglePrettyOSD(); - + void HandleAuthentication(); private slots: diff --git a/src/engine/deezerengine.cpp b/src/engine/deezerengine.cpp index db1941f0f..66edf99d7 100644 --- a/src/engine/deezerengine.cpp +++ b/src/engine/deezerengine.cpp @@ -18,6 +18,7 @@ */ #include "config.h" +#include "version.h" #include #include @@ -46,10 +47,15 @@ #include "deezer/deezerservice.h" #include "settings/deezersettingspage.h" +const char *DeezerEngine::kAppID = "303684"; +const char *DeezerEngine::kProductID = "strawberry"; +const char *DeezerEngine::kProductVersion = STRAWBERRY_VERSION_DISPLAY; + DeezerEngine::DeezerEngine(TaskManager *task_manager) : EngineBase(), state_(Engine::Empty), - position_(0) { + position_(0), + stopping_(false) { type_ = Engine::Deezer; ReloadSettings(); @@ -72,14 +78,14 @@ DeezerEngine::~DeezerEngine() { bool DeezerEngine::Init() { - qLog(Debug) << "Deezer native SDK Version:" << dz_connect_get_build_id(); + qLog(Debug) << "Deezer native SDK Version:" << dz_connect_get_build_id() << QCoreApplication::applicationName().toUtf8(); struct dz_connect_configuration config; memset(&config, 0, sizeof(struct dz_connect_configuration)); - config.app_id = QString::number(DeezerService::kAppID).toUtf8(); - config.product_id = QCoreApplication::applicationName().toUtf8(); - config.product_build_id = QCoreApplication::applicationVersion().toUtf8().constData(); - config.user_profile_path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation).toUtf8().constData(); + + config.app_id = kAppID; + config.product_id = kProductID; + config.product_build_id = kProductVersion; config.connect_event_cb = ConnectEventCallback; connect_ = dz_connect_new(&config); @@ -180,6 +186,7 @@ void DeezerEngine::LoadAccessToken() { bool DeezerEngine::Load(const QUrl &media_url, const QUrl &original_url, Engine::TrackChangeFlags change, bool force_stop_at_end, quint64 beginning_nanosec, qint64 end_nanosec) { if (!Initialised()) return false; + stopping_ = false; Engine::Base::Load(media_url, original_url, change, force_stop_at_end, beginning_nanosec, end_nanosec); dz_error_t dzerr = dz_player_load(player_, nullptr, nullptr, media_url.toString().toUtf8().constData()); @@ -192,6 +199,7 @@ bool DeezerEngine::Load(const QUrl &media_url, const QUrl &original_url, Engine: bool DeezerEngine::Play(quint64 offset_nanosec) { if (!Initialised()) return false; + stopping_ = false; dz_error_t dzerr(DZ_ERROR_NO_ERROR); if (state() == Engine::Paused) dzerr = dz_player_resume(player_, nullptr, nullptr); @@ -207,13 +215,11 @@ bool DeezerEngine::Play(quint64 offset_nanosec) { void DeezerEngine::Stop(bool stop_after) { if (!Initialised()) return; + stopping_ = true; dz_error_t dzerr = dz_player_stop(player_, nullptr, nullptr); if (dzerr != DZ_ERROR_NO_ERROR) return; - state_ = Engine::Empty; - emit TrackEnded(); - } void DeezerEngine::Pause() { @@ -223,6 +229,9 @@ void DeezerEngine::Pause() { dz_error_t dzerr = dz_player_pause(player_, nullptr, nullptr); if (dzerr != DZ_ERROR_NO_ERROR) return; + state_ = Engine::Paused; + emit StateChanged(state_); + } void DeezerEngine::Unpause() { @@ -237,14 +246,9 @@ void DeezerEngine::Seek(quint64 offset_nanosec) { if (!Initialised()) return; - int offset = (offset_nanosec / kNsecPerMsec); - - uint len = (length_nanosec() / kNsecPerMsec); - if (len == 0) return; - - float pos = float(offset) / len; - - dz_error_t dzerr = dz_player_seek(player_, nullptr, nullptr, pos); + stopping_ = false; + dz_useconds_t offset = (offset_nanosec / kNsecPerUsec); + dz_error_t dzerr = dz_player_seek(player_, nullptr, nullptr, offset); if (dzerr != DZ_ERROR_NO_ERROR) return; } @@ -269,7 +273,6 @@ qint64 DeezerEngine::position_nanosec() const { qint64 DeezerEngine::length_nanosec() const { if (state() == Engine::Empty) return 0; - const qint64 result = (end_nanosec_ - beginning_nanosec_); return result; @@ -379,93 +382,77 @@ void DeezerEngine::PlayerEventCallback(dz_player_handle handle, dz_player_event_ switch (type) { case DZ_PLAYER_EVENT_LIMITATION_FORCED_PAUSE: - qLog(Debug) << "Deezer: PLAYER_EVENT_LIMITATION_FORCED_PAUSE"; break; case DZ_PLAYER_EVENT_QUEUELIST_LOADED: - qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_LOADED"; break; case DZ_PLAYER_EVENT_QUEUELIST_NO_RIGHT: - qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_NO_RIGHT"; break; case DZ_PLAYER_EVENT_QUEUELIST_NEED_NATURAL_NEXT: - qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_NEED_NATURAL_NEXT"; break; case DZ_PLAYER_EVENT_QUEUELIST_TRACK_NOT_AVAILABLE_OFFLINE: - qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_TRACK_NOT_AVAILABLE_OFFLINE"; engine->state_ = Engine::Error; emit engine->StateChanged(engine->state_); emit engine->Error("Track not available offline."); break; case DZ_PLAYER_EVENT_QUEUELIST_TRACK_RIGHTS_AFTER_AUDIOADS: - qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_TRACK_RIGHTS_AFTER_AUDIOADS"; break; case DZ_PLAYER_EVENT_QUEUELIST_SKIP_NO_RIGHT: - qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_SKIP_NO_RIGHT"; break; case DZ_PLAYER_EVENT_QUEUELIST_TRACK_SELECTED: break; case DZ_PLAYER_EVENT_MEDIASTREAM_DATA_READY: - qLog(Debug) << "Deezer: PLAYER_EVENT_MEDIASTREAM_DATA_READY"; break; case DZ_PLAYER_EVENT_MEDIASTREAM_DATA_READY_AFTER_SEEK: - qLog(Debug) << "Deezer: PLAYER_EVENT_MEDIASTREAM_DATA_READY_AFTER_SEEK"; break; case DZ_PLAYER_EVENT_RENDER_TRACK_START_FAILURE: - qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_START_FAILURE"; engine->state_ = Engine::Error; emit engine->StateChanged(engine->state_); emit engine->Error("Track start failure."); break; case DZ_PLAYER_EVENT_RENDER_TRACK_START: - qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_START"; engine->state_ = Engine::Playing; engine->position_ = 0; emit engine->StateChanged(engine->state_); break; case DZ_PLAYER_EVENT_RENDER_TRACK_END: - qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_END"; engine->state_ = Engine::Idle; engine->position_ = 0; emit engine->TrackEnded(); break; case DZ_PLAYER_EVENT_RENDER_TRACK_PAUSED: - qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_PAUSED"; engine->state_ = Engine::Paused; emit engine->StateChanged(engine->state_); break; case DZ_PLAYER_EVENT_RENDER_TRACK_UNDERFLOW: - qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_UNDERFLOW"; break; case DZ_PLAYER_EVENT_RENDER_TRACK_RESUMED: - qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_RESUMED"; engine->state_ = Engine::Playing; emit engine->StateChanged(engine->state_); break; case DZ_PLAYER_EVENT_RENDER_TRACK_SEEKING: - qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_SEEKING"; break; case DZ_PLAYER_EVENT_RENDER_TRACK_REMOVED: - qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_REMOVED"; + if (!engine->stopping_) return; engine->state_ = Engine::Empty; engine->position_ = 0; - emit engine->TrackEnded(); + emit engine->StateChanged(engine->state_); break; case DZ_PLAYER_EVENT_UNKNOWN: @@ -473,7 +460,6 @@ void DeezerEngine::PlayerEventCallback(dz_player_handle handle, dz_player_event_ qLog(Error) << "Deezer: Unknown player event" << type; break; } - //emit engine->StateChanged(engine->state_); } diff --git a/src/engine/deezerengine.h b/src/engine/deezerengine.h index 3d425ff0c..97979f08c 100644 --- a/src/engine/deezerengine.h +++ b/src/engine/deezerengine.h @@ -65,12 +65,17 @@ class DeezerEngine : public Engine::Base { bool ALSADeviceSupport(const QString &output); private: + static const char *kAppID; + static const char *kProductVersion; + static const char *kProductID; + static const char *kPath; Engine::State state_; dz_connect_handle connect_; dz_player_handle player_; QString access_token_; QDateTime expiry_time_; qint64 position_; + bool stopping_; bool Initialised() const; bool CanDecode(const QUrl &url);