Fixup and finish deezer engine

This commit is contained in:
Jonas Kvinge
2018-10-19 19:15:33 +02:00
parent de11cb173b
commit 9eadeddfd9
4 changed files with 35 additions and 42 deletions

View File

@@ -288,7 +288,7 @@ void Player::NextInternal(Engine::TrackChangeFlags change) {
if (app_->playlist_manager()->active()->current_item()) { if (app_->playlist_manager()->active()->current_item()) {
const QUrl url = app_->playlist_manager()->active()->current_item()->Url(); 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 // The next track is already being loaded
if (url == loading_async_) return; if (url == loading_async_) return;
@@ -349,6 +349,7 @@ bool Player::HandleStopAfter() {
return true; return true;
} }
return false; return false;
} }
void Player::TrackEnded() { void Player::TrackEnded() {
@@ -360,6 +361,7 @@ void Player::TrackEnded() {
} }
NextInternal(Engine::Auto); NextInternal(Engine::Auto);
} }
void Player::PlayPause() { 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()) { if (change == Engine::Manual && engine_->position_nanosec() != engine_->length_nanosec()) {
emit TrackSkipped(current_item_); emit TrackSkipped(current_item_);
const QUrl &url = current_item_->Url(); 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(); 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. // 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()) { if (app_->playlist_manager()->active()->current_item()) {
const QUrl url = app_->playlist_manager()->active()->current_item()->Url(); 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(); url_handlers_[url.scheme()]->TrackAboutToEnd();
return; return;
} }
@@ -680,7 +682,7 @@ void Player::TrackAboutToEnd() {
QUrl url = next_item->Url(); QUrl url = next_item->Url();
// Get the actual track URL rather than the stream 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); UrlHandler::LoadResult result = url_handlers_[url.scheme()]->LoadNext(url);
switch (result.type_) { switch (result.type_) {
case UrlHandler::LoadResult::NoMoreTracks: case UrlHandler::LoadResult::NoMoreTracks:

View File

@@ -179,7 +179,7 @@ class Player : public PlayerInterface {
void Play(); void Play();
void ShowOSD(); void ShowOSD();
void TogglePrettyOSD(); void TogglePrettyOSD();
void HandleAuthentication(); void HandleAuthentication();
private slots: private slots:

View File

@@ -18,6 +18,7 @@
*/ */
#include "config.h" #include "config.h"
#include "version.h"
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
@@ -46,10 +47,15 @@
#include "deezer/deezerservice.h" #include "deezer/deezerservice.h"
#include "settings/deezersettingspage.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) DeezerEngine::DeezerEngine(TaskManager *task_manager)
: EngineBase(), : EngineBase(),
state_(Engine::Empty), state_(Engine::Empty),
position_(0) { position_(0),
stopping_(false) {
type_ = Engine::Deezer; type_ = Engine::Deezer;
ReloadSettings(); ReloadSettings();
@@ -72,14 +78,14 @@ DeezerEngine::~DeezerEngine() {
bool DeezerEngine::Init() { 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; struct dz_connect_configuration config;
memset(&config, 0, sizeof(struct dz_connect_configuration)); memset(&config, 0, sizeof(struct dz_connect_configuration));
config.app_id = QString::number(DeezerService::kAppID).toUtf8();
config.product_id = QCoreApplication::applicationName().toUtf8(); config.app_id = kAppID;
config.product_build_id = QCoreApplication::applicationVersion().toUtf8().constData(); config.product_id = kProductID;
config.user_profile_path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation).toUtf8().constData(); config.product_build_id = kProductVersion;
config.connect_event_cb = ConnectEventCallback; config.connect_event_cb = ConnectEventCallback;
connect_ = dz_connect_new(&config); 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) { 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; if (!Initialised()) return false;
stopping_ = false;
Engine::Base::Load(media_url, original_url, change, force_stop_at_end, beginning_nanosec, end_nanosec); 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()); 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) { bool DeezerEngine::Play(quint64 offset_nanosec) {
if (!Initialised()) return false; if (!Initialised()) return false;
stopping_ = false;
dz_error_t dzerr(DZ_ERROR_NO_ERROR); dz_error_t dzerr(DZ_ERROR_NO_ERROR);
if (state() == Engine::Paused) dzerr = dz_player_resume(player_, nullptr, nullptr); 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) { void DeezerEngine::Stop(bool stop_after) {
if (!Initialised()) return; if (!Initialised()) return;
stopping_ = true;
dz_error_t dzerr = dz_player_stop(player_, nullptr, nullptr); dz_error_t dzerr = dz_player_stop(player_, nullptr, nullptr);
if (dzerr != DZ_ERROR_NO_ERROR) return; if (dzerr != DZ_ERROR_NO_ERROR) return;
state_ = Engine::Empty;
emit TrackEnded();
} }
void DeezerEngine::Pause() { void DeezerEngine::Pause() {
@@ -223,6 +229,9 @@ void DeezerEngine::Pause() {
dz_error_t dzerr = dz_player_pause(player_, nullptr, nullptr); dz_error_t dzerr = dz_player_pause(player_, nullptr, nullptr);
if (dzerr != DZ_ERROR_NO_ERROR) return; if (dzerr != DZ_ERROR_NO_ERROR) return;
state_ = Engine::Paused;
emit StateChanged(state_);
} }
void DeezerEngine::Unpause() { void DeezerEngine::Unpause() {
@@ -237,14 +246,9 @@ void DeezerEngine::Seek(quint64 offset_nanosec) {
if (!Initialised()) return; if (!Initialised()) return;
int offset = (offset_nanosec / kNsecPerMsec); stopping_ = false;
dz_useconds_t offset = (offset_nanosec / kNsecPerUsec);
uint len = (length_nanosec() / kNsecPerMsec); dz_error_t dzerr = dz_player_seek(player_, nullptr, nullptr, offset);
if (len == 0) return;
float pos = float(offset) / len;
dz_error_t dzerr = dz_player_seek(player_, nullptr, nullptr, pos);
if (dzerr != DZ_ERROR_NO_ERROR) return; if (dzerr != DZ_ERROR_NO_ERROR) return;
} }
@@ -269,7 +273,6 @@ qint64 DeezerEngine::position_nanosec() const {
qint64 DeezerEngine::length_nanosec() const { qint64 DeezerEngine::length_nanosec() const {
if (state() == Engine::Empty) return 0; if (state() == Engine::Empty) return 0;
const qint64 result = (end_nanosec_ - beginning_nanosec_); const qint64 result = (end_nanosec_ - beginning_nanosec_);
return result; return result;
@@ -379,93 +382,77 @@ void DeezerEngine::PlayerEventCallback(dz_player_handle handle, dz_player_event_
switch (type) { switch (type) {
case DZ_PLAYER_EVENT_LIMITATION_FORCED_PAUSE: case DZ_PLAYER_EVENT_LIMITATION_FORCED_PAUSE:
qLog(Debug) << "Deezer: PLAYER_EVENT_LIMITATION_FORCED_PAUSE";
break; break;
case DZ_PLAYER_EVENT_QUEUELIST_LOADED: case DZ_PLAYER_EVENT_QUEUELIST_LOADED:
qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_LOADED";
break; break;
case DZ_PLAYER_EVENT_QUEUELIST_NO_RIGHT: case DZ_PLAYER_EVENT_QUEUELIST_NO_RIGHT:
qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_NO_RIGHT";
break; break;
case DZ_PLAYER_EVENT_QUEUELIST_NEED_NATURAL_NEXT: case DZ_PLAYER_EVENT_QUEUELIST_NEED_NATURAL_NEXT:
qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_NEED_NATURAL_NEXT";
break; break;
case DZ_PLAYER_EVENT_QUEUELIST_TRACK_NOT_AVAILABLE_OFFLINE: case DZ_PLAYER_EVENT_QUEUELIST_TRACK_NOT_AVAILABLE_OFFLINE:
qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_TRACK_NOT_AVAILABLE_OFFLINE";
engine->state_ = Engine::Error; engine->state_ = Engine::Error;
emit engine->StateChanged(engine->state_); emit engine->StateChanged(engine->state_);
emit engine->Error("Track not available offline."); emit engine->Error("Track not available offline.");
break; break;
case DZ_PLAYER_EVENT_QUEUELIST_TRACK_RIGHTS_AFTER_AUDIOADS: case DZ_PLAYER_EVENT_QUEUELIST_TRACK_RIGHTS_AFTER_AUDIOADS:
qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_TRACK_RIGHTS_AFTER_AUDIOADS";
break; break;
case DZ_PLAYER_EVENT_QUEUELIST_SKIP_NO_RIGHT: case DZ_PLAYER_EVENT_QUEUELIST_SKIP_NO_RIGHT:
qLog(Debug) << "Deezer: PLAYER_EVENT_QUEUELIST_SKIP_NO_RIGHT";
break; break;
case DZ_PLAYER_EVENT_QUEUELIST_TRACK_SELECTED: case DZ_PLAYER_EVENT_QUEUELIST_TRACK_SELECTED:
break; break;
case DZ_PLAYER_EVENT_MEDIASTREAM_DATA_READY: case DZ_PLAYER_EVENT_MEDIASTREAM_DATA_READY:
qLog(Debug) << "Deezer: PLAYER_EVENT_MEDIASTREAM_DATA_READY";
break; break;
case DZ_PLAYER_EVENT_MEDIASTREAM_DATA_READY_AFTER_SEEK: case DZ_PLAYER_EVENT_MEDIASTREAM_DATA_READY_AFTER_SEEK:
qLog(Debug) << "Deezer: PLAYER_EVENT_MEDIASTREAM_DATA_READY_AFTER_SEEK";
break; break;
case DZ_PLAYER_EVENT_RENDER_TRACK_START_FAILURE: case DZ_PLAYER_EVENT_RENDER_TRACK_START_FAILURE:
qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_START_FAILURE";
engine->state_ = Engine::Error; engine->state_ = Engine::Error;
emit engine->StateChanged(engine->state_); emit engine->StateChanged(engine->state_);
emit engine->Error("Track start failure."); emit engine->Error("Track start failure.");
break; break;
case DZ_PLAYER_EVENT_RENDER_TRACK_START: case DZ_PLAYER_EVENT_RENDER_TRACK_START:
qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_START";
engine->state_ = Engine::Playing; engine->state_ = Engine::Playing;
engine->position_ = 0; engine->position_ = 0;
emit engine->StateChanged(engine->state_); emit engine->StateChanged(engine->state_);
break; break;
case DZ_PLAYER_EVENT_RENDER_TRACK_END: case DZ_PLAYER_EVENT_RENDER_TRACK_END:
qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_END";
engine->state_ = Engine::Idle; engine->state_ = Engine::Idle;
engine->position_ = 0; engine->position_ = 0;
emit engine->TrackEnded(); emit engine->TrackEnded();
break; break;
case DZ_PLAYER_EVENT_RENDER_TRACK_PAUSED: case DZ_PLAYER_EVENT_RENDER_TRACK_PAUSED:
qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_PAUSED";
engine->state_ = Engine::Paused; engine->state_ = Engine::Paused;
emit engine->StateChanged(engine->state_); emit engine->StateChanged(engine->state_);
break; break;
case DZ_PLAYER_EVENT_RENDER_TRACK_UNDERFLOW: case DZ_PLAYER_EVENT_RENDER_TRACK_UNDERFLOW:
qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_UNDERFLOW";
break; break;
case DZ_PLAYER_EVENT_RENDER_TRACK_RESUMED: case DZ_PLAYER_EVENT_RENDER_TRACK_RESUMED:
qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_RESUMED";
engine->state_ = Engine::Playing; engine->state_ = Engine::Playing;
emit engine->StateChanged(engine->state_); emit engine->StateChanged(engine->state_);
break; break;
case DZ_PLAYER_EVENT_RENDER_TRACK_SEEKING: case DZ_PLAYER_EVENT_RENDER_TRACK_SEEKING:
qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_SEEKING";
break; break;
case DZ_PLAYER_EVENT_RENDER_TRACK_REMOVED: case DZ_PLAYER_EVENT_RENDER_TRACK_REMOVED:
qLog(Debug) << "Deezer: PLAYER_EVENT_RENDER_TRACK_REMOVED"; if (!engine->stopping_) return;
engine->state_ = Engine::Empty; engine->state_ = Engine::Empty;
engine->position_ = 0; engine->position_ = 0;
emit engine->TrackEnded(); emit engine->StateChanged(engine->state_);
break; break;
case DZ_PLAYER_EVENT_UNKNOWN: 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; qLog(Error) << "Deezer: Unknown player event" << type;
break; break;
} }
//emit engine->StateChanged(engine->state_);
} }

View File

@@ -65,12 +65,17 @@ class DeezerEngine : public Engine::Base {
bool ALSADeviceSupport(const QString &output); bool ALSADeviceSupport(const QString &output);
private: private:
static const char *kAppID;
static const char *kProductVersion;
static const char *kProductID;
static const char *kPath;
Engine::State state_; Engine::State state_;
dz_connect_handle connect_; dz_connect_handle connect_;
dz_player_handle player_; dz_player_handle player_;
QString access_token_; QString access_token_;
QDateTime expiry_time_; QDateTime expiry_time_;
qint64 position_; qint64 position_;
bool stopping_;
bool Initialised() const; bool Initialised() const;
bool CanDecode(const QUrl &url); bool CanDecode(const QUrl &url);