Add tidal support

This commit is contained in:
Jonas Kvinge
2018-08-09 18:10:03 +02:00
parent 26062bd07b
commit 820124f9e1
74 changed files with 5420 additions and 273 deletions

View File

@@ -15,7 +15,7 @@
*
* 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"
@@ -52,6 +52,9 @@
#include "covermanager/discogscoverprovider.h"
#include "covermanager/musicbrainzcoverprovider.h"
#include "internet/internetmodel.h"
#include "tidal/tidalsearch.h"
bool Application::kIsPortable = false;
class ApplicationImpl {
@@ -97,7 +100,9 @@ class ApplicationImpl {
app->MoveToNewThread(loader);
return loader;
}),
current_art_loader_([=]() { return new CurrentArtLoader(app, app); })
current_art_loader_([=]() { return new CurrentArtLoader(app, app); }),
internet_model_([=]() { return new InternetModel(app, app); }),
tidal_search_([=]() { return new TidalSearch(app, app); })
{ }
Lazy<TagReaderClient> tag_reader_client_;
@@ -113,6 +118,8 @@ class ApplicationImpl {
Lazy<CoverProviders> cover_providers_;
Lazy<AlbumCoverLoader> album_cover_loader_;
Lazy<CurrentArtLoader> current_art_loader_;
Lazy<InternetModel> internet_model_;
Lazy<TidalSearch> tidal_search_;
};
@@ -210,6 +217,13 @@ TaskManager *Application::task_manager() const {
}
EngineDevice *Application::enginedevice() const {
//qLog(Debug) << __PRETTY_FUNCTION__;
return p_->enginedevice_.get();
}
InternetModel* Application::internet_model() const {
return p_->internet_model_.get();
}
TidalSearch* Application::tidal_search() const {
return p_->tidal_search_.get();
}

View File

