Share radio microphone controls with desktop publication
This commit is contained in:
1 parent
b2bd2c284c
commit
fbc030dc5b
2 files changed
+40
-8
No files matched your search
@@ -2,6 +2,7 @@
|
||||
#include "videoplayer_window.h"
|
||||
#include "capture_controls.h"
|
||||
#include "sound_manager.h"
|
||||
#include "../transport/gui_bridge.h"
|
||||
#include "debug_config.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QCoreApplication>
|
||||
@@ -157,7 +158,9 @@ StreamPublishWindow::StreamPublishWindow(StreamPublishEngine* engine, uint64_t g
|
||||
m_cursor->setObjectName(QStringLiteral("streamShowCursor")); form->addRow(m_cursor);
|
||||
m_noAudio = addOption(m_microphone, text("No audio"), QVariant());
|
||||
addOption(m_microphone, text("Default microphone"), QString()); select(m_microphone, QString());
|
||||
for (const auto& device : SoundManager::enumerateCaptureDevices()) addOption(m_microphone, device.name, device.id);
|
||||
refreshMicrophones();
|
||||
connect(m_microphone, &QMenu::aboutToShow, this, &StreamPublishWindow::refreshMicrophones);
|
||||
connect(SoundManager::instance(), &SoundManager::devicesChanged, this, [this] { refreshMicrophones(); synchronize(); });
|
||||
m_inputChannels = new QLabel(settings); form->addRow(text("Audio input"), m_inputChannels);
|
||||
for (int qp : {0, 18, 23, 28, 35, 40}) addOption(m_maxQp, qp ? QString::number(qp) : text("Automatic"), qp);
|
||||
select(m_maxQp, 28);
|
||||
@@ -190,8 +193,23 @@ StreamPublishWindow::StreamPublishWindow(StreamPublishEngine* engine, uint64_t g
|
||||
connect(m_resolution, &QMenu::triggered, this, [this] {
|
||||
populateFrameRates(m_fps, m_modes, value(m_resolution).toSize(), value(m_fps).toInt()); apply();
|
||||
});
|
||||
for (auto* menu : {m_fps, m_codec, m_bitrate, m_maxQp, m_rotation, m_microphone})
|
||||
for (auto* menu : {m_fps, m_codec, m_bitrate, m_maxQp, m_rotation})
|
||||
connect(menu, &QMenu::triggered, this, &StreamPublishWindow::apply);
|
||||
connect(m_microphone, &QMenu::triggered, this, [this](QAction* action) {
|
||||
if (m_updating || !action->isCheckable()) return;
|
||||
if (action != m_noAudio) {
|
||||
auto* sound = SoundManager::instance();
|
||||
const QString id = action->data().toString();
|
||||
if (id != sound->captureDevice()) {
|
||||
if (gui_bridge_post_setting(GUI_SETTING_UI_STATE, "audio_input_id", id.toUtf8().constData()) < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop microphone selection could not be saved input=%s", qPrintable(id));
|
||||
m_status->setText(text("Failed to select device")); refreshMicrophones(); synchronize(); return;
|
||||
}
|
||||
sound->setDevices(sound->playbackDevice(), id);
|
||||
}
|
||||
}
|
||||
synchronize(); saveSettings();
|
||||
});
|
||||
for (auto* menu : {m_codec, m_maxQp}) connect(menu, &QMenu::triggered, this, [this] { if (!m_updating) synchronize(); });
|
||||
connect(m_cursor, &QCheckBox::toggled, this, &StreamPublishWindow::apply);
|
||||
connect(m_adaptiveQp, &QCheckBox::toggled, this, &StreamPublishWindow::apply);
|
||||
@@ -283,8 +301,7 @@ void StreamPublishWindow::restoreSettings() {
|
||||
restore(m_maxQp, maxQp, "max_qp"); m_adaptiveQp->setChecked(m_settings.value("adaptive_qp").toBool());
|
||||
restore(m_rotation, m_settings.value("rotation").toInt(), "rotation");
|
||||
m_cursor->setChecked(m_settings.value("show_cursor").toBool(true));
|
||||
if (m_settings.value("audio").toBool(true)) restore(m_microphone, m_settings.value("microphone").toString(), "microphone");
|
||||
else m_noAudio->setChecked(true);
|
||||
if (!m_settings.value("audio").toBool(true)) m_noAudio->setChecked(true);
|
||||
m_updating = false;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop capture settings restored: %s", QJsonDocument(m_settings).toJson(QJsonDocument::Compact).constData());
|
||||
}
|
||||
@@ -303,7 +320,7 @@ void StreamPublishWindow::saveSettings() {
|
||||
}
|
||||
if (selected(m_codec)) saved["codec"] = config.video.codec;
|
||||
saved["bitrate"] = value(m_bitrate).toInt(); saved["rotation"] = config.video.rotation;
|
||||
saved["audio"] = config.audio; saved["microphone"] = config.microphone;
|
||||
saved["audio"] = config.audio; saved.remove("microphone");
|
||||
saved["muted"] = m_audioMuted;
|
||||
saved["show_cursor"] = config.showCursor;
|
||||
saved["max_qp"] = value(m_maxQp).toInt(); saved["adaptive_qp"] = m_adaptiveQp->isChecked();
|
||||
@@ -379,6 +396,19 @@ void StreamPublishWindow::refreshModes(const StreamPublishConfig& previous, bool
|
||||
source.kind == StreamVideoSource::Screen && mode.size == m_modes.front().size);
|
||||
}
|
||||
|
||||
void StreamPublishWindow::refreshMicrophones() {
|
||||
QScopedValueRollback<bool> updating(m_updating, true);
|
||||
const bool audio = m_engine->active() ? m_engine->config().audio : selected(m_microphone) != m_noAudio;
|
||||
const QString input = SoundManager::instance()->captureDevice();
|
||||
clearOptions(m_microphone, "Audio source");
|
||||
m_noAudio = addOption(m_microphone, text("No audio"), QVariant());
|
||||
m_noAudio->setEnabled(!m_engine->active());
|
||||
addOption(m_microphone, text("Default microphone"), QString());
|
||||
for (const auto& device : SoundManager::enumerateCaptureDevices()) addOption(m_microphone, device.name, device.id);
|
||||
if (!option(m_microphone, input)) addOption(m_microphone, text("Selected microphone unavailable"), input);
|
||||
if (audio) select(m_microphone, input); else m_noAudio->setChecked(true);
|
||||
}
|
||||
|
||||
void StreamPublishWindow::refreshCodecs() {
|
||||
QScopedValueRollback<bool> updating(m_updating, true);
|
||||
int previous = selected(m_codec) ? value(m_codec).toInt() : m_settings.value("codec").toInt();
|
||||
@@ -405,7 +435,7 @@ StreamPublishConfig StreamPublishWindow::selection() const {
|
||||
config.adaptiveQp = config.video.maxQp >= 0 && m_adaptiveQp->isChecked();
|
||||
}
|
||||
config.showCursor = m_cursor->isChecked();
|
||||
config.microphone = value(m_microphone).toString(); config.audio = selected(m_microphone) != m_noAudio;
|
||||
config.audio = selected(m_microphone) != m_noAudio;
|
||||
config.startMuted = m_audioMuted; return config;
|
||||
}
|
||||
void StreamPublishWindow::apply() {
|
||||
@@ -422,7 +452,8 @@ void StreamPublishWindow::synchronize() {
|
||||
&& selected(m_source) && selected(m_resolution) && selected(m_fps) && selected(m_codec)));
|
||||
for (auto* menu : {m_source, m_resolution, m_fps, m_codec, m_bitrate, m_rotation})
|
||||
menu->menuAction()->setEnabled(!active || m_engine->running());
|
||||
m_microphone->menuAction()->setEnabled(!active);
|
||||
m_microphone->menuAction()->setEnabled(!active || (m_engine->running() && m_engine->config().audio));
|
||||
m_noAudio->setEnabled(!active);
|
||||
if (active) m_audioMuted = m_engine->muted();
|
||||
bool audio = active ? m_engine->config().audio : selection().audio;
|
||||
m_sound->setEnabled(audio && (!active || m_engine->running()));
|
||||
@@ -443,7 +474,7 @@ void StreamPublishWindow::synchronize() {
|
||||
m_adaptiveQp->setChecked(config.adaptiveQp);
|
||||
}
|
||||
select(m_rotation, config.video.rotation);
|
||||
if (config.audio) select(m_microphone, config.microphone); else m_noAudio->setChecked(true);
|
||||
if (config.audio) select(m_microphone, SoundManager::instance()->captureDevice()); else m_noAudio->setChecked(true);
|
||||
m_cursor->setChecked(config.showCursor);
|
||||
}
|
||||
m_cursor->setVisible(StreamPublishEngine::cursorSupported(selection().source));
|
||||
|
||||
@@ -51,6 +51,7 @@ private:
|
||||
void refreshModes(const StreamPublishConfig& previous, bool maximum = false);
|
||||
void updateMenuButtons(); // Обновляет иконки со значениями и подсказки верхнего ряда после выбора/синхронизации.
|
||||
void refreshCodecs(); // Перечитывает engine.codecs(), сохраняет текущий/saved codec, недоступный заменяет первым.
|
||||
void refreshMicrophones(); // Перечитывает устройства и общий с рацией выбор; «Без звука» относится только к трансляции.
|
||||
void synchronize(); // Читает engine config/state без apply; настраивает controls и ограничения изменения audio/cursor/QP.
|
||||
void apply(); // Для выбранного режима: reconfigure только active-engine, затем сохранение выбора; не во время m_updating.
|
||||
void restoreSettings(); // До start восстанавливает доступные значения JSON; некорректные/отсутствующие диагностируются и заменяются.
|
||||
|
||||
Reference in new issue
Block a user