1
0
Эх сурвалжийг харах

UI: Estimate recording time left until disk is full

Clayton Groeneveld 6 жил өмнө
parent
commit
171f811669

+ 2 - 0
UI/data/locale/en-US.ini

@@ -87,6 +87,7 @@ VerticalLayout="Vertical Layout"
 Group="Group"
 Group="Group"
 DoNotShowAgain="Do not show again"
 DoNotShowAgain="Do not show again"
 Default="(Default)"
 Default="(Default)"
+Calculating="Calculating..."
 
 
 # warning if program already open
 # warning if program already open
 AlreadyRunning.Title="OBS is already running"
 AlreadyRunning.Title="OBS is already running"
@@ -200,6 +201,7 @@ Basic.Stats.Status.Inactive="Inactive"
 Basic.Stats.DroppedFrames="Dropped Frames (Network)"
 Basic.Stats.DroppedFrames="Dropped Frames (Network)"
 Basic.Stats.MegabytesSent="Total Data Output"
 Basic.Stats.MegabytesSent="Total Data Output"
 Basic.Stats.Bitrate="Bitrate"
 Basic.Stats.Bitrate="Bitrate"
+Basic.Stats.DiskFullIn="Disk full in (approx.)"
 
 
 ResetUIWarning.Title="Are you sure you want to reset the UI?"
 ResetUIWarning.Title="Are you sure you want to reset the UI?"
 ResetUIWarning.Text="Resetting the UI will hide additional docks. You will need to unhide these docks from the view menu if you want them to be visible.\n\nAre you sure you want to reset the UI?"
 ResetUIWarning.Text="Resetting the UI will hide additional docks. You will need to unhide these docks from the view menu if you want them to be visible.\n\nAre you sure you want to reset the UI?"

+ 70 - 4
UI/window-basic-stats.cpp

@@ -4,6 +4,7 @@
 #include "window-basic-main.hpp"
 #include "window-basic-main.hpp"
 #include "platform.hpp"
 #include "platform.hpp"
 #include "obs-app.hpp"
 #include "obs-app.hpp"
+#include "qt-wrappers.hpp"
 
 
 #include <QDesktopWidget>
 #include <QDesktopWidget>
 #include <QPushButton>
 #include <QPushButton>
@@ -15,6 +16,7 @@
 #include <string>
 #include <string>
 
 
 #define TIMER_INTERVAL 2000
 #define TIMER_INTERVAL 2000
+#define REC_TIME_LEFT_INTERVAL 30000
 
 
 static void setThemeID(QWidget *widget, const QString &themeID)
 static void setThemeID(QWidget *widget, const QString &themeID)
 {
 {
@@ -28,15 +30,32 @@ static void setThemeID(QWidget *widget, const QString &themeID)
 	}
 	}
 }
 }
 
 
+void OBSBasicStats::OBSFrontendEvent(enum obs_frontend_event event, void *ptr)
+{
+	OBSBasicStats *stats = reinterpret_cast<OBSBasicStats *>(ptr);
+
+	switch ((int)event) {
+	case OBS_FRONTEND_EVENT_RECORDING_STARTED:
+		stats->StartRecTimeLeft();
+		break;
+	case OBS_FRONTEND_EVENT_RECORDING_STOPPED:
+		stats->ResetRecTimeLeft();
+		break;
+	}
+}
+
 OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
 OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
 	: QWidget             (parent),
 	: QWidget             (parent),
 	  cpu_info            (os_cpu_usage_info_start()),
 	  cpu_info            (os_cpu_usage_info_start()),
