playercontroller.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. #ifndef AVPLAYER2_PLAYERCONTROLLER_H
  2. #define AVPLAYER2_PLAYERCONTROLLER_H
  3. #pragma once
  4. #include <QElapsedTimer>
  5. #include <QMutex>
  6. #include <QObject>
  7. #include <QThread>
  8. #include <atomic>
  9. #include <condition_variable>
  10. #include <functional>
  11. #include <memory>
  12. #include <thread>
  13. #include <unordered_map>
  14. #include <QLoggingCategory>
  15. #include "AVPlayer2/audio_play_thread.h"
  16. Q_DECLARE_LOGGING_CATEGORY(playerControllerLog)
  17. // 前置声明
  18. class ReadThread;
  19. class VideoDecodeThread;
  20. class AudioDecodeThread;
  21. class SubtitleDecodeThread;
  22. class AudioPlayThread;
  23. class VideoPlayThread;
  24. class VideoStateData;
  25. class StartPlayThread;
  26. class StopWaitingThread;
  27. struct VideoState;
  28. class OpenGLVideoWidget;
  29. /**
  30. * @brief 媒体播放控制器
  31. *
  32. * 负责协调音视频解码和播放线程,管理播放状态和用户交互
  33. */
  34. class PlayerController : public QObject
  35. {
  36. Q_OBJECT
  37. public:
  38. /**
  39. * @brief 播放器状态枚举
  40. */
  41. enum class PlayerState {
  42. Idle, ///< 空闲状态
  43. Initializing, ///< 初始化中
  44. Playing, ///< 播放中
  45. Stopping ///< 停止中
  46. };
  47. explicit PlayerController(QWidget* parent = nullptr);
  48. ~PlayerController();
  49. //--------------------------------------------------------------------------
  50. // 播放控制公共接口
  51. //--------------------------------------------------------------------------
  52. /**
  53. * @brief 开始播放指定文件
  54. * @param file 媒体文件路径
  55. */
  56. void startToPlay(const QString& file);
  57. /**
  58. * @brief 停止当前播放
  59. */
  60. void stopPlay();
  61. /**
  62. * @brief 暂停/继续播放
  63. */
  64. void pausePlay();
  65. /**
  66. * @brief 静音控制
  67. * @param mute 是否静音
  68. */
  69. void playMute(bool mute);
  70. /**
  71. * @brief 开始拖动进度条
  72. */
  73. void playStartSeek();
  74. /**
  75. * @brief 快退
  76. */
  77. void playSeekPre();
  78. /**
  79. * @brief 快进
  80. */
  81. void playSeekNext();
  82. /**
  83. * @brief 设置音量
  84. * @param volume 音量值
  85. * @param maxValue 最大音量值
  86. */
  87. void setVolume(int volume, int maxValue = 100);
  88. /**
  89. * @brief 设置播放速度
  90. * @param speed 播放速度倍率
  91. */
  92. void setPlaySpeed(double speed);
  93. /**
  94. * @brief 是否正在播放
  95. * @return 播放状态
  96. */
  97. bool isPlaying() const;
  98. /**
  99. * @brief 获取当前播放文件路径
  100. * @return 文件路径
  101. */
  102. QString playingFile() const;
  103. /**
  104. * @brief 当前媒体是否包含视频流
  105. * @return 是否有视频
  106. */
  107. bool playingHasVideo();
  108. /**
  109. * @brief 当前媒体是否包含音频流
  110. * @return 是否有音频
  111. */
  112. bool playingHasAudio();
  113. /**
  114. * @brief 当前媒体是否包含字幕流
  115. * @return 是否有字幕
  116. */
  117. bool playingHasSubtitle();
  118. //--------------------------------------------------------------------------
  119. // 状态访问接口
  120. //--------------------------------------------------------------------------
  121. /**
  122. * @brief 获取视频状态对象
  123. * @return VideoState指针
  124. */
  125. VideoState* state();
  126. /**
  127. * @brief 获取设备音量
  128. * @return 音量值(0.0-1.0)
  129. */
  130. float deviceVolume() const;
  131. /**
  132. * @brief 设置设备音量
  133. * @param volume 音量值(0.0-1.0)
  134. */
  135. void setDeviceVolume(float volume);
  136. /**
  137. * @brief 打印所有线程状态信息
  138. */
  139. void dump() const;
  140. public slots:
  141. //--------------------------------------------------------------------------
  142. // 线程生命周期管理槽函数
  143. //--------------------------------------------------------------------------
  144. void readPacketStopped();
  145. void decodeVideoStopped();
  146. void decodeAudioStopped();
  147. void decodeSubtitleStopped();
  148. void audioPlayStopped();
  149. void videoPlayStopped();
  150. //--------------------------------------------------------------------------
  151. // 播放状态回调槽函数
  152. //--------------------------------------------------------------------------
  153. void playStarted(bool success = true);
  154. void playFailed(const QString& file);
  155. //--------------------------------------------------------------------------
  156. // 线程管理槽函数
  157. //--------------------------------------------------------------------------
  158. void setThreads();
  159. void startSendData(bool send = true);
  160. void videoSeek(double pos = 0, double incr = 0);
  161. void videoSeekEx(double value = 0, double maxValue = 0);
  162. signals:
  163. //--------------------------------------------------------------------------
  164. // 线程控制信号
  165. //--------------------------------------------------------------------------
  166. void startToPlaySignal();
  167. void stopAudioPlayThread();
  168. void stopVideoPlayThread();
  169. void stopDecodeThread();
  170. void stopReadPacketThread();
  171. void waitStopAudioPlayThread();
  172. void waitStopVideoPlayThread();
  173. //--------------------------------------------------------------------------
  174. // 播放状态信号
  175. //--------------------------------------------------------------------------
  176. void audioStopped(); ///< 音频结束
  177. void videoStopped(); ///< 视频结束
  178. void playbackFinished(); ///< 播放自然结束
  179. //--------------------------------------------------------------------------
  180. // 多媒体数据处理信号
  181. //--------------------------------------------------------------------------
  182. void frameReady(AVFrame*);
  183. void audioData(const AudioData& data);
  184. void subtitleReady(const QString& text);
  185. //--------------------------------------------------------------------------
  186. // UI更新信号
  187. //--------------------------------------------------------------------------
  188. void setPlayControlWnd(bool set);
  189. void updatePlayControlVolume();
  190. void updatePlayControlStatus();
  191. void updatePlayTime();
  192. void showMessage(const QString& message, const QString& windowTitle, const QString& styleSheet);
  193. void requestFullscreen(bool fullscreen);
  194. void requestHideStatusBar(bool hide);
  195. //--------------------------------------------------------------------------
  196. // 异步初始化信号
  197. //--------------------------------------------------------------------------
  198. void asyncInitFinished(const QString& file, bool success);
  199. protected slots:
  200. void onFrameReady(AVFrame* frame);
  201. private slots:
  202. void onAsyncInitFinished(const QString& file, bool success);
  203. private:
  204. //--------------------------------------------------------------------------
  205. // 线程类型枚举
  206. //--------------------------------------------------------------------------
  207. enum class ThreadType {
  208. Video,
  209. Audio,
  210. Read,
  211. DecodeVideo,
  212. DecodeAudio,
  213. DecodeSubtitle,
  214. BeforePlay,
  215. StopWaiting
  216. };
  217. std::unordered_map<ThreadType, std::mutex> m_threadMutexes;
  218. //--------------------------------------------------------------------------
  219. // 核心播放逻辑
  220. //--------------------------------------------------------------------------
  221. void allThreadStart();
  222. // 线程管理辅助方法
  223. void stopAndResetThreads();
  224. bool areAllThreadsStopped() const;
  225. //--------------------------------------------------------------------------
  226. // 线程创建方法
  227. //--------------------------------------------------------------------------
  228. bool createVideoState(const QString& file);
  229. bool createReadThread();
  230. bool createDecodeVideoThread();
  231. bool createDecodeAudioThread();
  232. bool createDecodeSubtitleThread();
  233. bool createVideoPlayThread();
  234. bool createAudioPlayThread();
  235. bool startPlayThread(); // 避免UI冻结的线程
  236. //--------------------------------------------------------------------------
  237. // 播放辅助方法
  238. //--------------------------------------------------------------------------
  239. void videoSeekInc(double incr);
  240. void printDecodeContext(const AVCodecContext* videoCtx, bool isVideo = true) const;
  241. void displayStatusMessage(const QString& message);
  242. QSize displayVideoSize(AVCodecContext* videoCtx) const;
  243. void setVolumeUpdown(bool increase = true, float unit = 0.05f);
  244. QString strippedName(const QString& fullPath) const;
  245. void hideCursor(bool hide = true);
  246. bool cursorInWindow(QWidget* widget);
  247. //--------------------------------------------------------------------------
  248. // 异步初始化相关
  249. //--------------------------------------------------------------------------
  250. void asyncInit(const QString& file);
  251. std::thread m_initThread;
  252. std::atomic<bool> m_initInProgress{false};
  253. std::atomic<bool> m_initSuccess{false};
  254. std::mutex m_stopMutex;
  255. //--------------------------------------------------------------------------
  256. // 状态机
  257. //--------------------------------------------------------------------------
  258. std::atomic<PlayerState> m_state{PlayerState::Idle};
  259. //--------------------------------------------------------------------------
  260. // 多媒体线程
  261. //--------------------------------------------------------------------------
  262. std::unique_ptr<ReadThread> m_packetReadThread; ///< 数据包读取线程
  263. std::unique_ptr<VideoDecodeThread> m_decodeVideoThread; ///< 视频解码线程
  264. std::unique_ptr<AudioDecodeThread> m_decodeAudioThread; ///< 音频解码线程
  265. std::unique_ptr<SubtitleDecodeThread> m_decodeSubtitleThread; ///< 字幕解码线程
  266. std::unique_ptr<AudioPlayThread> m_audioPlayThread; ///< 音频播放线程
  267. std::unique_ptr<VideoPlayThread> m_videoPlayThread; ///< 视频播放线程
  268. //--------------------------------------------------------------------------
  269. // 状态管理
  270. //--------------------------------------------------------------------------
  271. std::unique_ptr<VideoStateData> m_videoState; ///< 视频状态数据
  272. std::unique_ptr<StartPlayThread> m_beforePlayThread; ///< 播放前准备线程
  273. std::thread m_eventThread; ///< 事件处理线程
  274. QString m_currentFile; ///< 当前播放文件路径
  275. };
  276. #endif // AVPLAYER2_PLAYERCONTROLLER_H