| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- #ifndef AVPLAYER2_PLAYERCONTROLLER_H
- #define AVPLAYER2_PLAYERCONTROLLER_H
- #pragma once
- #include <QElapsedTimer>
- #include <QMutex>
- #include <QObject>
- #include <QThread>
- #include <atomic>
- #include <condition_variable>
- #include <functional>
- #include <memory>
- #include <unordered_map>
- #include "audio_play_thread.h"
- #include <QLoggingCategory>
- Q_DECLARE_LOGGING_CATEGORY(playerControllerLog)
- // 前置声明
- class ReadThread;
- class VideoDecodeThread;
- class AudioDecodeThread;
- class SubtitleDecodeThread;
- class AudioPlayThread;
- class VideoPlayThread;
- class VideoStateData;
- class StartPlayThread;
- class StopWaitingThread;
- struct VideoState;
- class OpenGLVideoWidget;
- /**
- * @brief 媒体播放控制器
- *
- * 负责协调音视频解码和播放线程,管理播放状态和用户交互
- */
- class PlayerController : public QObject
- {
- Q_OBJECT
- public:
- /**
- * @brief 播放器状态枚举
- */
- enum class PlayerState {
- Idle, ///< 空闲状态
- Initializing, ///< 初始化中
- Playing, ///< 播放中
- Stopping ///< 停止中
- };
- explicit PlayerController(QWidget* parent = nullptr);
- ~PlayerController();
- //--------------------------------------------------------------------------
- // 播放控制公共接口
- //--------------------------------------------------------------------------
-
- /**
- * @brief 开始播放指定文件
- * @param file 媒体文件路径
- */
- void startToPlay(const QString& file);
-
- /**
- * @brief 停止当前播放
- */
- void stopPlay();
-
- /**
- * @brief 暂停/继续播放
- */
- void pausePlay();
-
- /**
- * @brief 静音控制
- * @param mute 是否静音
- */
- void playMute(bool mute);
-
- /**
- * @brief 开始拖动进度条
- */
- void playStartSeek();
-
- /**
- * @brief 快退
- */
- void playSeekPre();
-
- /**
- * @brief 快进
- */
- void playSeekNext();
-
- /**
- * @brief 设置音量
- * @param volume 音量值
- * @param maxValue 最大音量值
- */
- void setVolume(int volume, int maxValue = 100);
-
- /**
- * @brief 设置播放速度
- * @param speed 播放速度倍率
- */
- void setPlaySpeed(double speed);
-
- /**
- * @brief 是否正在播放
- * @return 播放状态
- */
- bool isPlaying() const;
-
- /**
- * @brief 获取当前播放文件路径
- * @return 文件路径
- */
- QString playingFile() const;
-
- /**
- * @brief 当前媒体是否包含视频流
- * @return 是否有视频
- */
- bool playingHasVideo();
-
- /**
- * @brief 当前媒体是否包含音频流
- * @return 是否有音频
- */
- bool playingHasAudio();
-
- /**
- * @brief 当前媒体是否包含字幕流
- * @return 是否有字幕
- */
- bool playingHasSubtitle();
- //--------------------------------------------------------------------------
- // 状态访问接口
- //--------------------------------------------------------------------------
-
- /**
- * @brief 获取视频状态对象
- * @return VideoState指针
- */
- VideoState* state();
-
- /**
- * @brief 获取设备音量
- * @return 音量值(0.0-1.0)
- */
- float deviceVolume() const;
-
- /**
- * @brief 设置设备音量
- * @param volume 音量值(0.0-1.0)
- */
- void setDeviceVolume(float volume);
- /**
- * @brief 打印所有线程状态信息
- */
- void dump() const;
- public slots:
- //--------------------------------------------------------------------------
- // 线程生命周期管理槽函数
- //--------------------------------------------------------------------------
- void readPacketStopped();
- void decodeVideoStopped();
- void decodeAudioStopped();
- void decodeSubtitleStopped();
- void audioPlayStopped();
- void videoPlayStopped();
- //--------------------------------------------------------------------------
- // 播放状态回调槽函数
- //--------------------------------------------------------------------------
- void playStarted(bool success = true);
- void playFailed(const QString& file);
- //--------------------------------------------------------------------------
- // 线程管理槽函数
- //--------------------------------------------------------------------------
- void setThreads();
- void startSendData(bool send = true);
- void videoSeek(double pos = 0, double incr = 0);
- void videoSeekEx(double value = 0, double maxValue = 0);
- signals:
- //--------------------------------------------------------------------------
- // 线程控制信号
- //--------------------------------------------------------------------------
- void startToPlaySignal();
- void stopAudioPlayThread();
- void stopVideoPlayThread();
- void stopDecodeThread();
- void stopReadPacketThread();
- void waitStopAudioPlayThread();
- void waitStopVideoPlayThread();
- //--------------------------------------------------------------------------
- // 播放状态信号
- //--------------------------------------------------------------------------
- void audioStopped(); ///< 音频结束
- void videoStopped(); ///< 视频结束
- void playbackFinished(); ///< 播放自然结束
- //--------------------------------------------------------------------------
- // 多媒体数据处理信号
- //--------------------------------------------------------------------------
- void frameReady(AVFrame*);
- void audioData(const AudioData& data);
- void subtitleReady(const QString& text);
- //--------------------------------------------------------------------------
- // UI更新信号
- //--------------------------------------------------------------------------
- void setPlayControlWnd(bool set);
- void updatePlayControlVolume();
- void updatePlayControlStatus();
- void updatePlayTime();
- void showMessage(const QString& message, const QString& windowTitle, const QString& styleSheet);
- void requestFullscreen(bool fullscreen);
- void requestHideStatusBar(bool hide);
- //--------------------------------------------------------------------------
- // 异步初始化信号
- //--------------------------------------------------------------------------
- void asyncInitFinished(const QString& file, bool success);
- protected slots:
- void onFrameReady(AVFrame* frame);
- private slots:
- void onAsyncInitFinished(const QString& file, bool success);
- private:
- //--------------------------------------------------------------------------
- // 线程类型枚举
- //--------------------------------------------------------------------------
- enum class ThreadType {
- Video,
- Audio,
- Read,
- DecodeVideo,
- DecodeAudio,
- DecodeSubtitle,
- BeforePlay,
- StopWaiting
- };
- std::unordered_map<ThreadType, std::mutex> m_threadMutexes;
- //--------------------------------------------------------------------------
- // 核心播放逻辑
- //--------------------------------------------------------------------------
- void allThreadStart();
- // 线程管理辅助方法
- void stopAndResetThreads();
- bool areAllThreadsStopped() const;
- //--------------------------------------------------------------------------
- // 线程创建方法
- //--------------------------------------------------------------------------
- bool createVideoState(const QString& file);
- bool createReadThread();
- bool createDecodeVideoThread();
- bool createDecodeAudioThread();
- bool createDecodeSubtitleThread();
- bool createVideoPlayThread();
- bool createAudioPlayThread();
- bool startPlayThread(); // 避免UI冻结的线程
- //--------------------------------------------------------------------------
- // 播放辅助方法
- //--------------------------------------------------------------------------
- void videoSeekInc(double incr);
- void printDecodeContext(const AVCodecContext* videoCtx, bool isVideo = true) const;
- void displayStatusMessage(const QString& message);
- QSize displayVideoSize(AVCodecContext* videoCtx) const;
- void setVolumeUpdown(bool increase = true, float unit = 0.05f);
- QString strippedName(const QString& fullPath) const;
- void hideCursor(bool hide = true);
- bool cursorInWindow(QWidget* widget);
- //--------------------------------------------------------------------------
- // 初始化相关(已移除异步逻辑)
- //--------------------------------------------------------------------------
- mutable std::mutex m_stopMutex;
- //--------------------------------------------------------------------------
- // 状态机
- //--------------------------------------------------------------------------
- std::atomic<PlayerState> m_state{PlayerState::Idle};
- //--------------------------------------------------------------------------
- // 多媒体线程
- //--------------------------------------------------------------------------
- std::unique_ptr<ReadThread> m_packetReadThread; ///< 数据包读取线程
- std::unique_ptr<VideoDecodeThread> m_decodeVideoThread; ///< 视频解码线程
- std::unique_ptr<AudioDecodeThread> m_decodeAudioThread; ///< 音频解码线程
- std::unique_ptr<SubtitleDecodeThread> m_decodeSubtitleThread; ///< 字幕解码线程
- std::unique_ptr<AudioPlayThread> m_audioPlayThread; ///< 音频播放线程
- std::unique_ptr<VideoPlayThread> m_videoPlayThread; ///< 视频播放线程
- //--------------------------------------------------------------------------
- // 状态管理
- //--------------------------------------------------------------------------
- std::unique_ptr<VideoStateData> m_videoState; ///< 视频状态数据
- std::unique_ptr<StartPlayThread> m_beforePlayThread; ///< 播放前准备线程
- std::thread m_eventThread; ///< 事件处理线程
- QString m_currentFile; ///< 当前播放文件路径
- };
- #endif // AVPLAYER2_PLAYERCONTROLLER_H
|