#ifndef PLAYBACKMANAGER_H #define PLAYBACKMANAGER_H #include #include #include #include #include "externalplayeripc.h" class QEmbyCore; class QProcess; class IndependentPlayerHost; class QTimer; struct MediaSourceInfo; class PlaybackManager : public QObject { Q_OBJECT public: static PlaybackManager* instance(); void init(QEmbyCore* core); // Whether an in-shell embedded player host exists to receive // requestEmbeddedPlay (AppShellHost + PlayerRouteController). When false, // the embedded branch falls back to IndependentPlayerHost (QML window). void setEmbeddedHostAvailable(bool available); void startPlayback(const QString& mediaId, const QString& title, const QString& streamUrl, long long startPositionTicks, const QVariant& extraData = QVariant()); void startExternalPlayback(const QString& playerPath, const QString& mediaId, const QString& title, const QString& streamUrl, long long startPositionTicks, const QVariant& extraData = QVariant()); void startInternalPlayback(const QString& mediaId, const QString& title, const QString& streamUrl, long long startPositionTicks, const QVariant& extraData = QVariant()); void stopExternalPlayer(); // Stop independent QML player window and/or external process before quit. // Returns true if something was stopped (caller may defer quit briefly). bool stopActivePlaybackForQuit(); signals: void requestEmbeddedPlay(const QString& mediaId, const QString& title, const QString& streamUrl, long long startPositionTicks, const QVariant& extraData); void playbackFinished(); private: explicit PlaybackManager(QObject *parent = nullptr); ~PlaybackManager() = default; void launchExternalPlayer(const QString& mediaId, const QString& title, const QString& streamUrl, long long startPositionTicks, const QVariant& extraData, const QString& playerPathOverride = QString()); void launchIndependentWindow(const QString& mediaId, const QString& title, const QString& streamUrl, long long startPositionTicks, const QVariant& extraData); static PlayerType identifyPlayerType(const QString& playerPath); static QStringList buildPlayerArgs(PlayerType type, long long startPositionTicks, int audioStreamIndex, int subtitleStreamIndex, bool subtitleDisabled, const MediaSourceInfo* sourceInfo); static QString ticksToTimeString(long long ticks); static double ticksToSeconds(long long ticks); static int computeRelativeStreamIndex(const MediaSourceInfo& source, const QString& streamType, int globalIndex); static QString generateIpcEndpoint(PlayerType type); void cleanupExternalPlayerState(); QEmbyCore* m_core = nullptr; bool m_embeddedHostAvailable = true; QPointer m_extProcess; QPointer m_independentHost; ExternalPlayerIPC* m_ipc = nullptr; QTimer* m_progressTimer = nullptr; QString m_currentMediaId; QString m_currentMediaSourceId; QString m_currentPlaySessionId; }; #endif