/* * Sailfin: a Jellyfin client written using Qt * Copyright (C) 2021-2022 Chris Josten and the Sailfin Contributors. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef JELLYFIN_MODEL_PLAYER_H #define JELLYFIN_MODEL_PLAYER_H #include #include #include namespace Jellyfin { namespace Model { Q_DECLARE_LOGGING_CATEGORY(player) class PlayerStateClass { Q_GADGET public: enum Value { Stopped, Playing, Paused }; Q_ENUM(Value); private: PlayerStateClass() {} }; class MediaStatusClass { Q_GADGET public: enum Value { NoMedia, Loading, Loaded, Stalled, Buffering, Buffered, EndOfMedia, Error }; Q_ENUM(Value); private: MediaStatusClass() {} }; using PlayerState = PlayerStateClass::Value; using MediaStatus = MediaStatusClass::Value; /** * @brief Abstract class for a player */ class Player : public QObject { Q_OBJECT Q_PROPERTY(Jellyfin::Model::PlayerStateClass::Value state READ state NOTIFY stateChanged) Q_PROPERTY(Jellyfin::Model::MediaStatusClass::Value mediaStatus READ mediaStatus NOTIFY mediaStatusChanged) Q_PROPERTY(qint64 position READ position NOTIFY positionChanged) Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged) Q_PROPERTY(bool seekable READ seekable NOTIFY seekableChanged) Q_PROPERTY(bool hasAudio READ hasAudio NOTIFY hasAudioChanged) Q_PROPERTY(bool hasVideo READ hasVideo NOTIFY hasVideoChanged) Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged) // Used in QML by the VideoOutput Q_PROPERTY(QObject* videoOutputSource READ videoOutputSource NOTIFY videoOutputSourceChanged); public: public: ~Player(); virtual PlayerState state() const = 0; virtual MediaStatus mediaStatus() const = 0; virtual qint64 position() const = 0; virtual qint64 duration() const = 0; virtual bool seekable() const = 0; virtual bool hasVideo() const = 0; virtual bool hasAudio() const = 0; virtual QString errorString() const = 0; virtual QObject *videoOutputSource() const = 0; public slots: virtual void pause() = 0; virtual void play(qint64 startPos = 0) = 0; virtual void stop() = 0; virtual void seek(qint64 position) = 0; virtual void setMedia(const QUrl &url, int audioIndex = -1, int subTitleIndex = -1) = 0; signals: void stateChanged(Jellyfin::Model::PlayerStateClass::Value newState); void mediaStatusChanged(Jellyfin::Model::MediaStatusClass::Value newMediaStatus); void positionChanged(qint64 newPosition); void durationChanged(qint64 newDuration); void errorStringChanged(); /** * @brief Sent when the position changed due to calling the seek method. */ void seeked(); void seekableChanged(bool seekable); void hasAudioChanged(); void hasVideoChanged(); void aboutToFinish(); void videoOutputSourceChanged(); }; #define USE_QTMULTIMEDIA_PLAYER #ifdef USE_QTMULTIMEDIA_PLAYER class QtMultimediaPlayerPrivate; /** * @brief Player implementation that uses QtMultimedia */ class QtMultimediaPlayer : public Player { Q_OBJECT Q_DECLARE_PRIVATE(QtMultimediaPlayer); public: explicit QtMultimediaPlayer(QObject *parent = nullptr); virtual ~QtMultimediaPlayer(); PlayerState state() const override; MediaStatus mediaStatus() const override; qint64 position() const override; qint64 duration() const override; bool seekable() const override; bool hasVideo() const override; bool hasAudio() const override; QString errorString() const override; QObject *videoOutputSource() const override; public slots: void pause() override; void play(qint64 startPos = 0) override; void stop() override; void seek(qint64 position) override; void setMedia(const QUrl &url, int audioIndex, int subtitleIndex) override; private: QScopedPointer d_ptr; }; #endif // ifdef USE_QTMULTIMEDIA_PLAYER } // NS Model } // NS Jellyfin #endif // JELLYFIN_MODEL_PLAYER_H