#ifndef FFMPEGVIDEOPULLER_H #define FFMPEGVIDEOPULLER_H #pragma once extern "C" { #include #include } #include #include #include #include #include #include "RingBuffer.h" class FFmpegVideoPuller : public QObject { Q_OBJECT public: explicit FFmpegVideoPuller(QObject* parent = nullptr); ~FFmpegVideoPuller(); bool open(const QString& url, int videoBufferSec = 300, int audioBufferSec = 300); // 默认缓存5分钟 void setSpeed(float speed); // 设置倍速 float getSpeed() const; void start(); void stop(); // 进度相关 double getFirstPts() const; double getLastPts() const; double getCurrentPts() const; void seekToPts(double pts); // 跳转到指定pts // 取帧接口 AVFrame* getCurrentVideoFrame(); AVFrame* getCurrentAudioFrame(); // 播放指针前进 void nextVideoFrame(); void nextAudioFrame(); // 缓冲区大小 size_t videoBufferSize() const; size_t audioBufferSize() const; void setVideoRenderCallback(std::function cb) { m_videoRenderCallback = cb; } void setAudioPlayCallback(std::function cb) { m_audioPlayCallback = cb; } double getTotalDuration() const { return m_totalDuration; } private: void decodeLoop(); void videoPlayLoop(); void audioPlayLoop(); // 音视频同步 std::atomic m_audioPts{0.0}; std::atomic m_videoPts{0.0}; std::mutex m_syncMutex; QString m_url; std::atomic m_running{false}; mutable std::mutex m_speedMutex; float m_speed = 1.0f; // FFmpeg相关 AVFormatContext* m_fmtCtx = nullptr; AVCodecContext* m_videoCodecCtx = nullptr; AVCodecContext* m_audioCodecCtx = nullptr; int m_videoStreamIdx = -1; int m_audioStreamIdx = -1; // 缓冲区 RingBuffer* m_videoBuffer = nullptr; RingBuffer* m_audioBuffer = nullptr; // 线程 QThread* m_decodeThread = nullptr; QThread* m_videoPlayThread = nullptr; QThread* m_audioPlayThread = nullptr; // 播放指针 std::atomic m_videoPlayIndex{0}; std::atomic m_audioPlayIndex{0}; std::atomic m_currentPts{0.0}; mutable std::mutex m_ptsMutex; std::function m_videoRenderCallback; std::function m_audioPlayCallback; double m_totalDuration = -1.0; }; #endif // FFMPEGVIDEOPULLER_H