@@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef APPLICATION_H_
@@ -49,6 +49,8 @@ class DeviceManager;
class CoverProviders;
class AlbumCoverLoader;
class CurrentArtLoader;
class InternetModel;
class TidalSearch;
class Application : public QObject {
Q_OBJECT
@@ -79,6 +81,9 @@ class Application : public QObject {
CollectionBackend *collection_backend() const;
CollectionModel *collection_model() const;
InternetModel *internet_model() const;
TidalSearch *tidal_search() const;
void MoveToNewThread(QObject *object);
void MoveToThread(QObject *object, QThread *thread);

View File

@@ -52,7 +52,7 @@
#include "scopedtransaction.h"
const char *Database::kDatabaseFilename = "strawberry.db";
const int Database::kSchemaVersion = 0;
const int Database::kSchemaVersion = 1;
const char *Database::kMagicAllSongsTables = "%allsongstables";
int Database::sNextConnectionId = 1;

View File

@@ -126,6 +126,8 @@
#include "settings/playlistsettingspage.h"
#include "settings/settingsdialog.h"
#include "tidal/tidalsearchview.h"
#if defined(HAVE_GSTREAMER) && defined(HAVE_CHROMAPRINT)
# include "musicbrainz/tagfetcher.h"
#endif
@@ -186,6 +188,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
manager->SetPlaylistManager(app->playlist_manager());
return manager;
}),
tidal_search_view_(new TidalSearchView(app_, this)),
playlist_menu_(new QMenu(this)),
playlist_add_to_another_(nullptr),
playlistitem_actions_separator_(nullptr),
@@ -218,7 +221,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
ui_->volume->setValue(volume);
VolumeChanged(volume);
// Initialise the global search widget
// Initialise the tidal search widget
StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker());
// Add tabs to the fancy tab widget
@@ -227,6 +230,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
ui_->tabs->addTab(file_view_, IconLoader::Load("document-open"), tr("Files"));
ui_->tabs->addTab(playlist_list_, IconLoader::Load("view-media-playlist"), tr("Playlists"));
ui_->tabs->addTab(device_view_, IconLoader::Load("device"), tr("Devices"));
ui_->tabs->addTab(tidal_search_view_, IconLoader::Load("tidal"), tr("Tidal", "Tidal"));
//ui_->tabs->AddSpacer();
// Add the now playing widget to the fancy tab widget
@@ -475,6 +479,9 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
collection_view_->filter()->AddMenuAction(separator);
collection_view_->filter()->AddMenuAction(collection_config_action);
// Tidal
connect(tidal_search_view_, SIGNAL(AddToPlaylist(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
// Playlist menu
playlist_play_pause_ = playlist_menu_->addAction(tr("Play"), this, SLOT(PlaylistPlay()));
playlist_menu_->addAction(ui_->action_stop);
@@ -657,6 +664,12 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
ReloadSettings();
// Tidal search shortcut
QAction *tidal_search_action = new QAction(this);
tidal_search_action->setShortcuts(QList<QKeySequence>() << QKeySequence("Ctrl+F") << QKeySequence("Ctrl+L"));
addAction(tidal_search_action);
connect(tidal_search_action, SIGNAL(triggered()), SLOT(FocusTidalSearchField()));
// Reload pretty OSD to avoid issues with fonts
osd_->ReloadPrettyOSDSettings();
@@ -745,6 +758,7 @@ void MainWindow::ReloadAllSettings() {
osd_->ReloadSettings();
collection_view_->ReloadSettings();
ui_->playlist->view()->ReloadSettings();
tidal_search_view_->ReloadSettings();
}
@@ -787,7 +801,7 @@ void MainWindow::MediaPaused() {
}
void MainWindow::MediaPlaying() {
ui_->action_stop->setEnabled(true);
ui_->action_stop_after_this_track->setEnabled(true);
ui_->action_play_pause->setIcon(IconLoader::Load("media-pause"));
@@ -1789,7 +1803,7 @@ void MainWindow::EditFileTags(const QList<QUrl> &urls) {
Song song;
song.set_url(url);
song.set_valid(true);
song.set_filetype(Song::Type_Mpeg);
song.set_filetype(Song::Type_MPEG);
songs << song;
}
@@ -2261,3 +2275,37 @@ void MainWindow::keyPressEvent(QKeyEvent *event) {
}
}
void MainWindow::FocusTidalSearchField() {
ui_->tabs->setCurrentWidget(tidal_search_view_);
tidal_search_view_->FocusSearchField();
}
void MainWindow::DoTidalSearch(const QString& query) {
FocusTidalSearchField();
tidal_search_view_->StartSearch(query);
}
void MainWindow::SearchForArtist() {
PlaylistItemPtr item(app_->playlist_manager()->current()->item_at(playlist_menu_index_.row()));
Song song = item->Metadata();
if (!song.albumartist().isEmpty()) {
DoTidalSearch(song.albumartist().simplified());
}
else if (!song.artist().isEmpty()) {
DoTidalSearch(song.artist().simplified());
}
}
void MainWindow::SearchForAlbum() {
PlaylistItemPtr item(app_->playlist_manager()->current()->item_at(playlist_menu_index_.row()));
Song song = item->Metadata();
if (!song.album().isEmpty()) {
DoTidalSearch(song.album().simplified());
}
}

View File

@@ -84,6 +84,7 @@ class TranscodeDialog;
#endif
class Ui_MainWindow;
class Windows7ThumbBar;
class TidalSearchView;
class MainWindow : public QMainWindow, public PlatformInterface {
Q_OBJECT
@@ -263,6 +264,11 @@ signals:
void ShowConsole();
void FocusTidalSearchField();
void DoTidalSearch(const QString& query);
void SearchForArtist();
void SearchForAlbum();
private:
void ConnectStatusView(StatusView *statusview);
@@ -313,6 +319,8 @@ signals:
PlaylistItemList autocomplete_tag_items_;
#endif
TidalSearchView *tidal_search_view_;
QAction *collection_show_all_;
QAction *collection_show_duplicates_;
QAction *collection_show_untagged_;
@@ -335,6 +343,9 @@ signals:
QAction *playlist_add_to_another_;
QList<QAction*> playlistitem_actions_;
QAction *playlistitem_actions_separator_;
QAction *search_for_artist_;
QAction *search_for_album_;
QModelIndex playlist_menu_index_;
QSortFilterProxyModel *collection_sort_model_;

View File

@@ -60,6 +60,8 @@
# include "dbus/metatypes.h"
#endif
#include "tidal/tidalsearch.h"
void RegisterMetaTypes() {
qRegisterMetaType<const char*>("const char*");
@@ -113,4 +115,7 @@ void RegisterMetaTypes() {
#endif
#endif
qRegisterMetaType<TidalSearch::ResultList>("TidalSearch::ResultList");
qRegisterMetaType<TidalSearch::Result>("TidalSearch::Result");
}

View File

@@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef MIMEDATA_H
@@ -52,6 +52,9 @@ class MimeData : public QMimeData {
// If this is set then the items are added to the queue after being inserted.
bool enqueue_now_;
// If this is set then the items are added to the beginning of the queue after being inserted.
bool enqueue_next_now_;
// If this is set then the items are inserted into a newly created playlist.
bool open_in_new_playlist_;

View File

@@ -15,7 +15,7 @@
*
* 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"
@@ -393,7 +393,7 @@ bool Mpris2::CanPause() const {
bool Mpris2::CanSeek() const { return CanSeek(app_->player()->GetState()); }
bool Mpris2::CanSeek(Engine::State state) const {
return app_->player()->GetCurrentItem() && state != Engine::Empty;
return app_->player()->GetCurrentItem() && state != Engine::Empty && !app_->player()->GetCurrentItem()->Metadata().is_stream();
}
bool Mpris2::CanControl() const { return true; }

View File

@@ -15,7 +15,7 @@
*
* 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"

View File

@@ -287,9 +287,10 @@ uint Song::mtime() const { return d->mtime_; }
uint Song::ctime() const { return d->ctime_; }
int Song::filesize() const { return d->filesize_; }
Song::FileType Song::filetype() const { return d->filetype_; }
bool Song::is_cdda() const { return d->filetype_ == Type_Cdda; }
bool Song::is_stream() const { return d->filetype_ == Type_Stream; }
bool Song::is_cdda() const { return d->filetype_ == Type_CDDA; }
bool Song::is_collection_song() const {
return !is_cdda() && id() != -1;
return !is_cdda() && !is_stream() && id() != -1;
}
const QString &Song::art_automatic() const { return d->art_automatic_; }
const QString &Song::art_manual() const { return d->art_manual_; }
@@ -329,10 +330,10 @@ void Song::set_bitdepth(int v) { d->bitdepth_ = v; }
void Song::set_directory_id(int v) { d->directory_id_ = v; }
void Song::set_url(const QUrl &v) {
if (Application::kIsPortable) {
QUrl base =
QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/");
QUrl base = QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/");
d->url_ = base.resolved(v);
} else {
}
else {
d->url_ = v;
}
}
@@ -364,36 +365,35 @@ QString Song::JoinSpec(const QString &table) {
QString Song::TextForFiletype(FileType type) {
switch (type) {
case Song::Type_Wav: return QObject::tr("Wav");
case Song::Type_Flac: return QObject::tr("FLAC");
case Song::Type_WAV: return QObject::tr("Wav");
case Song::Type_FLAC: return QObject::tr("FLAC");
case Song::Type_WavPack: return QObject::tr("WavPack");
case Song::Type_OggFlac: return QObject::tr("Ogg FLAC");
case Song::Type_OggVorbis: return QObject::tr("Ogg Vorbis");
case Song::Type_OggOpus: return QObject::tr("Ogg Opus");
case Song::Type_OggSpeex: return QObject::tr("Ogg Speex");
case Song::Type_Mpeg: return QObject::tr("MP3");
case Song::Type_Mp4: return QObject::tr("MP4 AAC");
case Song::Type_Asf: return QObject::tr("Windows Media audio");
case Song::Type_Aiff: return QObject::tr("AIFF");
case Song::Type_Mpc: return QObject::tr("MPC");
case Song::Type_MPEG: return QObject::tr("MP3");
case Song::Type_MP4: return QObject::tr("MP4 AAC");
case Song::Type_ASF: return QObject::tr("Windows Media audio");
case Song::Type_AIFF: return QObject::tr("AIFF");
case Song::Type_MPC: return QObject::tr("MPC");
case Song::Type_TrueAudio: return QObject::tr("TrueAudio");
case Song::Type_Cdda: return QObject::tr("CDDA");
case Song::Type_CDDA: return QObject::tr("CDDA");
case Song::Type_Unknown:
default:
return QObject::tr("Unknown");
}
}
bool Song::IsFileLossless() const {
switch (filetype()) {
case Song::Type_Wav:
case Song::Type_Flac:
case Song::Type_WAV:
case Song::Type_FLAC:
case Song::Type_OggFlac:
case Song::Type_WavPack:
case Song::Type_Aiff:
case Song::Type_AIFF:
return true;
default:
return false;
@@ -628,7 +628,7 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
else if (Song::kColumns.value(i) == "unavailable") {
d->unavailable_ = q.value(x).toBool();
}
else if (Song::kColumns.value(i) == "playcount") {
d->playcount_ = q.value(x).isNull() ? 0 : q.value(x).toInt();
}
@@ -650,7 +650,7 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
}
else if (Song::kColumns.value(i) == "compilation_effective") {
}
else if (Song::kColumns.value(i) == "art_automatic") {
d->art_automatic_ = q.value(x).toString();
}
@@ -662,11 +662,11 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
}
else if (Song::kColumns.value(i) == "effective_originalyear") {
}
else if (Song::kColumns.value(i) == "cue_path") {
d->cue_path_ = tostr(x);
}
else {
qLog(Error) << "Forgot to handle" << Song::kColumns.value(i);
}
@@ -752,7 +752,7 @@ void Song::InitFromItdb(const Itdb_Track *track, const QString &prefix) {
}
d->basefilename_ = QFileInfo(filename).fileName();
d->filetype_ = track->type2 ? Type_Mpeg : Type_Mp4;
d->filetype_ = track->type2 ? Type_MPEG : Type_MP4;
d->filesize_ = track->size;
d->mtime_ = track->time_modified;
d->ctime_ = track->time_added;
@@ -785,7 +785,7 @@ void Song::ToItdb(Itdb_Track *track) const {
//track->bithdepth = d->bithdepth_;
track->type1 = 0;
track->type2 = d->filetype_ == Type_Mp4 ? 0 : 1;
track->type2 = d->filetype_ == Type_MP4 ? 0 : 1;
track->mediatype = 1; // Audio
track->size = d->filesize_;
track->time_modified = d->mtime_;
@@ -825,15 +825,15 @@ void Song::InitFromMTP(const LIBMTP_track_t *track, const QString &host) {
d->playcount_ = track->usecount;
switch (track->filetype) {
case LIBMTP_FILETYPE_WAV: d->filetype_ = Type_Wav; break;
case LIBMTP_FILETYPE_MP3: d->filetype_ = Type_Mpeg; break;
case LIBMTP_FILETYPE_WMA: d->filetype_ = Type_Asf; break;
case LIBMTP_FILETYPE_WAV: d->filetype_ = Type_WAV; break;
case LIBMTP_FILETYPE_MP3: d->filetype_ = Type_MPEG; break;
case LIBMTP_FILETYPE_WMA: d->filetype_ = Type_ASF; break;
case LIBMTP_FILETYPE_OGG: d->filetype_ = Type_OggVorbis; break;
case LIBMTP_FILETYPE_MP4: d->filetype_ = Type_Mp4; break;
case LIBMTP_FILETYPE_AAC: d->filetype_ = Type_Mp4; break;
case LIBMTP_FILETYPE_MP4: d->filetype_ = Type_MP4; break;
case LIBMTP_FILETYPE_AAC: d->filetype_ = Type_MP4; break;
case LIBMTP_FILETYPE_FLAC: d->filetype_ = Type_OggFlac; break;
case LIBMTP_FILETYPE_MP2: d->filetype_ = Type_Mpeg; break;
case LIBMTP_FILETYPE_M4A: d->filetype_ = Type_Mp4; break;
case LIBMTP_FILETYPE_MP2: d->filetype_ = Type_MPEG; break;
case LIBMTP_FILETYPE_M4A: d->filetype_ = Type_MP4; break;
default: d->filetype_ = Type_Unknown; break;
}
@@ -868,14 +868,14 @@ void Song::ToMTP(LIBMTP_track_t *track) const {
track->usecount = d->playcount_;
switch (d->filetype_) {
case Type_Asf: track->filetype = LIBMTP_FILETYPE_ASF; break;
case Type_Mp4: track->filetype = LIBMTP_FILETYPE_MP4; break;
case Type_Mpeg: track->filetype = LIBMTP_FILETYPE_MP3; break;
case Type_Flac:
case Type_ASF: track->filetype = LIBMTP_FILETYPE_ASF; break;
case Type_MP4: track->filetype = LIBMTP_FILETYPE_MP4; break;
case Type_MPEG: track->filetype = LIBMTP_FILETYPE_MP3; break;
case Type_FLAC:
case Type_OggFlac: track->filetype = LIBMTP_FILETYPE_FLAC; break;
case Type_OggSpeex:
case Type_OggVorbis: track->filetype = LIBMTP_FILETYPE_OGG; break;
case Type_Wav: track->filetype = LIBMTP_FILETYPE_WAV; break;
case Type_WAV: track->filetype = LIBMTP_FILETYPE_WAV; break;
default: track->filetype = LIBMTP_FILETYPE_UNDEF_AUDIO; break;
}
@@ -927,7 +927,7 @@ void Song::BindToQuery(QSqlQuery *query) const {
query->bindValue(":performer", strval(d->performer_));
query->bindValue(":grouping", strval(d->grouping_));
query->bindValue(":comment", strval(d->comment_));
query->bindValue(":beginning", d->beginning_);
query->bindValue(":length", intval(length_nanosec()));
@@ -1037,7 +1037,8 @@ QString Song::TitleWithCompilationArtist() const {
}
QString Song::SampleRateBitDepthToText() const {
if (d->samplerate_ == -1) return QString("");
if (d->bitdepth_ == -1) return QString("%1 hz").arg(d->samplerate_);
return QString("%1 hz / %2 bit").arg(d->samplerate_).arg(d->bitdepth_);
@@ -1071,7 +1072,7 @@ bool Song::IsMetadataEqual(const Song &other) const {
}
bool Song::IsEditable() const {
return d->valid_ && !d->url_.isEmpty() && d->filetype_ != Type_Unknown && !has_cue();
return d->valid_ && !d->url_.isEmpty() && !is_stream() && d->filetype_ != Type_Unknown && !has_cue();
}
bool Song::operator==(const Song &other) const {

View File

@@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef SONG_H
@@ -58,12 +58,6 @@ struct _Itdb_Track;
struct LIBMTP_track_struct;
#endif
#ifdef HAVE_LIBLASTFM
namespace lastfm {
class Track;
}
#endif
class SqlRow;
class Song {
@@ -95,20 +89,20 @@ class Song {
// If a new lossless file is added, also add it to IsFileLossless().
enum FileType {
Type_Unknown = 0,
Type_Wav = 1,
Type_Flac = 2,
Type_WAV = 1,
Type_FLAC = 2,
Type_WavPack = 3,
Type_OggFlac = 4,
Type_OggVorbis = 5,
Type_OggOpus = 6,
Type_OggSpeex = 7,
Type_Mpeg = 8,
Type_Mp4 = 9,
Type_Asf = 10,
Type_Aiff = 11,
Type_Mpc = 12,
Type_MPEG = 8,
Type_MP4 = 9,
Type_ASF = 10,
Type_AIFF = 11,
Type_MPC = 12,
Type_TrueAudio = 13,
Type_Cdda = 90,
Type_CDDA = 90,
Type_Stream = 91,
};
@@ -127,9 +121,6 @@ class Song {
void InitFromQuery(const SqlRow &query, bool reliable_metadata, int col = 0);
void InitFromFilePartial(const QString &filename); // Just store the filename: incomplete but fast
void InitArtManual(); // Check if there is already a art in the cache and store the filename in art_manual
#ifdef HAVE_LIBLASTFM
void InitFromLastFM(const lastfm::Track &track);
#endif
void MergeFromSimpleMetaBundle(const Engine::SimpleMetaBundle &bundle);
@@ -152,9 +143,6 @@ class Song {
// Save
void BindToQuery(QSqlQuery *query) const;
void BindToFtsQuery(QSqlQuery *query) const;
#ifdef HAVE_LIBLASTFM
void ToLastFM(lastfm::Track *track, bool prefer_album_artist) const;
#endif
void ToXesam(QVariantMap *map) const;
void ToProtobuf(pb::tagreader::SongMetadata *pb) const;
@@ -210,6 +198,7 @@ class Song {
const QString &effective_albumartist() const;
bool is_collection_song() const;
bool is_stream() const;
bool is_cdda() const;
// Playlist views are special because you don't want to fill in album artists automatically for compilations, but you do for normal albums:

View File

@@ -15,7 +15,7 @@
*
* 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"
@@ -51,6 +51,8 @@
#include "song.h"
#include "songloader.h"
#include "tagreaderclient.h"
#include "engine/enginetype.h"
#include "engine/enginebase.h"
#include "collection/collectionbackend.h"
#include "collection/collectionquery.h"
#include "collection/sqlrow.h"
@@ -78,6 +80,7 @@ SongLoader::SongLoader(CollectionBackendInterface *collection, const Player *pla
parser_(nullptr),
collection_(collection),
player_(player) {
if (sRawUriSchemes.isEmpty()) {
sRawUriSchemes << "udp"
<< "mms"
@@ -97,7 +100,7 @@ SongLoader::SongLoader(CollectionBackendInterface *collection, const Player *pla
}
SongLoader::~SongLoader() {
#ifdef HAVE_GSTREAMER
if (pipeline_) {
state_ = Finished;
@@ -121,24 +124,29 @@ SongLoader::Result SongLoader::Load(const QUrl &url) {
return Success;
}
if (player_->engine()->type() == Engine::GStreamer) {
#ifdef HAVE_GSTREAMER
preload_func_ = std::bind(&SongLoader::LoadRemote, this);
preload_func_ = std::bind(&SongLoader::LoadRemote, this);
return BlockingLoadRequired;
#else
return Error;
#endif
}
return BlockingLoadRequired;
return Success;
}
void SongLoader::LoadFilenamesBlocking() {
if (preload_func_) {
preload_func_();
}
}
SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) {
qLog(Debug) << "Fast Loading local file" << filename;
// First check to see if it's a directory - if so we can load all the songs inside right away.
if (QFileInfo(filename).isDir()) {
@@ -149,7 +157,7 @@ SongLoader::Result SongLoader::LoadLocalPartial(const QString &filename) {
song.InitFromFilePartial(filename);
if (song.is_valid()) songs_ << song;
return Success;
}
SongLoader::Result SongLoader::LoadAudioCD() {
@@ -208,6 +216,7 @@ SongLoader::Result SongLoader::LoadLocal(const QString &filename) {
// It's not in the database, load it asynchronously.
preload_func_ = std::bind(&SongLoader::LoadLocalAsync, this, filename);
return BlockingLoadRequired;
}
void SongLoader::LoadLocalAsync(const QString &filename) {
@@ -253,6 +262,7 @@ void SongLoader::LoadLocalAsync(const QString &filename) {
Song song;
song.InitFromFilePartial(filename);
if (song.is_valid()) songs_ << song;
}
void SongLoader::LoadMetadataBlocking() {
@@ -274,7 +284,8 @@ void SongLoader::EffectiveSongLoad(Song *song) {
Song collection_song = collection_->GetSongByUrl(song->url());
if (collection_song.is_valid()) {
*song = collection_song;
} else {
}
else {
// it's a normal media file
QString filename = song->url().toLocalFile();
TagReaderClient::Instance()->ReadFileBlocking(filename, song);
@@ -318,7 +329,15 @@ void SongLoader::LoadLocalDirectory(const QString &filename) {
// so if the user has the "Start playing when adding to playlist" preference behaviour set,
// it can enjoy the first song being played (seek it, have moodbar, etc.)
if (!songs_.isEmpty()) EffectiveSongLoad(&(*songs_.begin()));
}
void SongLoader::AddAsRawStream() {
Song song;
song.set_valid(true);
song.set_filetype(Song::Type_Stream);
song.set_url(url_);
song.set_title(url_.toString());
songs_ << song;
}
void SongLoader::Timeout() {
@@ -348,10 +367,10 @@ void SongLoader::StopTypefind() {
}
else if (success_) {
//qLog(Debug) << "Loading" << url_ << "as raw stream";
qLog(Debug) << "Loading" << url_ << "as raw stream";
// It wasn't a playlist - just put the URL in as a stream
//AddAsRawStream();
AddAsRawStream();
}
emit LoadRemoteFinished();
@@ -413,7 +432,7 @@ void SongLoader::LoadRemote() {
#ifdef HAVE_GSTREAMER
void SongLoader::TypeFound(GstElement *, uint, GstCaps *caps, void *self) {
SongLoader *instance = static_cast<SongLoader*>(self);
if (instance->state_ != WaitingForType) return;

View File

@@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU General Public License
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef SONGLOADER_H
@@ -106,6 +106,8 @@ signals:
void LoadLocalDirectory(const QString &filename);
void LoadPlaylist(ParserBase *parser, const QString &filename);
void AddAsRawStream();
#ifdef HAVE_GSTREAMER
void LoadRemote();