-	  timer               (this)
+	  timer               (this),
+	  recTimeLeft         (this)
 {
 {
 	QVBoxLayout *mainLayout = new QVBoxLayout();
 	QVBoxLayout *mainLayout = new QVBoxLayout();
 	QGridLayout *topLayout = new QGridLayout();
 	QGridLayout *topLayout = new QGridLayout();
 	outputLayout = new QGridLayout();
 	outputLayout = new QGridLayout();
 
 
+	bitrates.reserve(REC_TIME_LEFT_INTERVAL / TIMER_INTERVAL);
+
 	int row = 0;
 	int row = 0;
 
 
 	auto newStatBare = [&] (QString name, QWidget *label, int col)
 	auto newStatBare = [&] (QString name, QWidget *label, int col)
@@ -57,10 +76,12 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
 
 
 	cpuUsage = new QLabel(this);
 	cpuUsage = new QLabel(this);
 	hddSpace = new QLabel(this);
 	hddSpace = new QLabel(this);
+	recordTimeLeft = new QLabel(this);
 	memUsage = new QLabel(this);
 	memUsage = new QLabel(this);
 
 
 	newStat("CPUUsage", cpuUsage, 0);
 	newStat("CPUUsage", cpuUsage, 0);
 	newStat("HDDSpaceAvailable", hddSpace, 0);
 	newStat("HDDSpaceAvailable", hddSpace, 0);
+	newStat("DiskFullIn", recordTimeLeft, 0);
 	newStat("MemoryUsage", memUsage, 0);
 	newStat("MemoryUsage", memUsage, 0);
 
 
 	fps = new QLabel(this);
 	fps = new QLabel(this);
@@ -152,6 +173,11 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
 
 
 	Update();
 	Update();
 
 
+	QObject::connect(&recTimeLeft, &QTimer::timeout, this,
+			&OBSBasicStats::RecordingTimeLeft);
+	recTimeLeft.setInterval(REC_TIME_LEFT_INTERVAL);
+	recTimeLeft.start();
+
 	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
 	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
 
 
 	const char *geometry = config_get_string(main->Config(),
 	const char *geometry = config_get_string(main->Config(),
@@ -170,6 +196,8 @@ OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable)
 						size(), rect));
 						size(), rect));
 		}
 		}
 	}
 	}
+
+	obs_frontend_add_event_callback(OBSFrontendEvent, this);
 }
 }
 
 
 void OBSBasicStats::closeEvent(QCloseEvent *event)
 void OBSBasicStats::closeEvent(QCloseEvent *event)
@@ -280,7 +308,7 @@ void OBSBasicStats::Update()
 #define MBYTE (1024ULL * 1024ULL)
 #define MBYTE (1024ULL * 1024ULL)
 #define GBYTE (1024ULL * 1024ULL * 1024ULL)
 #define GBYTE (1024ULL * 1024ULL * 1024ULL)
 #define TBYTE (1024ULL * 1024ULL * 1024ULL * 1024ULL)
 #define TBYTE (1024ULL * 1024ULL * 1024ULL * 1024ULL)
-	uint64_t num_bytes = os_get_free_disk_space(path);
+	num_bytes = os_get_free_disk_space(path);
 	QString abrv = QStringLiteral(" MB");
 	QString abrv = QStringLiteral(" MB");
 	long double num;
 	long double num;
 
 
@@ -393,6 +421,45 @@ void OBSBasicStats::Update()
 
 
 	outputLabels[0].Update(strOutput, false);
 	outputLabels[0].Update(strOutput, false);
 	outputLabels[1].Update(recOutput, true);
 	outputLabels[1].Update(recOutput, true);
+
+	if (obs_output_active(recOutput)) {
+		long double kbps = outputLabels[1].kbps;
+		bitrates.push_back(kbps);
+	}
+}
+
+void OBSBasicStats::StartRecTimeLeft()
+{
+	recordTimeLeft->setText(QTStr("Calculating"));
+	recTimeLeft.start();
+}
+
+void OBSBasicStats::ResetRecTimeLeft()
+{
+	bitrates.clear();
+	recTimeLeft.stop();
+	recordTimeLeft->setText(QTStr(""));
+}
+
+void OBSBasicStats::RecordingTimeLeft()
+{
+	long double averageBitrate = accumulate(bitrates.begin(),
+			bitrates.end(), 0.0) /
+			(long double)bitrates.size();
+	long double bytesPerSec = (averageBitrate / 8.0l) * 1000.0l;
+	long double secondsUntilFull = (long double)num_bytes / bytesPerSec;
+
+	bitrates.clear();
+
+	int totalMinutes = (int)secondsUntilFull / 60;
+	int minutes      = totalMinutes % 60;
+	int hours        = totalMinutes / 60;
+
+	QString text;
+	text.sprintf("%d %s, %d %s", hours, QT_TO_UTF8(QTStr("Hours")),
+			minutes, QT_TO_UTF8(QTStr("Minutes")));
+	recordTimeLeft->setText(text);
+	recordTimeLeft->setMinimumWidth(recordTimeLeft->width());
 }
 }
 
 
 void OBSBasicStats::Reset()
 void OBSBasicStats::Reset()
