Explorar el Código

独立捕获源

zhuizhu hace 7 meses
padre
commit
66181d702f

+ 2 - 0
libs/AvRecorder/AvRecorder.pri

@@ -16,6 +16,7 @@ HEADERS += \
     $$PWD/ui/audio_render.h \
     $$PWD/ui/audio_widget.h \
     $$PWD/ui/av_recorder.h \
+    $$PWD/ui/capture_source_widget.h \
     $$PWD/ui/opengl_video_widget.h \
     $$PWD/ui/settings_page.h
 
@@ -35,6 +36,7 @@ SOURCES += \
     $$PWD/ui/audio_render.cpp \
     $$PWD/ui/audio_widget.cpp \
     $$PWD/ui/av_recorder.cpp \
+    $$PWD/ui/capture_source_widget.cpp \
     $$PWD/ui/opengl_video_widget.cpp \
     $$PWD/ui/settings_page.cpp
 

+ 16 - 38
libs/AvRecorder/ui/av_recorder.cpp

@@ -42,16 +42,7 @@ AvRecorder::AvRecorder(QWidget* parent)
     m_speakerWidget->SetName("扬声器");
 
     // 3. 捕获区
-    m_captureComboBox = new QComboBox;
-    m_updateListBtn = new QPushButton("刷新窗口列表");
-    QGroupBox* captureGroup = new QGroupBox("捕获源");
-    QHBoxLayout* captureRow = new QHBoxLayout;
-    captureRow->addWidget(m_captureComboBox);
-    captureRow->addWidget(m_updateListBtn);
-    captureGroup->setLayout(captureRow);
-
-    // m_captureComboBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
-    m_captureComboBox->setMinimumWidth(20);
+    m_captureSourceWidget = new CaptureSourceWidget(this);
 
     // 4. 音频区分组
     QGroupBox* audioGroup = new QGroupBox("音频");
@@ -97,7 +88,7 @@ AvRecorder::AvRecorder(QWidget* parent)
 
     // 7. 左侧功能区(捕获区在上,音频区在下)
     QVBoxLayout* leftLayout = new QVBoxLayout;
-    leftLayout->addWidget(captureGroup);
+    leftLayout->addWidget(m_captureSourceWidget);
     leftLayout->addWidget(audioGroup);
     leftLayout->addStretch();
 
@@ -127,7 +118,6 @@ AvRecorder::AvRecorder(QWidget* parent)
 
     // 12. 连接信号槽、初始化数据
     initConnect();
-    updateCaptureList();
 }
 
 void AvRecorder::setSettings(const SettingsPage::Param& param)
@@ -214,12 +204,11 @@ void AvRecorder::initConnect()
     connect(m_speakerWidget, &AudioWidget::SetVolumeScale, this, [this](float scale) {
         m_audioRecorder.SetVolumeScale(scale, SPEAKER_INDEX);
     });
-    connect(m_updateListBtn, &QPushButton::released, this, [this] { updateCaptureList(); });
-    
     // 连接音频设备选择按钮
     connect(m_audioDeviceBtn, &QPushButton::clicked, this, &AvRecorder::showAudioDeviceMenu);
     
-    connect(m_captureComboBox, &QComboBox::currentTextChanged, this, [this](const QString& text) {
+    // 连接捕获源控件信号
+    connect(m_captureSourceWidget, &CaptureSourceWidget::captureSourceTextChanged, this, [this](const QString& text) {
         if (text.isEmpty() || m_isLocked) {
             return;
         }
@@ -232,7 +221,11 @@ void AvRecorder::initConnect()
         }
         m_isLocked = false;
     });
-    connect(m_captureComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AvRecorder::onCaptureSourceChanged);
+    connect(m_captureSourceWidget, &CaptureSourceWidget::captureSourceIndexChanged, this, &AvRecorder::onCaptureSourceChanged);
+    connect(m_captureSourceWidget, &CaptureSourceWidget::refreshRequested, this, [this]() {
+        // 刷新请求处理,可以在这里添加额外的逻辑
+        qDebug() << "Capture source list refreshed";
+    });
     connect(m_isDrawCursorBox, &QCheckBox::stateChanged, this, [this] {
         m_videoRecorder.SetIsDrawCursor(m_isDrawCursorBox->isChecked());
     });
@@ -328,11 +321,11 @@ bool AvRecorder::start()
 
 void AvRecorder::startCapture(CaptureMethod method)
 {
-    int idx = m_captureComboBox->currentIndex();
+    int idx = m_captureSourceWidget->getCurrentIndex();
     if (idx < 0) return;
     int monitorCnt = (int)MonitorFinder::GetList().size();
     QString type = (idx < monitorCnt) ? "monitor" : "window";
-    qintptr ptrHwnd = m_captureComboBox->currentData().value<qintptr>();
+    qintptr ptrHwnd = m_captureSourceWidget->getCurrentData().value<qintptr>();
 
     bool ok = false;
     if (m_isRecord || m_isLive) {
@@ -479,9 +472,8 @@ bool AvRecorder::startStream(std::string_view path, std::string_view format)
     m_recordTime = QTime::currentTime();
     m_captureStatusLabel->setText("状态: 正在工作");
     m_settingsBtn->setEnabled(false);
-    m_captureComboBox->setEnabled(false); // 禁用采集源切换
+    m_captureSourceWidget->setEnabled(false); // 禁用采集源切换
     m_syncRecordBox->setEnabled(false);
-    m_updateListBtn->setEnabled(false);
     m_captureMethodBox->setEnabled(false); // 禁用采集方式切换
 
     // 注意:不要在这里修改 m_isLive,由调用方(按钮逻辑)根据场景设置
@@ -511,9 +503,8 @@ void AvRecorder::stopStream()
 
     m_captureStatusLabel->setText("状态: 正常");
     m_settingsBtn->setEnabled(true);
-    m_captureComboBox->setEnabled(true); // 恢复采集源切换
+    m_captureSourceWidget->setEnabled(true); // 恢复采集源切换
     m_syncRecordBox->setEnabled(true);
-    m_updateListBtn->setEnabled(true);
     m_captureMethodBox->setEnabled(true); // 恢复采集方式切换
 }
 bool AvRecorder::startSyncRecord()
@@ -584,20 +575,7 @@ void AvRecorder::stopSyncRecord()
         m_isSyncRecord = false;
     }
 }
