diff --git a/main2.c b/main2.c index 5b49c7e..24ce037 100644 --- a/main2.c +++ b/main2.c @@ -10,6 +10,7 @@ #include #include #include +#include #endif #include @@ -123,13 +124,14 @@ static void transmit_all(const char *buf, size_t sz) { } } +#define WS_TXT 1 #define WS_BIN 2 #define WS_CLOSE 8 #define WS_FIN 128 #define WS_HEADER_MAX 10 -static int ws_header(size_t sz, uint8_t hdr[static WS_HEADER_MAX]) { +static int ws_header(size_t sz, bool binary, uint8_t hdr[static WS_HEADER_MAX]) { int i; - hdr[0] = WS_BIN | WS_FIN; + hdr[0] = (binary ? WS_BIN : WS_TXT) | WS_FIN; if(sz < 126) { hdr[1] = sz; i = 2; @@ -154,27 +156,53 @@ static int ws_header(size_t sz, uint8_t hdr[static WS_HEADER_MAX]) { return i; } -static void ws_send(Client *cli, const uint8_t *buf, size_t sz) { +static void ws_send(Client *cli, bool binary, const uint8_t *buf, size_t sz) { if(sz == 0) return; uint8_t wshdr[WS_HEADER_MAX]; - int wshdrsz = ws_header(sz, wshdr); + int wshdrsz = ws_header(sz, binary, wshdr); transmit(cli, wshdr, wshdrsz); transmit(cli, buf, sz); } -static void ws_broadcast(const uint8_t *buf, size_t sz) { +static void ws_broadcast(bool binary, const uint8_t *buf, size_t sz) { if(sz == 0) return; uint8_t wshdr[WS_HEADER_MAX]; - int wshdrsz = ws_header(sz, wshdr); + int wshdrsz = ws_header(sz, binary, wshdr); transmit_all(wshdr, wshdrsz); transmit_all(buf, sz); } +static bool should_send_status_update() { + static uint64_t lastSec = 0; + + struct timespec tv; + clock_gettime(CLOCK_MONOTONIC, &tv); + + if(tv.tv_sec - lastSec < 10) { + return false; + } + + lastSec = tv.tv_sec; + + return true; +} + +static void send_status_update() { + char buf[512] = {}; + snprintf(buf, sizeof(buf) - 1, "{\"status\": {\"viewer_count\": %lu}}", clientsSz); + + ws_broadcast(false, buf, strlen(buf)); +} + static void stream_step(const uint8_t *newbuf, size_t newsz) { + if(should_send_status_update()) { + send_status_update(); + } + if(Stream.state == LOADING_HEADER) { Stream.mkvHeader = realloc(Stream.mkvHeader, Stream.mkvHeaderSz + newsz); memcpy(Stream.mkvHeader + Stream.mkvHeaderSz, newbuf, newsz); @@ -182,8 +210,8 @@ static void stream_step(const uint8_t *newbuf, size_t newsz) { uint8_t *clusterEl = memmem(Stream.mkvHeader, Stream.mkvHeaderSz, "\x1F\x43\xB6\x75", 4); if(clusterEl) { - ws_broadcast(Stream.mkvHeader, clusterEl - Stream.mkvHeader); - ws_broadcast(clusterEl, Stream.mkvHeader + Stream.mkvHeaderSz - clusterEl); + ws_broadcast(true, Stream.mkvHeader, clusterEl - Stream.mkvHeader); + ws_broadcast(true, clusterEl, Stream.mkvHeader + Stream.mkvHeaderSz - clusterEl); Stream.mkvHeaderSz = clusterEl - Stream.mkvHeader; Stream.state = STREAMING; @@ -210,15 +238,17 @@ static void stream_step(const uint8_t *newbuf, size_t newsz) { } if(Stream.state == LOADING_HEADER) { + puts("New header"); + if(i > 4) { - ws_broadcast(newbuf, i - 4); + ws_broadcast(true, newbuf, i - 4); } Stream.mkvHeader = realloc(Stream.mkvHeader, Stream.mkvHeaderSz = 4 + (newsz - i)); memcpy(Stream.mkvHeader, "\x1A\x45\xDF\xA3", 4); memcpy(Stream.mkvHeader + 4, newbuf + i, newsz - i); } else { - ws_broadcast(newbuf, newsz); + ws_broadcast(true, newbuf, newsz); } } } @@ -302,7 +332,7 @@ static int handle(Client *cli) { if(Stream.state == STREAMING && Stream.mkvHeader) { printf("Sending header\n"); - ws_send(cli, Stream.mkvHeader, Stream.mkvHeaderSz); + ws_send(cli, true, Stream.mkvHeader, Stream.mkvHeaderSz); } }