playercontroller.h 10 KB

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