-void AvRecorder::updateCaptureList()
-{
-    m_captureComboBox->clear();
-    auto&& monitorList = MonitorFinder::GetList(true);
-    for (auto&& monitor : monitorList) {
-        QString text = "屏幕: " + QString::fromStdWString(monitor.title);
-        m_captureComboBox->addItem(text, QVariant::fromValue(qintptr(monitor.monitor)));
-    }
-    auto&& windowList = WindowFinder::GetList(true);
-    for (auto&& window : windowList) {
-        QString text = "窗口: " + QString::fromStdWString(window.title);
-        m_captureComboBox->addItem(text, QVariant::fromValue(qintptr(window.hwnd)));
-    }
-}
+
 
 void AvRecorder::initStatusBarUi()
 {
@@ -643,7 +621,7 @@ void AvRecorder::updateCaptureMethodBox(bool isMonitor) {
 
 // 捕获源切换时调用
 void AvRecorder::onCaptureSourceChanged() {
-    int idx = m_captureComboBox->currentIndex();
+    int idx = m_captureSourceWidget->getCurrentIndex();
     int monitorCnt = (int)MonitorFinder::GetList().size();
     bool isMonitor = (idx >= 0 && idx < monitorCnt);
     updateCaptureMethodBox(isMonitor);
@@ -656,7 +634,7 @@ void AvRecorder::onCaptureSourceChanged() {
         if (isMonitor) {
             m_videoRecorder.SetCaptureSource(idx, method);
         } else {
-            qintptr ptrHwnd = m_captureComboBox->currentData().value<qintptr>();
+            qintptr ptrHwnd = m_captureSourceWidget->getCurrentData().value<qintptr>();
             m_videoRecorder.SetCaptureSource((HWND)ptrHwnd, method);
         }
     }

+ 2 - 4
libs/AvRecorder/ui/av_recorder.h

@@ -11,6 +11,7 @@
 #include <QMenu>
 
 #include "audio_widget.h"
+#include "capture_source_widget.h"
 #include "qcombobox.h"
 #include "qstatusbar.h"
 #include "recorder/audio_recorder.h"
@@ -37,7 +38,6 @@ public slots:
 private:
     SettingsPage::Param m_settingsParam;
     void initStatusBarUi();
-    void updateCaptureList();
     void startCapture(CaptureMethod method);
     void stopCapture();
     void startPreview();
@@ -69,9 +69,7 @@ private:
     QCheckBox* m_syncRecordBox = nullptr; // 添加同步录像的复选框
     QTimer* m_videoRenderTimer = nullptr;
     QTimer m_otherTimer;
-    QComboBox* m_captureComboBox = nullptr;
-
-    QPushButton* m_updateListBtn = nullptr;
+    CaptureSourceWidget* m_captureSourceWidget = nullptr;
 
     bool m_isRecord = false;
     bool m_isLive = false;

+ 110 - 0
libs/AvRecorder/ui/capture_source_widget.cpp

@@ -0,0 +1,110 @@
+#include "capture_source_widget.h"
+
+#include <capturer/finder.h>
+
+CaptureSourceWidget::CaptureSourceWidget(QWidget* parent)
+    : QWidget(parent)
+    , m_captureComboBox(nullptr)
+    , m_updateListBtn(nullptr)
+    , m_captureGroup(nullptr)
+    , m_layout(nullptr)
+{
+    setupUi();
+    updateCaptureList();
+}
+
+void CaptureSourceWidget::setupUi()
+{
+    // 创建控件
+    m_captureComboBox = new QComboBox(this);
+    m_updateListBtn = new QPushButton("刷新窗口列表", this);
+    m_captureGroup = new QGroupBox("捕获源", this);
+    
+    // 设置ComboBox属性
+    m_captureComboBox->setMinimumWidth(20);
+    
+    // 创建布局
+    m_layout = new QHBoxLayout();
+    m_layout->addWidget(m_captureComboBox);
+    m_layout->addWidget(m_updateListBtn);
+    m_captureGroup->setLayout(m_layout);
+    
+    // 设置主布局
+    QHBoxLayout* mainLayout = new QHBoxLayout(this);
+    mainLayout->setContentsMargins(0, 0, 0, 0);
+    mainLayout->addWidget(m_captureGroup);
+    setLayout(mainLayout);
+    
+    // 连接信号槽
+    connect(m_captureComboBox, &QComboBox::currentTextChanged, 
+            this, &CaptureSourceWidget::onComboBoxTextChanged);
+    connect(m_captureComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
+            this, &CaptureSourceWidget::onComboBoxIndexChanged);
+    connect(m_updateListBtn, &QPushButton::clicked,
+            this, &CaptureSourceWidget::onRefreshButtonClicked);
+}
+
+int CaptureSourceWidget::getCurrentIndex() const
+{
+    return m_captureComboBox ? m_captureComboBox->currentIndex() : -1;
+}
+
+QVariant CaptureSourceWidget::getCurrentData() const
+{
+    return m_captureComboBox ? m_captureComboBox->currentData() : QVariant();
+}
+
+QString CaptureSourceWidget::getCurrentText() const
+{
+    return m_captureComboBox ? m_captureComboBox->currentText() : QString();
+}
+
+void CaptureSourceWidget::setEnabled(bool enabled)
+{
+    QWidget::setEnabled(enabled);
+    if (m_captureComboBox) {
+        m_captureComboBox->setEnabled(enabled);
+    }
+    if (m_updateListBtn) {
+        m_updateListBtn->setEnabled(enabled);
+    }
+}
+
+void CaptureSourceWidget::updateCaptureList()
+{
+    if (!m_captureComboBox) {
+        return;
+    }
+    
+    m_captureComboBox->clear();
+    
+    // 添加屏幕列表
+    auto&& monitorList = MonitorFinder::GetList(true);
+    for (auto&& monitor : monitorList) {
+        QString text = "屏幕: " + QString::fromStdWString(monitor.title);
+        m_captureComboBox->addItem(text, QVariant::fromValue(qintptr(monitor.monitor)));
+    }
+    
+    // 添加窗口列表
+    auto&& windowList = WindowFinder::GetList(true);
+    for (auto&& window : windowList) {
+        QString text = "窗口: " + QString::fromStdWString(window.title);
+        m_captureComboBox->addItem(text, QVariant::fromValue(qintptr(window.hwnd)));
+    }
+}
+
+void CaptureSourceWidget::onComboBoxTextChanged(const QString& text)
+{
+    emit captureSourceTextChanged(text);
+}
+
+void CaptureSourceWidget::onComboBoxIndexChanged(int index)
+{
+    emit captureSourceIndexChanged(index);
+}
+
+void CaptureSourceWidget::onRefreshButtonClicked()
+{
+    updateCaptureList();
+    emit refreshRequested();
+}

+ 55 - 0
libs/AvRecorder/ui/capture_source_widget.h

@@ -0,0 +1,55 @@
+#pragma once
+
+#include <QWidget>
+#include <QComboBox>
+#include <QPushButton>
+#include <QHBoxLayout>
+#include <QGroupBox>
+#include <QVariant>
+
+class CaptureSourceWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit CaptureSourceWidget(QWidget* parent = nullptr);
+    ~CaptureSourceWidget() = default;
+
+    // 获取当前选中的捕获源索引
+    int getCurrentIndex() const;
+    
+    // 获取当前选中的捕获源数据
+    QVariant getCurrentData() const;
+    
+    // 获取当前选中的文本
+    QString getCurrentText() const;
+    
+    // 设置启用状态
+    void setEnabled(bool enabled);
+    
+    // 刷新捕获源列表
+    void updateCaptureList();
+
+signals:
+    // 捕获源文本改变信号
+    void captureSourceTextChanged(const QString& text);
+    
+    // 捕获源索引改变信号
+    void captureSourceIndexChanged(int index);
+    
+    // 刷新按钮点击信号
+    void refreshRequested();
+
+private slots:
+    void onComboBoxTextChanged(const QString& text);
+    void onComboBoxIndexChanged(int index);
+    void onRefreshButtonClicked();
+
+private:
+    void setupUi();
+    
+    QComboBox* m_captureComboBox;
+    QPushButton* m_updateListBtn;
+    QGroupBox* m_captureGroup;
+    QHBoxLayout* m_layout;
+};