This commit is contained in:
Stéphane Lepin 2016-11-27 17:32:37 +01:00
parent 03bf41b250
commit 5abcd18ba0
2 changed files with 39 additions and 27 deletions

View File

@ -57,12 +57,13 @@ A request to stop streaming has been issued.
Recording stopped successfully. Recording stopped successfully.
#### "StreamStatus" #### "StreamStatus"
Sent each second with the following information : Sent every 2 seconds with the following information :
- **streaming** (bool) : Current Streaming state. - **streaming** (bool) : Current Streaming state.
- **recording** (bool) : Current Recording state. - **recording** (bool) : Current Recording state.
- **preview-only** (bool) : Always false. - **preview-only** (bool) : Always false.
- **bytes-per-sec** (integer) : Amount of data (in bytes) transmitted by the stream encoder. - **bytes-per-sec** (integer) : Amount of data per second (in bytes) transmitted by the stream encoder.
- **strain** (double) : i have no idea what this is - **kbits-per-sec** (integer) : "bytes-per-sec" converted to kilobits per second
- **strain** (double) : Percentage of dropped frames
- **total-stream-time** (integer) : Total time (in seconds) since the stream started. - **total-stream-time** (integer) : Total time (in seconds) since the stream started.
- **num-total-frames** (integer) : Total number of frames transmitted since the stream started. - **num-total-frames** (integer) : Total number of frames transmitted since the stream started.
- **num-dropped-frames** (integer) : Number of frames dropped by the encoder since the stream started. - **num-dropped-frames** (integer) : Number of frames dropped by the encoder since the stream started.

View File

@ -24,7 +24,7 @@ WSEvents::WSEvents(WSServer *server) {
QTimer *statusTimer = new QTimer(); QTimer *statusTimer = new QTimer();
connect(statusTimer, SIGNAL(timeout()), this, SLOT(StreamStatus())); connect(statusTimer, SIGNAL(timeout()), this, SLOT(StreamStatus()));
statusTimer->start(1000); statusTimer->start(2000); // equal to frontend's constant BITRATE_UPDATE_SECONDS
} }
WSEvents::~WSEvents() { WSEvents::~WSEvents() {
@ -167,49 +167,60 @@ void WSEvents::OnExit() {
} }
void WSEvents::StreamStatus() { void WSEvents::StreamStatus() {
bool streamingActive = obs_frontend_streaming_active(); bool streaming_active = obs_frontend_streaming_active();
bool recordingActive = obs_frontend_recording_active(); bool recording_active = obs_frontend_recording_active();
obs_output_t *streamOutput = obs_frontend_get_streaming_output(); obs_output_t *stream_output = obs_frontend_get_streaming_output();
if (!streamOutput || !streamingActive || !recordingActive) { if (!stream_output || !streaming_active) {
if (stream_output) {
obs_output_release(stream_output);
}
return; return;
} }
uint64_t bytesSent = obs_output_get_total_bytes(streamOutput); uint64_t bytes_sent = obs_output_get_total_bytes(stream_output);
uint64_t bytesSentTime = os_gettime_ns(); uint64_t bytes_sent_time = os_gettime_ns();
if (bytesSent < _lastBytesSent) { if (bytes_sent < _lastBytesSent) {
bytesSent = 0; bytes_sent = 0;
} }
if (bytesSent == 0) { if (bytes_sent == 0) {
_lastBytesSent = 0; _lastBytesSent = 0;
} }
uint64_t bitsBetween = (bytesSent - _lastBytesSent) * 8; uint64_t bytes_between = bytes_sent - _lastBytesSent;
double timePassed = double(bytesSentTime - _lastBytesSentTime) / 1000000000.0; double time_passed = double(bytes_sent_time - _lastBytesSentTime) / 1000000000.0;
uint64_t bitsPerSec = bitsBetween / timePassed; uint64_t bytes_per_sec = bytes_between / time_passed;
uint64_t bytesPerSec = bitsPerSec / 8;
_lastBytesSent = bytesSent; _lastBytesSent = bytes_sent;
_lastBytesSentTime = bytesSentTime; _lastBytesSentTime = bytes_sent_time;
uint64_t totalStreamTime = (os_gettime_ns() - _streamStartTime) / 1000000000; uint64_t totalStreamTime = (os_gettime_ns() - _streamStartTime) / 1000000000;
int total_frames = obs_output_get_total_frames(stream_output);
int dropped_frames = obs_output_get_frames_dropped(stream_output);
float strain = 0.0;
if (total_frames > 0) {
strain = (dropped_frames / total_frames) * 100.0;
}
obs_data_t *data = obs_data_create(); obs_data_t *data = obs_data_create();
obs_data_set_bool(data, "streaming", streamingActive); obs_data_set_bool(data, "streaming", streaming_active);
obs_data_set_bool(data, "recording", recordingActive); obs_data_set_bool(data, "recording", recording_active);
obs_data_set_bool(data, "preview-only", false); // Retrocompat with OBSRemote obs_data_set_int(data, "bytes-per-sec", bytes_per_sec);
obs_data_set_int(data, "bytes-per-sec", bytesPerSec); // BUG : Computation seems buggy obs_data_set_int(data, "kbits-per-sec", (bytes_per_sec * 8) / 1024);
obs_data_set_double(data, "strain", 0.0); // dafuq is strain
obs_data_set_int(data, "total-stream-time", totalStreamTime); obs_data_set_int(data, "total-stream-time", totalStreamTime);
obs_data_set_int(data, "num-total-frames", obs_output_get_total_frames(streamOutput)); obs_data_set_int(data, "num-total-frames", total_frames);
obs_data_set_int(data, "num-dropped-frames", obs_output_get_frames_dropped(streamOutput)); obs_data_set_int(data, "num-dropped-frames", dropped_frames);
obs_data_set_double(data, "fps", obs_get_active_fps()); obs_data_set_double(data, "fps", obs_get_active_fps());
obs_data_set_double(data, "strain", strain);
obs_data_set_bool(data, "preview-only", false); // Retrocompat with OBSRemote
broadcastUpdate("StreamStatus", data); broadcastUpdate("StreamStatus", data);
obs_data_release(data); obs_data_release(data);
obs_output_release(streamOutput); obs_output_release(stream_output);
} }