Add Spotify support

This commit is contained in:
Jonas Kvinge
2022-06-04 15:51:35 +02:00
parent f33b30fe79
commit 5f540a4c08
44 changed files with 4486 additions and 346 deletions

View File

@@ -37,6 +37,9 @@
#include "enginebase.h"
#include "settings/backendsettingspage.h"
#include "settings/networkproxysettingspage.h"
#ifdef HAVE_SPOTIFY
# include "settings/spotifysettingspage.h"
#endif
EngineBase::EngineBase(QObject *parent)
: QObject(parent),
@@ -239,6 +242,15 @@ void EngineBase::ReloadSettings() {
s.endGroup();
#ifdef HAVE_SPOTIFY
s.beginGroup(SpotifySettingsPage::kSettingsGroup);
spotify_username_ = s.value("username").toString();
QByteArray password = s.value("password").toByteArray();
if (password.isEmpty()) spotify_password_.clear();
else spotify_password_ = QString::fromUtf8(QByteArray::fromBase64(password));
s.endGroup();
#endif
}
void EngineBase::EmitAboutToFinish() {

View File

@@ -247,6 +247,12 @@ class EngineBase : public QObject {
bool http2_enabled_;
bool strict_ssl_enabled_;
// Spotify
#ifdef HAVE_SPOTIFY
QString spotify_username_;
QString spotify_password_;
#endif
bool about_to_end_emitted_;
Q_DISABLE_COPY(EngineBase)

View File

@@ -173,7 +173,7 @@ void GstEngine::StartPreloading(const QUrl &media_url, const QUrl &stream_url, c
if (current_pipeline_) {
current_pipeline_->PrepareNextUrl(media_url, stream_url, gst_url, beginning_nanosec, force_stop_at_end ? end_nanosec : 0);
// Add request to discover the stream
if (discoverer_) {
if (discoverer_ && media_url.scheme() != QStringLiteral("spotify")) {
if (!gst_discoverer_discover_uri_async(discoverer_, gst_url.constData())) {
qLog(Error) << "Failed to start stream discovery for" << gst_url;
}
@@ -230,7 +230,7 @@ bool GstEngine::Load(const QUrl &media_url, const QUrl &stream_url, const Engine
}
// Add request to discover the stream
if (discoverer_) {
if (discoverer_ && media_url.scheme() != QStringLiteral("spotify")) {
if (!gst_discoverer_discover_uri_async(discoverer_, gst_url.constData())) {
qLog(Error) << "Failed to start stream discovery for" << gst_url;
}
@@ -816,6 +816,10 @@ SharedPtr<GstEnginePipeline> GstEngine::CreatePipeline() {
ret->set_strict_ssl_enabled(strict_ssl_enabled_);
ret->set_fading_enabled(fadeout_enabled_ || autocrossfade_enabled_ || fadeout_pause_enabled_);
#ifdef HAVE_SPOTIFY
ret->set_spotify_login(spotify_username_, spotify_password_);
#endif
ret->AddBufferConsumer(this);
for (GstBufferConsumer *consumer : std::as_const(buffer_consumers_)) {
ret->AddBufferConsumer(consumer);

View File

@@ -300,6 +300,15 @@ void GstEnginePipeline::set_fading_enabled(const bool enabled) {
fading_enabled_ = enabled;
}
#ifdef HAVE_SPOTIFY
void GstEnginePipeline::set_spotify_login(const QString &spotify_username, const QString &spotify_password) {
spotify_username_ = spotify_username;
spotify_password_ = spotify_password;
}
#endif // HAVE_SPOTIFY
QString GstEnginePipeline::GstStateText(const GstState state) {
switch (state) {
@@ -996,6 +1005,17 @@ void GstEnginePipeline::SourceSetupCallback(GstElement *playbin, GstElement *sou
}
}
#ifdef HAVE_SPOTIFY
if (instance->media_url_.scheme() == QStringLiteral("spotify") &&
!instance->spotify_username_.isEmpty() &&
!instance->spotify_password_.isEmpty() &&
g_object_class_find_property(G_OBJECT_GET_CLASS(source), "username") &&
g_object_class_find_property(G_OBJECT_GET_CLASS(source), "password")) {
g_object_set(source, "username", instance->spotify_username_.toUtf8().constData(), nullptr);
g_object_set(source, "password", instance->spotify_password_.toUtf8().constData(), nullptr);
}
#endif
// If the pipeline was buffering we stop that now.
if (instance->buffering_) {
instance->buffering_ = false;

View File

@@ -76,6 +76,9 @@ class GstEnginePipeline : public QObject {
void set_bs2b_enabled(const bool enabled);
void set_strict_ssl_enabled(const bool enabled);
void set_fading_enabled(const bool enabled);
#ifdef HAVE_SPOTIFY
void set_spotify_login(const QString &spotify_username, const QString &spotify_password);
#endif
// Creates the pipeline, returns false on error
bool InitFromUrl(const QUrl &media_url, const QUrl &stream_url, const QByteArray &gst_url, const qint64 end_nanosec, const double ebur128_loudness_normalizing_gain_db, QString &error);
@@ -249,6 +252,12 @@ class GstEnginePipeline : public QObject {
bool bs2b_enabled_;
bool strict_ssl_enabled_;
// Spotify
#ifdef HAVE_SPOTIFY
QString spotify_username_;
QString spotify_password_;
#endif
// These get called when there is a new audio buffer available
QList<GstBufferConsumer*> buffer_consumers_;
QMutex buffer_consumers_mutex_;