Make SongLoader add URLs as raw streams if there exists a URL handler

for that scheme.  This fixes a bug where sky:// URLs couldn't be added
with MPRIS.
This commit is contained in:
David Sansome 2014-01-24 23:54:38 +11:00
parent 556fb62cd2
commit f816a47ad9
9 changed files with 38 additions and 19 deletions

View File

@ -69,7 +69,7 @@ void Player::Init() {
connect(engine_.get(), SIGNAL(TrackAboutToEnd()), SLOT(TrackAboutToEnd())); connect(engine_.get(), SIGNAL(TrackAboutToEnd()), SLOT(TrackAboutToEnd()));
connect(engine_.get(), SIGNAL(TrackEnded()), SLOT(TrackEnded())); connect(engine_.get(), SIGNAL(TrackEnded()), SLOT(TrackEnded()));
connect(engine_.get(), SIGNAL(MetaData(Engine::SimpleMetaBundle)), connect(engine_.get(), SIGNAL(MetaData(Engine::SimpleMetaBundle)),
SLOT(EngineMetadataReceived(Engine::SimpleMetaBundle))); SLOT(EngineMetadataReceived(Engine::SimpleMetaBundle)));
engine_->SetVolume(settings_.value("volume", 50).toInt()); engine_->SetVolume(settings_.value("volume", 50).toInt());

View File

@ -33,16 +33,17 @@
#include "config.h" #include "config.h"
#include "core/concurrentrun.h" #include "core/concurrentrun.h"
#include "core/logging.h" #include "core/logging.h"
#include "core/song.h" #include "core/player.h"
#include "core/signalchecker.h" #include "core/signalchecker.h"
#include "core/song.h"
#include "core/tagreaderclient.h" #include "core/tagreaderclient.h"
#include "core/timeconstants.h" #include "core/timeconstants.h"
#include "internet/fixlastfm.h" #include "internet/fixlastfm.h"
#include "internet/internetmodel.h" #include "internet/internetmodel.h"
#include "library/librarybackend.h" #include "library/librarybackend.h"
#include "library/sqlrow.h" #include "library/sqlrow.h"
#include "playlistparsers/parserbase.h"
#include "playlistparsers/cueparser.h" #include "playlistparsers/cueparser.h"
#include "playlistparsers/parserbase.h"
#include "playlistparsers/playlistparser.h" #include "playlistparsers/playlistparser.h"
#include "podcasts/podcastparser.h" #include "podcasts/podcastparser.h"
#include "podcasts/podcastservice.h" #include "podcasts/podcastservice.h"
@ -52,7 +53,9 @@
QSet<QString> SongLoader::sRawUriSchemes; QSet<QString> SongLoader::sRawUriSchemes;
const int SongLoader::kDefaultTimeout = 5000; const int SongLoader::kDefaultTimeout = 5000;
SongLoader::SongLoader(LibraryBackendInterface* library, QObject *parent) SongLoader::SongLoader(LibraryBackendInterface* library,
const Player* player,
QObject *parent)
: QObject(parent), : QObject(parent),
timeout_timer_(new QTimer(this)), timeout_timer_(new QTimer(this)),
playlist_parser_(new PlaylistParser(library, this)), playlist_parser_(new PlaylistParser(library, this)),
@ -63,7 +66,8 @@ SongLoader::SongLoader(LibraryBackendInterface* library, QObject *parent)
success_(false), success_(false),
parser_(NULL), parser_(NULL),
is_podcast_(false), is_podcast_(false),
library_(library) library_(library),
player_(player)
{ {
if (sRawUriSchemes.isEmpty()) { if (sRawUriSchemes.isEmpty()) {
sRawUriSchemes << "udp" << "mms" << "mmsh" << "mmst" << "mmsu" << "rtsp" sRawUriSchemes << "udp" << "mms" << "mmsh" << "mmst" << "mmsu" << "rtsp"
@ -91,9 +95,10 @@ SongLoader::Result SongLoader::Load(const QUrl& url) {
return LoadLocal(url_.toLocalFile()); return LoadLocal(url_.toLocalFile());
} }
if (sRawUriSchemes.contains(url_.scheme())) { if (sRawUriSchemes.contains(url_.scheme()) ||
// The URI scheme indicates that it can't possibly be a playlist, so add player_->HandlerForUrl(url) != nullptr) {
// it as a raw stream. // The URI scheme indicates that it can't possibly be a playlist, or we have
// a custom handler for the URL, so add it as a raw stream.
AddAsRawStream(); AddAsRawStream();
return Success; return Success;
} }

View File

@ -33,13 +33,15 @@
class CueParser; class CueParser;
class LibraryBackendInterface; class LibraryBackendInterface;
class ParserBase; class ParserBase;
class Player;
class PlaylistParser; class PlaylistParser;
class PodcastParser; class PodcastParser;
class SongLoader : public QObject { class SongLoader : public QObject {
Q_OBJECT Q_OBJECT
public: public:
SongLoader(LibraryBackendInterface* library, QObject* parent = 0); SongLoader(LibraryBackendInterface* library, const Player* player,
QObject* parent = 0);
~SongLoader(); ~SongLoader();
enum Result { enum Result {
@ -130,6 +132,7 @@ private:
bool is_podcast_; bool is_podcast_;
QByteArray buffer_; QByteArray buffer_;
LibraryBackendInterface* library_; LibraryBackendInterface* library_;
const Player* player_;
boost::shared_ptr<GstElement> pipeline_; boost::shared_ptr<GstElement> pipeline_;

View File

@ -25,6 +25,7 @@
#include "songloaderinserter.h" #include "songloaderinserter.h"
#include "songmimedata.h" #include "songmimedata.h"
#include "songplaylistitem.h" #include "songplaylistitem.h"
#include "core/application.h"
#include "core/closure.h" #include "core/closure.h"
#include "core/logging.h" #include "core/logging.h"
#include "core/modelfuturewatcher.h" #include "core/modelfuturewatcher.h"
@ -761,7 +762,8 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, int ro
} }
} }
} else if (data->hasFormat(kCddaMimeType)) { } else if (data->hasFormat(kCddaMimeType)) {
SongLoaderInserter* inserter = new SongLoaderInserter(task_manager_, library_); SongLoaderInserter* inserter = new SongLoaderInserter(
task_manager_, library_, backend_->app()->player());
connect(inserter, SIGNAL(Error(QString)), SIGNAL(LoadTracksError(QString))); connect(inserter, SIGNAL(Error(QString)), SIGNAL(LoadTracksError(QString)));
inserter->LoadAudioCD(this, row, play_now, enqueue_now); inserter->LoadAudioCD(this, row, play_now, enqueue_now);
} else if (data->hasUrls()) { } else if (data->hasUrls()) {
@ -773,7 +775,8 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, int ro
} }
void Playlist::InsertUrls(const QList<QUrl> &urls, int pos, bool play_now, bool enqueue) { void Playlist::InsertUrls(const QList<QUrl> &urls, int pos, bool play_now, bool enqueue) {
SongLoaderInserter* inserter = new SongLoaderInserter(task_manager_, library_); SongLoaderInserter* inserter = new SongLoaderInserter(
task_manager_, library_, backend_->app()->player());
connect(inserter, SIGNAL(Error(QString)), SIGNAL(LoadTracksError(QString))); connect(inserter, SIGNAL(Error(QString)), SIGNAL(LoadTracksError(QString)));
inserter->Load(this, pos, play_now, enqueue, urls); inserter->Load(this, pos, play_now, enqueue, urls);

View File

@ -78,6 +78,8 @@ class PlaylistBackend : public QObject {
void FavoritePlaylist(int id, bool is_favorite); void FavoritePlaylist(int id, bool is_favorite);
void RemovePlaylist(int id); void RemovePlaylist(int id);
Application* app() const { return app_; }
public slots: public slots:
void SavePlaylist(int playlist, const PlaylistItemList& items, void SavePlaylist(int playlist, const PlaylistItemList& items,
int last_played, smart_playlists::GeneratorPtr dynamic); int last_played, smart_playlists::GeneratorPtr dynamic);

View File

@ -156,7 +156,7 @@ void PlaylistManager::New(const QString& name, const SongList& songs,
void PlaylistManager::Load(const QString& filename) { void PlaylistManager::Load(const QString& filename) {
QUrl url = QUrl::fromLocalFile(filename); QUrl url = QUrl::fromLocalFile(filename);
SongLoader* loader = new SongLoader(library_backend_, this); SongLoader* loader = new SongLoader(library_backend_, app_->player(), this);
connect(loader, SIGNAL(LoadFinished(bool)), SLOT(LoadFinished(bool))); connect(loader, SIGNAL(LoadFinished(bool)), SLOT(LoadFinished(bool)));
SongLoader::Result result = loader->Load(url); SongLoader::Result result = loader->Load(url);
QFileInfo info(filename); QFileInfo info(filename);

View File

@ -23,8 +23,9 @@
#include "core/songloader.h" #include "core/songloader.h"
#include "core/taskmanager.h" #include "core/taskmanager.h"
SongLoaderInserter::SongLoaderInserter( SongLoaderInserter::SongLoaderInserter(TaskManager* task_manager,
TaskManager* task_manager, LibraryBackendInterface* library) LibraryBackendInterface* library,
const Player* player)
: task_manager_(task_manager), : task_manager_(task_manager),
destination_(NULL), destination_(NULL),
row_(-1), row_(-1),
@ -32,7 +33,8 @@ SongLoaderInserter::SongLoaderInserter(
enqueue_(false), enqueue_(false),
async_load_id_(0), async_load_id_(0),
async_progress_(0), async_progress_(0),
library_(library) { library_(library),
player_(player) {
} }
SongLoaderInserter::~SongLoaderInserter() { SongLoaderInserter::~SongLoaderInserter() {
@ -53,7 +55,7 @@ void SongLoaderInserter::Load(Playlist *destination,
destination, SLOT(UpdateItems(const SongList&))); destination, SLOT(UpdateItems(const SongList&)));
foreach (const QUrl& url, urls) { foreach (const QUrl& url, urls) {
SongLoader* loader = new SongLoader(library_, this); SongLoader* loader = new SongLoader(library_, player_, this);
// we're connecting this before we're even sure if this is an async load // we're connecting this before we're even sure if this is an async load
// to avoid race conditions (signal emission before we're listening to it) // to avoid race conditions (signal emission before we're listening to it)
@ -92,7 +94,7 @@ void SongLoaderInserter::LoadAudioCD(Playlist *destination,
play_now_ = play_now; play_now_ = play_now;
enqueue_ = enqueue; enqueue_ = enqueue;
SongLoader *loader = new SongLoader(library_, this); SongLoader* loader = new SongLoader(library_, player_, this);
connect(loader, SIGNAL(LoadFinished(bool)), SLOT(AudioCDTagsLoaded(bool))); connect(loader, SIGNAL(LoadFinished(bool)), SLOT(AudioCDTagsLoaded(bool)));
qLog(Info) << "Loading audio CD..."; qLog(Info) << "Loading audio CD...";
SongLoader::Result ret = loader->LoadAudioCD(); SongLoader::Result ret = loader->LoadAudioCD();

View File

@ -25,6 +25,7 @@
#include "core/song.h" #include "core/song.h"
class LibraryBackendInterface; class LibraryBackendInterface;
class Player;
class Playlist; class Playlist;
class SongLoader; class SongLoader;
class TaskManager; class TaskManager;
@ -34,7 +35,9 @@ class QModelIndex;
class SongLoaderInserter : public QObject { class SongLoaderInserter : public QObject {
Q_OBJECT Q_OBJECT
public: public:
SongLoaderInserter(TaskManager* task_manager, LibraryBackendInterface* library); SongLoaderInserter(TaskManager* task_manager,
LibraryBackendInterface* library,
const Player* player);
~SongLoaderInserter(); ~SongLoaderInserter();
void Load(Playlist* destination, int row, bool play_now, bool enqueue, void Load(Playlist* destination, int row, bool play_now, bool enqueue,
@ -70,6 +73,7 @@ private:
int async_load_id_; int async_load_id_;
int async_progress_; int async_progress_;
LibraryBackendInterface* library_; LibraryBackendInterface* library_;
const Player* player_;
}; };
#endif // SONGLOADERINSERTER_H #endif // SONGLOADERINSERTER_H

View File

@ -51,7 +51,7 @@ public:
protected: protected:
void SetUp() { void SetUp() {
library_.reset(new MockLibraryBackend); library_.reset(new MockLibraryBackend);
loader_.reset(new SongLoader(library_.get())); loader_.reset(new SongLoader(library_.get(), nullptr));
loader_->set_timeout(20000); loader_->set_timeout(20000);
// the thing we return is not really important // the thing we return is not really important