mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-01-22 21:28:32 -05:00
The status bar doesn't currently own its references to outputs, which can be a problem if streaming outputs are released soon after stream stop. The Multitrack Video output does exactly that, so the status bar will sometimes try to access an invalid pointer for updating its stats. Keeping a weak reference around and upgrading it to collect stats, similar to how the stats window behaves.
644 lines
16 KiB
C++
644 lines
16 KiB
C++
#include <QPainter>
|
|
#include <QPixmap>
|
|
#include "obs-app.hpp"
|
|
#include "window-basic-main.hpp"
|
|
#include "window-basic-status-bar.hpp"
|
|
#include "window-basic-main-outputs.hpp"
|
|
#include "qt-wrappers.hpp"
|
|
#include "platform.hpp"
|
|
|
|
#include "ui_StatusBarWidget.h"
|
|
|
|
static constexpr int bitrateUpdateSeconds = 2;
|
|
static constexpr int congestionUpdateSeconds = 4;
|
|
static constexpr float excellentThreshold = 0.0f;
|
|
static constexpr float goodThreshold = 0.3333f;
|
|
static constexpr float mediocreThreshold = 0.6667f;
|
|
static constexpr float badThreshold = 1.0f;
|
|
|
|
StatusBarWidget::StatusBarWidget(QWidget *parent)
|
|
: QWidget(parent),
|
|
ui(new Ui::StatusBarWidget)
|
|
{
|
|
ui->setupUi(this);
|
|
}
|
|
|
|
StatusBarWidget::~StatusBarWidget() {}
|
|
|
|
OBSBasicStatusBar::OBSBasicStatusBar(QWidget *parent)
|
|
: QStatusBar(parent),
|
|
excellentPixmap(QIcon(":/res/images/network-excellent.svg")
|
|
.pixmap(QSize(16, 16))),
|
|
goodPixmap(
|
|
QIcon(":/res/images/network-good.svg").pixmap(QSize(16, 16))),
|
|
mediocrePixmap(QIcon(":/res/images/network-mediocre.svg")
|
|
.pixmap(QSize(16, 16))),
|
|
badPixmap(
|
|
QIcon(":/res/images/network-bad.svg").pixmap(QSize(16, 16))),
|
|
recordingActivePixmap(QIcon(":/res/images/recording-active.svg")
|
|
.pixmap(QSize(16, 16))),
|
|
recordingPausePixmap(QIcon(":/res/images/recording-pause.svg")
|
|
.pixmap(QSize(16, 16))),
|
|
streamingActivePixmap(QIcon(":/res/images/streaming-active.svg")
|
|
.pixmap(QSize(16, 16)))
|
|
{
|
|
congestionArray.reserve(congestionUpdateSeconds);
|
|
|
|
statusWidget = new StatusBarWidget(this);
|
|
statusWidget->ui->delayInfo->setText("");
|
|
statusWidget->ui->droppedFrames->setText(
|
|
QTStr("DroppedFrames").arg("0", "0.0"));
|
|
statusWidget->ui->statusIcon->setPixmap(inactivePixmap);
|
|
statusWidget->ui->streamIcon->setPixmap(streamingInactivePixmap);
|
|
statusWidget->ui->streamTime->setDisabled(true);
|
|
statusWidget->ui->recordIcon->setPixmap(recordingInactivePixmap);
|
|
statusWidget->ui->recordTime->setDisabled(true);
|
|
statusWidget->ui->delayFrame->hide();
|
|
statusWidget->ui->issuesFrame->hide();
|
|
statusWidget->ui->kbps->hide();
|
|
|
|
addPermanentWidget(statusWidget, 1);
|
|
setMinimumHeight(statusWidget->height());
|
|
|
|
UpdateIcons();
|
|
connect(App(), &OBSApp::StyleChanged, this,
|
|
&OBSBasicStatusBar::UpdateIcons);
|
|
|
|
messageTimer = new QTimer(this);
|
|
messageTimer->setSingleShot(true);
|
|
connect(messageTimer, &QTimer::timeout, this,
|
|
&OBSBasicStatusBar::clearMessage);
|
|
|
|
clearMessage();
|
|
}
|
|
|
|
void OBSBasicStatusBar::Activate()
|
|
{
|
|
if (!active) {
|
|
refreshTimer = new QTimer(this);
|
|
connect(refreshTimer, &QTimer::timeout, this,
|
|
&OBSBasicStatusBar::UpdateStatusBar);
|
|
|
|
int skipped = video_output_get_skipped_frames(obs_get_video());
|
|
int total = video_output_get_total_frames(obs_get_video());
|
|
|
|
totalStreamSeconds = 0;
|
|
totalRecordSeconds = 0;
|
|
lastSkippedFrameCount = 0;
|
|
startSkippedFrameCount = skipped;
|
|
startTotalFrameCount = total;
|
|
|
|
refreshTimer->start(1000);
|
|
active = true;
|
|
|
|
if (streamOutput) {
|
|
statusWidget->ui->statusIcon->setPixmap(inactivePixmap);
|
|
}
|
|
}
|
|
|
|
if (streamOutput) {
|
|
statusWidget->ui->streamIcon->setPixmap(streamingActivePixmap);
|
|
statusWidget->ui->streamTime->setDisabled(false);
|
|
statusWidget->ui->issuesFrame->show();
|
|
statusWidget->ui->kbps->show();
|
|
firstCongestionUpdate = true;
|
|
}
|
|
|
|
if (recordOutput) {
|
|
statusWidget->ui->recordIcon->setPixmap(recordingActivePixmap);
|
|
statusWidget->ui->recordTime->setDisabled(false);
|
|
}
|
|
}
|
|
|
|
void OBSBasicStatusBar::Deactivate()
|
|
{
|
|
OBSBasic *main = qobject_cast<OBSBasic *>(parent());
|
|
if (!main)
|
|
return;
|
|
|
|
if (!streamOutput) {
|
|
statusWidget->ui->streamTime->setText(QString("00:00:00"));
|
|
statusWidget->ui->streamTime->setDisabled(true);
|
|
statusWidget->ui->streamIcon->setPixmap(
|
|
streamingInactivePixmap);
|
|
statusWidget->ui->statusIcon->setPixmap(inactivePixmap);
|
|
statusWidget->ui->delayFrame->hide();
|
|
statusWidget->ui->issuesFrame->hide();
|
|
statusWidget->ui->kbps->hide();
|
|
totalStreamSeconds = 0;
|
|
congestionArray.clear();
|
|
disconnected = false;
|
|
firstCongestionUpdate = false;
|
|
}
|
|
|
|
if (!recordOutput) {
|
|
statusWidget->ui->recordTime->setText(QString("00:00:00"));
|
|
statusWidget->ui->recordTime->setDisabled(true);
|
|
statusWidget->ui->recordIcon->setPixmap(
|
|
recordingInactivePixmap);
|
|
totalRecordSeconds = 0;
|
|
}
|
|
|
|
if (main->outputHandler && !main->outputHandler->Active()) {
|
|
delete refreshTimer;
|
|
|
|
statusWidget->ui->delayInfo->setText("");
|
|
statusWidget->ui->droppedFrames->setText(
|
|
QTStr("DroppedFrames").arg("0", "0.0"));
|
|
statusWidget->ui->kbps->setText("0 kbps");
|
|
|
|
delaySecTotal = 0;
|
|
delaySecStarting = 0;
|
|
delaySecStopping = 0;
|
|
reconnectTimeout = 0;
|
|
active = false;
|
|
overloadedNotify = true;
|
|
|
|
statusWidget->ui->statusIcon->setPixmap(inactivePixmap);
|
|
}
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateDelayMsg()
|
|
{
|
|
QString msg;
|
|
|
|
if (delaySecTotal) {
|
|
if (delaySecStarting && !delaySecStopping) {
|
|
msg = QTStr("Basic.StatusBar.DelayStartingIn");
|
|
msg = msg.arg(QString::number(delaySecStarting));
|
|
|
|
} else if (!delaySecStarting && delaySecStopping) {
|
|
msg = QTStr("Basic.StatusBar.DelayStoppingIn");
|
|
msg = msg.arg(QString::number(delaySecStopping));
|
|
|
|
} else if (delaySecStarting && delaySecStopping) {
|
|
msg = QTStr("Basic.StatusBar.DelayStartingStoppingIn");
|
|
msg = msg.arg(QString::number(delaySecStopping),
|
|
QString::number(delaySecStarting));
|
|
} else {
|
|
msg = QTStr("Basic.StatusBar.Delay");
|
|
msg = msg.arg(QString::number(delaySecTotal));
|
|
}
|
|
|
|
if (!statusWidget->ui->delayFrame->isVisible())
|
|
statusWidget->ui->delayFrame->show();
|
|
|
|
statusWidget->ui->delayInfo->setText(msg);
|
|
}
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateBandwidth()
|
|
{
|
|
if (!streamOutput)
|
|
return;
|
|
|
|
if (++seconds < bitrateUpdateSeconds)
|
|
return;
|
|
|
|
OBSOutput output = OBSGetStrongRef(streamOutput);
|
|
if (!output)
|
|
return;
|
|
|
|
uint64_t bytesSent = obs_output_get_total_bytes(output);
|
|
uint64_t bytesSentTime = os_gettime_ns();
|
|
|
|
if (bytesSent < lastBytesSent)
|
|
bytesSent = 0;
|
|
if (bytesSent == 0)
|
|
lastBytesSent = 0;
|
|
|
|
uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8;
|
|
|
|
double timePassed =
|
|
double(bytesSentTime - lastBytesSentTime) / 1000000000.0;
|
|
|
|
double kbitsPerSec = double(bitsBetween) / timePassed / 1000.0;
|
|
|
|
QString text;
|
|
text += QString::number(kbitsPerSec, 'f', 0) + QString(" kbps");
|
|
|
|
statusWidget->ui->kbps->setText(text);
|
|
statusWidget->ui->kbps->setMinimumWidth(
|
|
statusWidget->ui->kbps->width());
|
|
|
|
if (!statusWidget->ui->kbps->isVisible())
|
|
statusWidget->ui->kbps->show();
|
|
|
|
lastBytesSent = bytesSent;
|
|
lastBytesSentTime = bytesSentTime;
|
|
seconds = 0;
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateCPUUsage()
|
|
{
|
|
OBSBasic *main = qobject_cast<OBSBasic *>(parent());
|
|
if (!main)
|
|
return;
|
|
|
|
QString text;
|
|
text += QString("CPU: ") +
|
|
QString::number(main->GetCPUUsage(), 'f', 1) + QString("%");
|
|
|
|
statusWidget->ui->cpuUsage->setText(text);
|
|
statusWidget->ui->cpuUsage->setMinimumWidth(
|
|
statusWidget->ui->cpuUsage->width());
|
|
|
|
UpdateCurrentFPS();
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateCurrentFPS()
|
|
{
|
|
struct obs_video_info ovi;
|
|
obs_get_video_info(&ovi);
|
|
float targetFPS = (float)ovi.fps_num / (float)ovi.fps_den;
|
|
|
|
QString text = QString::asprintf("%.2f / %.2f FPS",
|
|
obs_get_active_fps(), targetFPS);
|
|
|
|
statusWidget->ui->fpsCurrent->setText(text);
|
|
statusWidget->ui->fpsCurrent->setMinimumWidth(
|
|
statusWidget->ui->fpsCurrent->width());
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateStreamTime()
|
|
{
|
|
totalStreamSeconds++;
|
|
|
|
int seconds = totalStreamSeconds % 60;
|
|
int totalMinutes = totalStreamSeconds / 60;
|
|
int minutes = totalMinutes % 60;
|
|
int hours = totalMinutes / 60;
|
|
|
|
QString text =
|
|
QString::asprintf("%02d:%02d:%02d", hours, minutes, seconds);
|
|
statusWidget->ui->streamTime->setText(text);
|
|
if (streamOutput && !statusWidget->ui->streamTime->isEnabled())
|
|
statusWidget->ui->streamTime->setDisabled(false);
|
|
|
|
if (reconnectTimeout > 0) {
|
|
QString msg = QTStr("Basic.StatusBar.Reconnecting")
|
|
.arg(QString::number(retries),
|
|
QString::number(reconnectTimeout));
|
|
showMessage(msg);
|
|
disconnected = true;
|
|
statusWidget->ui->statusIcon->setPixmap(disconnectedPixmap);
|
|
congestionArray.clear();
|
|
reconnectTimeout--;
|
|
|
|
} else if (retries > 0) {
|
|
QString msg = QTStr("Basic.StatusBar.AttemptingReconnect");
|
|
showMessage(msg.arg(QString::number(retries)));
|
|
}
|
|
|
|
if (delaySecStopping > 0 || delaySecStarting > 0) {
|
|
if (delaySecStopping > 0)
|
|
--delaySecStopping;
|
|
if (delaySecStarting > 0)
|
|
--delaySecStarting;
|
|
UpdateDelayMsg();
|
|
}
|
|
}
|
|
|
|
extern volatile bool recording_paused;
|
|
|
|
void OBSBasicStatusBar::UpdateRecordTime()
|
|
{
|
|
bool paused = os_atomic_load_bool(&recording_paused);
|
|
|
|
if (!paused) {
|
|
totalRecordSeconds++;
|
|
|
|
if (recordOutput && !statusWidget->ui->recordTime->isEnabled())
|
|
statusWidget->ui->recordTime->setDisabled(false);
|
|
} else {
|
|
statusWidget->ui->recordIcon->setPixmap(
|
|
streamPauseIconToggle ? recordingPauseInactivePixmap
|
|
: recordingPausePixmap);
|
|
|
|
streamPauseIconToggle = !streamPauseIconToggle;
|
|
}
|
|
|
|
UpdateRecordTimeLabel();
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateRecordTimeLabel()
|
|
{
|
|
int seconds = totalRecordSeconds % 60;
|
|
int totalMinutes = totalRecordSeconds / 60;
|
|
int minutes = totalMinutes % 60;
|
|
int hours = totalMinutes / 60;
|
|
|
|
QString text =
|
|
QString::asprintf("%02d:%02d:%02d", hours, minutes, seconds);
|
|
if (os_atomic_load_bool(&recording_paused)) {
|
|
text += QStringLiteral(" (PAUSED)");
|
|
}
|
|
|
|
statusWidget->ui->recordTime->setText(text);
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateDroppedFrames()
|
|
{
|
|
if (!streamOutput)
|
|
return;
|
|
|
|
OBSOutput output = OBSGetStrongRef(streamOutput);
|
|
if (!output)
|
|
return;
|
|
|
|
int totalDropped = obs_output_get_frames_dropped(output);
|
|
int totalFrames = obs_output_get_total_frames(output);
|
|
double percent = (double)totalDropped / (double)totalFrames * 100.0;
|
|
|
|
if (!totalFrames)
|
|
return;
|
|
|
|
QString text = QTStr("DroppedFrames");
|
|
text = text.arg(QString::number(totalDropped),
|
|
QString::number(percent, 'f', 1));
|
|
statusWidget->ui->droppedFrames->setText(text);
|
|
|
|
if (!statusWidget->ui->issuesFrame->isVisible())
|
|
statusWidget->ui->issuesFrame->show();
|
|
|
|
/* ----------------------------------- *
|
|
* calculate congestion color */
|
|
|
|
float congestion = obs_output_get_congestion(output);
|
|
float avgCongestion = (congestion + lastCongestion) * 0.5f;
|
|
if (avgCongestion < congestion)
|
|
avgCongestion = congestion;
|
|
if (avgCongestion > 1.0f)
|
|
avgCongestion = 1.0f;
|
|
|
|
lastCongestion = congestion;
|
|
|
|
if (disconnected)
|
|
return;
|
|
|
|
bool update = firstCongestionUpdate;
|
|
float congestionOverTime = avgCongestion;
|
|
|
|
if (congestionArray.size() >= congestionUpdateSeconds) {
|
|
congestionOverTime = accumulate(congestionArray.begin(),
|
|
congestionArray.end(), 0.0f) /
|
|
(float)congestionArray.size();
|
|
congestionArray.clear();
|
|
update = true;
|
|
} else {
|
|
congestionArray.emplace_back(avgCongestion);
|
|
}
|
|
|
|
if (update) {
|
|
if (congestionOverTime <= excellentThreshold + EPSILON)
|
|
statusWidget->ui->statusIcon->setPixmap(
|
|
excellentPixmap);
|
|
else if (congestionOverTime <= goodThreshold)
|
|
statusWidget->ui->statusIcon->setPixmap(goodPixmap);
|
|
else if (congestionOverTime <= mediocreThreshold)
|
|
statusWidget->ui->statusIcon->setPixmap(mediocrePixmap);
|
|
else if (congestionOverTime <= badThreshold)
|
|
statusWidget->ui->statusIcon->setPixmap(badPixmap);
|
|
|
|
firstCongestionUpdate = false;
|
|
}
|
|
}
|
|
|
|
void OBSBasicStatusBar::OBSOutputReconnect(void *data, calldata_t *params)
|
|
{
|
|
OBSBasicStatusBar *statusBar =
|
|
reinterpret_cast<OBSBasicStatusBar *>(data);
|
|
|
|
int seconds = (int)calldata_int(params, "timeout_sec");
|
|
QMetaObject::invokeMethod(statusBar, "Reconnect", Q_ARG(int, seconds));
|
|
}
|
|
|
|
void OBSBasicStatusBar::OBSOutputReconnectSuccess(void *data, calldata_t *)
|
|
{
|
|
OBSBasicStatusBar *statusBar =
|
|
reinterpret_cast<OBSBasicStatusBar *>(data);
|
|
|
|
QMetaObject::invokeMethod(statusBar, "ReconnectSuccess");
|
|
}
|
|
|
|
void OBSBasicStatusBar::Reconnect(int seconds)
|
|
{
|
|
OBSBasic *main = qobject_cast<OBSBasic *>(parent());
|
|
|
|
if (!retries)
|
|
main->SysTrayNotify(
|
|
QTStr("Basic.SystemTray.Message.Reconnecting"),
|
|
QSystemTrayIcon::Warning);
|
|
|
|
reconnectTimeout = seconds;
|
|
|
|
if (streamOutput) {
|
|
OBSOutput output = OBSGetStrongRef(streamOutput);
|
|
if (!output)
|
|
return;
|
|
|
|
delaySecTotal = obs_output_get_active_delay(output);
|
|
UpdateDelayMsg();
|
|
|
|
retries++;
|
|
}
|
|
}
|
|
|
|
void OBSBasicStatusBar::ReconnectClear()
|
|
{
|
|
retries = 0;
|
|
reconnectTimeout = 0;
|
|
seconds = -1;
|
|
lastBytesSent = 0;
|
|
lastBytesSentTime = os_gettime_ns();
|
|
delaySecTotal = 0;
|
|
UpdateDelayMsg();
|
|
}
|
|
|
|
void OBSBasicStatusBar::ReconnectSuccess()
|
|
{
|
|
OBSBasic *main = qobject_cast<OBSBasic *>(parent());
|
|
|
|
QString msg = QTStr("Basic.StatusBar.ReconnectSuccessful");
|
|
showMessage(msg, 4000);
|
|
main->SysTrayNotify(msg, QSystemTrayIcon::Information);
|
|
ReconnectClear();
|
|
|
|
if (streamOutput) {
|
|
OBSOutput output = OBSGetStrongRef(streamOutput);
|
|
if (!output)
|
|
return;
|
|
|
|
delaySecTotal = obs_output_get_active_delay(output);
|
|
UpdateDelayMsg();
|
|
disconnected = false;
|
|
firstCongestionUpdate = true;
|
|
}
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateStatusBar()
|
|
{
|
|
OBSBasic *main = qobject_cast<OBSBasic *>(parent());
|
|
|
|
UpdateBandwidth();
|
|
|
|
if (streamOutput)
|
|
UpdateStreamTime();
|
|
|
|
if (recordOutput)
|
|
UpdateRecordTime();
|
|
|
|
UpdateDroppedFrames();
|
|
|
|
int skipped = video_output_get_skipped_frames(obs_get_video());
|
|
int total = video_output_get_total_frames(obs_get_video());
|
|
|
|
skipped -= startSkippedFrameCount;
|
|
total -= startTotalFrameCount;
|
|
|
|
int diff = skipped - lastSkippedFrameCount;
|
|
double percentage = double(skipped) / double(total) * 100.0;
|
|
|
|
if (diff > 10 && percentage >= 0.1f) {
|
|
showMessage(QTStr("HighResourceUsage"), 4000);
|
|
if (!main->isVisible() && overloadedNotify) {
|
|
main->SysTrayNotify(QTStr("HighResourceUsage"),
|
|
QSystemTrayIcon::Warning);
|
|
overloadedNotify = false;
|
|
}
|
|
}
|
|
|
|
lastSkippedFrameCount = skipped;
|
|
}
|
|
|
|
void OBSBasicStatusBar::StreamDelayStarting(int sec)
|
|
{
|
|
OBSBasic *main = qobject_cast<OBSBasic *>(parent());
|
|
if (!main || !main->outputHandler)
|
|
return;
|
|
|
|
OBSOutputAutoRelease output = obs_frontend_get_streaming_output();
|
|
streamOutput = obs_output_get_weak_output(output);
|
|
|
|
delaySecTotal = delaySecStarting = sec;
|
|
UpdateDelayMsg();
|
|
Activate();
|
|
}
|
|
|
|
void OBSBasicStatusBar::StreamDelayStopping(int sec)
|
|
{
|
|
delaySecTotal = delaySecStopping = sec;
|
|
UpdateDelayMsg();
|
|
}
|
|
|
|
void OBSBasicStatusBar::StreamStarted(obs_output_t *output)
|
|
{
|
|
streamOutput = obs_output_get_weak_output(output);
|
|
|
|
streamSigs.emplace_back(obs_output_get_signal_handler(output),
|
|
"reconnect", OBSOutputReconnect, this);
|
|
streamSigs.emplace_back(obs_output_get_signal_handler(output),
|
|
"reconnect_success", OBSOutputReconnectSuccess,
|
|
this);
|
|
|
|
retries = 0;
|
|
lastBytesSent = 0;
|
|
lastBytesSentTime = os_gettime_ns();
|
|
Activate();
|
|
}
|
|
|
|
void OBSBasicStatusBar::StreamStopped()
|
|
{
|
|
if (streamOutput) {
|
|
streamSigs.clear();
|
|
|
|
ReconnectClear();
|
|
streamOutput = nullptr;
|
|
clearMessage();
|
|
Deactivate();
|
|
}
|
|
}
|
|
|
|
void OBSBasicStatusBar::RecordingStarted(obs_output_t *output)
|
|
{
|
|
recordOutput = output;
|
|
Activate();
|
|
}
|
|
|
|
void OBSBasicStatusBar::RecordingStopped()
|
|
{
|
|
recordOutput = nullptr;
|
|
Deactivate();
|
|
}
|
|
|
|
void OBSBasicStatusBar::RecordingPaused()
|
|
{
|
|
if (recordOutput) {
|
|
statusWidget->ui->recordIcon->setPixmap(recordingPausePixmap);
|
|
streamPauseIconToggle = true;
|
|
}
|
|
|
|
UpdateRecordTimeLabel();
|
|
}
|
|
|
|
void OBSBasicStatusBar::RecordingUnpaused()
|
|
{
|
|
if (recordOutput) {
|
|
statusWidget->ui->recordIcon->setPixmap(recordingActivePixmap);
|
|
}
|
|
|
|
UpdateRecordTimeLabel();
|
|
}
|
|
|
|
static QPixmap GetPixmap(const QString &filename)
|
|
{
|
|
QString path = obs_frontend_is_theme_dark() ? "theme:Dark/"
|
|
: ":/res/images/";
|
|
return QIcon(path + filename).pixmap(QSize(16, 16));
|
|
}
|
|
|
|
void OBSBasicStatusBar::UpdateIcons()
|
|
{
|
|
disconnectedPixmap = GetPixmap("network-disconnected.svg");
|
|
inactivePixmap = GetPixmap("network-inactive.svg");
|
|
|
|
streamingInactivePixmap = GetPixmap("streaming-inactive.svg");
|
|
|
|
recordingInactivePixmap = GetPixmap("recording-inactive.svg");
|
|
recordingPauseInactivePixmap =
|
|
GetPixmap("recording-pause-inactive.svg");
|
|
|
|
bool streaming = obs_frontend_streaming_active();
|
|
|
|
if (!streaming) {
|
|
statusWidget->ui->streamIcon->setPixmap(
|
|
streamingInactivePixmap);
|
|
statusWidget->ui->statusIcon->setPixmap(inactivePixmap);
|
|
} else {
|
|
if (disconnected)
|
|
statusWidget->ui->statusIcon->setPixmap(
|
|
disconnectedPixmap);
|
|
}
|
|
|
|
bool recording = obs_frontend_recording_active();
|
|
|
|
if (!recording)
|
|
statusWidget->ui->recordIcon->setPixmap(
|
|
recordingInactivePixmap);
|
|
}
|
|
|
|
void OBSBasicStatusBar::showMessage(const QString &message, int timeout)
|
|
{
|
|
messageTimer->stop();
|
|
|
|
statusWidget->ui->message->setText(message);
|
|
|
|
if (timeout)
|
|
messageTimer->start(timeout);
|
|
}
|
|
|
|
void OBSBasicStatusBar::clearMessage()
|
|
{
|
|
statusWidget->ui->message->setText("");
|
|
}
|