@@ -428,8 +495,7 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec)
 	uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8;
 	uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8;
 	long double timePassed = (long double)(curTime - lastBytesSentTime) /
 	long double timePassed = (long double)(curTime - lastBytesSentTime) /
 		1000000000.0l;
 		1000000000.0l;
-	long double kbps = (long double)bitsBetween /
-		timePassed / 1000.0l;
+	kbps = (long double)bitsBetween / timePassed / 1000.0l;
 
 
 	if (timePassed < 0.01l)
 	if (timePassed < 0.01l)
 		kbps = 0.0l;
 		kbps = 0.0l;

+ 15 - 0
UI/window-basic-stats.hpp

@@ -17,6 +17,7 @@ class OBSBasicStats : public QWidget {
 	QLabel *fps = nullptr;
 	QLabel *fps = nullptr;
 	QLabel *cpuUsage = nullptr;
 	QLabel *cpuUsage = nullptr;
 	QLabel *hddSpace = nullptr;
 	QLabel *hddSpace = nullptr;
+	QLabel *recordTimeLeft = nullptr;
 	QLabel *memUsage = nullptr;
 	QLabel *memUsage = nullptr;
 
 
 	QLabel *renderTime = nullptr;
 	QLabel *renderTime = nullptr;
@@ -28,6 +29,9 @@ class OBSBasicStats : public QWidget {
 	os_cpu_usage_info_t *cpu_info = nullptr;
 	os_cpu_usage_info_t *cpu_info = nullptr;
 
 
 	QTimer timer;
 	QTimer timer;
+	QTimer recTimeLeft;
+	uint64_t num_bytes = 0;
+	std::vector<long double> bitrates;
 
 
 	struct OutputLabels {
 	struct OutputLabels {
 		QPointer<QLabel> name;
 		QPointer<QLabel> name;
@@ -44,6 +48,8 @@ class OBSBasicStats : public QWidget {
 
 
 		void Update(obs_output_t *output, bool rec);
 		void Update(obs_output_t *output, bool rec);
 		void Reset(obs_output_t *output);
 		void Reset(obs_output_t *output);
+
+		long double kbps = 0.0l;
 	};
 	};
 
 
 	QList<OutputLabels> outputLabels;
 	QList<OutputLabels> outputLabels;
@@ -54,14 +60,23 @@ class OBSBasicStats : public QWidget {
 
 
 	virtual void closeEvent(QCloseEvent *event) override;
 	virtual void closeEvent(QCloseEvent *event) override;
 
 
+	static void OBSFrontendEvent(enum obs_frontend_event event, void *ptr);
+
 public:
 public:
 	OBSBasicStats(QWidget *parent = nullptr, bool closable = true);
 	OBSBasicStats(QWidget *parent = nullptr, bool closable = true);
 	~OBSBasicStats();
 	~OBSBasicStats();
 
 
 	static void InitializeValues();
 	static void InitializeValues();
+
+	void StartRecTimeLeft();
+	void ResetRecTimeLeft();
+
 private:
 private:
 	QPointer<QObject> shortcutFilter;
 	QPointer<QObject> shortcutFilter;
 
 
+private slots:
+	void RecordingTimeLeft();
+
 protected:
 protected:
 	virtual void showEvent(QShowEvent *event) override;
 	virtual void showEvent(QShowEvent *event) override;
 	virtual void hideEvent(QHideEvent *event) override;
 	virtual void hideEvent(QHideEvent *event) override;