Pārlūkot izejas kodu

retry websocket connection every 3 seconds w/ animation

Noah Vogt 15 stundas atpakaļ
vecāks
revīzija
420aa140a6
2 mainītis faili ar 76 papildinājumiem un 34 dzēšanām
  1. 5 4
      README.md
  2. 71 30
      cd-rec-status.cpp

+ 5 - 4
README.md

@@ -7,19 +7,20 @@ An [OBS](https://github.com/obsproject/obs-studio) plugin to display the status
 The [offical obs plugin template](https://github.com/obsproject/obs-plugintemplate) was used to create this plugin.
 
 ## How it works
-
 This plugin listens in on a WebSocket server on `ws://localhost:8765` from which it receives messages like:
 ```json
 {
   "recording": true,
   "cd": 3,
   "track": 7,
-  "cd_time": "00:12:03",
-  "track_time": "00:01:26"
+  "cd_time": "12:03",
+  "track_time": "01:26"
 }
 ```
-It then adds a dock on the obs studio interface titled *CD Rec Status* that displays the state of the (ongoing) cd recording.
 
+An example implemtation of such a websocket can be found [here](https://github.com/noahvogt/slidegen/blob/master/cd_recording_status_websocket.py).
+
+It then adds a dock on the obs studio interface titled *CD Rec Status* that displays the state of the (ongoing) cd recording.
 
 ## Building
 - checkout the [obs studio](https://github.com/obsproject/obs-studio) repository

+ 71 - 30
cd-rec-status.cpp

@@ -14,12 +14,24 @@ OBS_MODULE_USE_DEFAULT_LOCALE("cd-rec-status", "en-US")
 
 class CDStatusDock : public QWidget {
 public:
-    CDStatusDock(QWidget *parent = nullptr) : QWidget(parent), socket(new QWebSocket()) {
+    CDStatusDock(QWidget *parent = nullptr) : QWidget(parent), socket(new QWebSocket()), retryDotCount(0) {
         QVBoxLayout *layout = new QVBoxLayout(this);
-        statusLabel = new QLabel("Connecting to server...", this);
+        statusLabel = new QLabel("Connecting to websocket...", this);
         layout->addWidget(statusLabel);
         setLayout(layout);
 
+        retryDotCount = 0;
+
+        // Retry every 3s
+        reconnectTimer = new QTimer(this);
+        reconnectTimer->setInterval(3000);
+        connect(reconnectTimer, &QTimer::timeout, this, &CDStatusDock::tryReconnect);
+
+        // Animate retrying text every 500ms
+        retryAnimationTimer = new QTimer(this);
+        retryAnimationTimer->setInterval(500);
+        connect(retryAnimationTimer, &QTimer::timeout, this, &CDStatusDock::updateRetryingLabel);
+
         connect(socket, &QWebSocket::connected, this, &CDStatusDock::onConnected);
         connect(socket, &QWebSocket::disconnected, this, &CDStatusDock::onDisconnected);
         connect(socket, &QWebSocket::textMessageReceived, this, &CDStatusDock::onMessageReceived);
@@ -28,22 +40,40 @@ public:
     }
 
     ~CDStatusDock() {
+        reconnectTimer->stop();
+	retryAnimationTimer->stop();
         socket->close();
         delete socket;
     }
 
-
 private slots:
     void onConnected() {
-        statusLabel->setText("Connected to status server");
-        updateBackgroundColor(Qt::gray);  // assume no recording yet
+        reconnectTimer->stop();
+        retryAnimationTimer->stop();
+        statusLabel->setText("Connected to websocket");
+        updateBackgroundColor(Qt::gray);
     }
 
+
     void onDisconnected() {
-        statusLabel->setText("Disconnected from server");
+        retryDotCount = 0;
+        reconnectTimer->start();
+        retryAnimationTimer->start();
+        updateRetryingLabel();
         updateBackgroundColor(Qt::red);
     }
 
+    void tryReconnect() {
+        if (socket->state() == QAbstractSocket::ConnectedState ||
+            socket->state() == QAbstractSocket::ConnectingState)
+            return;
+
+        socket->abort();  // force close if half-open
+        socket->open(QUrl(QStringLiteral("ws://localhost:8765")));
+
+        updateRetryingLabel();
+    }
+
     void onMessageReceived(const QString &message) {
         QJsonParseError parseError;
         QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &parseError);
@@ -56,41 +86,52 @@ private slots:
         QJsonObject obj = doc.object();
         bool isRecording = obj["recording"].toBool();
 
-	QString statusText;
-	if (isRecording) {
-		statusText =
-			QString("Recording: active\nCD: %2\nTrack: %3\nElapsed CD Time: %4\nElapsed Track Time: %5")
-				.arg(obj["cd"].toInt())
-				.arg(obj["track"].toInt())
-				.arg(obj["cd_time"].toString())
-				.arg(obj["track_time"].toString());
-	} else {
-		statusText = QString("Recording is currently not active.");
-	}
-
-	statusLabel->setText(statusText);
+        QString statusText;
+        if (isRecording) {
+            statusText =
+                QString("Recording: active\nCD: %1\nTrack: %2\nElapsed CD Time: %3\nElapsed Track Time: %4")
+                    .arg(obj["cd"].toInt())
+                    .arg(obj["track"].toInt())
+                    .arg(obj["cd_time"].toString())
+                    .arg(obj["track_time"].toString());
+        } else {
+            statusText = QString("Recording is currently not active.");
+        }
+
+        statusLabel->setText(statusText);
         updateBackgroundColor(isRecording ? QColor("#228B22") : Qt::gray);
     }
 
 private:
     void updateBackgroundColor(const QColor &bgColor) {
-    this->setStyleSheet(QString(
-        "background-color: %1;"
-        "color: %2;"
-    ).arg(bgColor.name())
-     .arg(isColorDark(bgColor) ? "white" : "black"));
-}
+        this->setStyleSheet(QString(
+            "background-color: %1;"
+            "color: %2;"
+        ).arg(bgColor.name())
+         .arg(isColorDark(bgColor) ? "white" : "black"));
+    }
+
+    bool isColorDark(const QColor &color) {
+        // Perceived brightness formula
+        int brightness = (color.red() * 299 + color.green() * 587 + color.blue() * 114) / 1000;
+        return brightness < 128;
+    }
+
+    void updateRetryingLabel() {
+        retryDotCount = (retryDotCount % 3) + 1;
+        QString dots = QString(".").repeated(retryDotCount);
+        statusLabel->setText(QString("Disconnected from websocket\nRetrying%1").arg(dots));
+    }
 
-bool isColorDark(const QColor &color) {
-    // Perceived brightness formula
-    int brightness = (color.red() * 299 + color.green() * 587 + color.blue() * 114) / 1000;
-    return brightness < 128;
-}
 
 
 private:
     QLabel *statusLabel;
     QWebSocket *socket;
+
+    QTimer *reconnectTimer;
+    QTimer *retryAnimationTimer;
+    int retryDotCount;
 };
 
 static void *create_cd_status_dock(obs_source_t *) {