From b0274b8254dfab5bfbea855d5127e75ba59e874e Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Sun, 22 Sep 2024 17:03:06 -0400 Subject: [PATCH] Have the server back off when ffmpeg fails repeatedly. --- config.json | 2 +- main.cpp | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/config.json b/config.json index c6da316..941059f 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,5 @@ { - "listen_at": "rtmp://192.168.254.146/", + "listen_at": "rtmp://192.168.254.147/", "bitrate": "7M", "send_to": "https://127.0.0.1:5001/" } diff --git a/main.cpp b/main.cpp index abfc11b..5a37742 100644 --- a/main.cpp +++ b/main.cpp @@ -1,13 +1,17 @@ #define FSM_DEBUG 1 #include +#include #include #include +#include +#include #include "dbc.hpp" #include "fsm.hpp" #define BUF_MAX 1024 * 10 using namespace fmt; using namespace nlohmann; +using namespace std::chrono_literals; struct Config { json json_config; @@ -30,7 +34,7 @@ struct Config { }; FILE *run_ffmpeg(Config &config) { - string ffmpeg_cmd = format("ffmpeg -listen 1 -i {} -bufsize 3000k -maxrate {} -flags +global_header -c:v libx264 -preset veryfast -tune zerolatency -g:v 60 -vb {} -c:a copy -f flv {}", + string ffmpeg_cmd = format("ffmpeg -listen 1 -i {} -bufsize 3000k -maxrate {} -flags +global_header -c:v libx264 -preset veryfast -tune zerolatency -g:v 60 -vb {} -c:a copy -f flv {} 2> output.log", config.listen_at, config.bitrate, config.bitrate, @@ -38,7 +42,7 @@ FILE *run_ffmpeg(Config &config) { println("RUNNING: {}", ffmpeg_cmd); - return popen(ffmpeg_cmd.c_str(), "r"); + return popen(ffmpeg_cmd.c_str(), "re"); } @@ -55,13 +59,14 @@ class Server : DeadSimpleFSM { FILE *handle = nullptr; char buffer[BUF_MAX]; char *res = nullptr; + std::chrono::milliseconds wait_time = 200ms; public: Server(Config &config) : config(config) {}; bool stopped() { - return in_state(ServerState::STOP) || in_state(ServerState::ERROR); + return in_state(ServerState::STOP); } void event(ServerEvent ev) { @@ -76,8 +81,10 @@ public: void START(ServerEvent ev) { handle = run_ffmpeg(config); if(handle == nullptr) { + dbc::log("ERROR when launching ffmpeg"); state(ServerState::ERROR); } else { + wait_time = 200ms; state(ServerState::READING); } } @@ -86,6 +93,7 @@ public: res = fgets(buffer, BUF_MAX, handle); if(res == nullptr) { + dbc::log("STOP shutting down..."); state(ServerState::STOP); } else { state(ServerState::READING); @@ -95,6 +103,7 @@ public: void STOP(ServerEvent ev) { int rc = pclose(handle); if(rc != 0) { + dbc::log("ERROR when calling pclose on ffmpeg"); state(ServerState::ERROR); } else { state(ServerState::STOP); @@ -102,12 +111,18 @@ public: } void ERROR(ServerEvent ev) { - state(ServerState::ERROR); + println("Error in server, waiting {}...", wait_time); + wait_time *= 2; + std::this_thread::sleep_for(wait_time); + dbc::log("Attempting to run it again..."); + state(ServerState::START); } }; -int main() { - Config config("config.json"); +int main(int argc, char *argv[]) { + dbc::check(argc == 2, "USAGE: distributary config.json"); + println("Using config {}", argv[1]); + Config config(argv[1]); Server server(config); while(!server.stopped()) {