/* * Strawberry Music Player * This file was part of Clementine. * Copyright 2010, David Sansome * Copyright 2018-2021, Jonas Kvinge * * Strawberry is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Strawberry is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Strawberry. If not, see . * */ #ifndef SONGLOADER_H #define SONGLOADER_H #include "config.h" #include #include #include #ifdef HAVE_GSTREAMER # include #endif #include #include #include #include #include #include #include #include #include "song.h" class QTimer; class Player; class CollectionBackendInterface; class PlaylistParser; class ParserBase; class CueParser; #if defined(HAVE_AUDIOCD) && defined(HAVE_GSTREAMER) class CddaSongLoader; #endif class SongLoader : public QObject { Q_OBJECT public: explicit SongLoader(CollectionBackendInterface *collection, const Player *player, QObject *parent = nullptr); ~SongLoader() override; enum Result { Success, Error, BlockingLoadRequired, }; static const int kDefaultTimeout; const QUrl &url() const { return url_; } const SongList &songs() const { return songs_; } int timeout() const { return timeout_; } void set_timeout(int msec) { timeout_ = msec; } // If Success is returned the songs are fully loaded. If BlockingLoadRequired is returned LoadFilenamesBlocking() needs to be called next. Result Load(const QUrl &url); // Loads the files with only filenames. When finished, songs() contains a complete list of all Song objects, but without metadata. // This method is blocking, do not call it from the UI thread. SongLoader::Result LoadFilenamesBlocking(); // Completely load songs previously loaded with LoadFilenamesBlocking(). // When finished, the Song objects in songs() contain metadata now. This method is blocking, do not call it from the UI thread. void LoadMetadataBlocking(); Result LoadAudioCD(); QStringList errors() { return errors_; } signals: void AudioCDTracksLoadFinished(); void LoadAudioCDFinished(bool success); void LoadRemoteFinished(); private slots: void ScheduleTimeout(); void Timeout(); void StopTypefind(); #if defined(HAVE_AUDIOCD) && defined(HAVE_GSTREAMER) void AudioCDTracksLoadFinishedSlot(const SongList &songs, const QString &error); void AudioCDTracksTagsLoaded(const SongList &songs); #endif // HAVE_AUDIOCD && HAVE_GSTREAMER private: enum State { WaitingForType, WaitingForMagic, WaitingForData, Finished }; Result LoadLocal(const QString &filename); SongLoader::Result LoadLocalAsync(const QString &filename); void EffectiveSongLoad(Song *song); Result LoadLocalPartial(const QString &filename); void LoadLocalDirectory(const QString &filename); void LoadPlaylist(ParserBase *parser, const QString &filename); void AddAsRawStream(); #ifdef HAVE_GSTREAMER Result LoadRemote(); // GStreamer callbacks static void TypeFound(GstElement *typefind, uint probability, GstCaps *caps, void *self); static GstPadProbeReturn DataReady(GstPad*, GstPadProbeInfo *info, gpointer self); static GstBusSyncReply BusCallbackSync(GstBus*, GstMessage*, gpointer); static gboolean BusCallback(GstBus*, GstMessage*, gpointer); void StopTypefindAsync(bool success); void ErrorMessageReceived(GstMessage *msg); void EndOfStreamReached(); void MagicReady(); bool IsPipelinePlaying(); #endif void ScheduleTimeoutAsync(); private: static QSet sRawUriSchemes; QUrl url_; SongList songs_; QTimer *timeout_timer_; PlaylistParser *playlist_parser_; CueParser *cue_parser_; // For async loads std::function preload_func_; int timeout_; State state_; bool success_; ParserBase *parser_; QString mime_type_; QByteArray buffer_; CollectionBackendInterface *collection_; const Player *player_; #ifdef HAVE_GSTREAMER std::shared_ptr pipeline_; #endif QThreadPool thread_pool_; QStringList errors_; }; #endif // SONGLOADER_H