| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- #pragma once
- #include <QElapsedTimer>
- #include <QMutex>
- #include <QObject>
- #include <QThread>
- #include <memory>
- #include <thread>
- #include <atomic>
- #include <condition_variable>
- #include <functional>
- #include "AVPlayer2/audio_play_thread.h"
- class ReadThread;
- class VideoDecodeThread;
- class AudioDecodeThread;
- class SubtitleDecodeThread;
- class AudioPlayThread;
- class VideoPlayThread;
- class VideoStateData;
- class StartPlayThread;
- class StopWaitingThread;
- struct VideoState;
- class OpenGLVideoWidget;
- class PlayerController : public QObject
- {
- Q_OBJECT
- public:
- enum class PlayerState {
- Idle,
- Initializing,
- Playing,
- Stopping
- };
- explicit PlayerController(QWidget* parent = nullptr);
- ~PlayerController();
- // 播放控制接口
- void startToPlay(const QString& file);
- void stopPlay();
- void pausePlay();
- void playMute(bool mute);
- void playStartSeek();
- void playSeekPre();
- void playSeekNext();
- void setVolume(int volume, int maxValue = 100);
- void setPlaySpeed(double speed);
- bool isPlaying() const;
- QString playingFile() const;
- bool playingHasVideo();
- bool playingHasAudio();
- bool playingHasSubtitle();
- // 状态访问接口
- VideoState* state();
- float deviceVolume() const;
- void setDeviceVolume(float volume);
- // 线程访问接口
- AudioPlayThread* audioPlayThread() const { return m_audioPlayThread.get(); }
- VideoPlayThread* videoPlayThread() const { return m_videoPlayThread.get(); }
- VideoStateData* videoStateData() const { return m_videoState.get(); }
- 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);
- 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 playSeek();
- 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);
- private slots:
- void onAsyncInitFinished(const QString& file, bool success);
- private:
- // 核心播放逻辑
- bool startPlay();
- void waitStopPlay(const QString& file);
- void allThreadStart();
- // 线程创建方法
- bool createVideoState(const QString& file);
- void deleteVideoState();
- 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);
- // 异步初始化相关
- void asyncInit(const QString& file);
- std::thread m_initThread;
- std::atomic<bool> m_initInProgress{false};
- std::atomic<bool> m_initSuccess{false};
- std::mutex m_stopMutex;
- // 状态机
- std::atomic<PlayerState> m_state{PlayerState::Idle};
- private:
- // 多媒体线程
- 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::unique_ptr<StopWaitingThread> m_stopPlayWaitingThread;
- QString m_currentFile; // 更清晰的命名
- void checkAndResetState();
- };
|