Skip to content

Commit 4a45f82

Browse files
committed
Continuous recordings and segment duration setting
1 parent ab876b3 commit 4a45f82

File tree

8 files changed

+91
-6
lines changed

8 files changed

+91
-6
lines changed

divinus.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ rtsp:
3737

3838
record:
3939
enable: false
40+
continuous: false
4041
path: /mnt/sdcard/recordings
4142
#filename: "output.mp4"
43+
#segment_duration: 0
4244
#segment_size: 52428800
4345

4446
stream:

doc/endpoints.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,36 @@ Configures text or image overlays by their ID (0-9 at the moment).
242242
}
243243
```
244244

245+
### Recordings
246+
247+
#### `/api/record`
248+
249+
Manages video recording operations.
250+
251+
| Method | Parameters | Description |
252+
|--------|--------------------|----------------------------------------------------|
253+
| GET | `continuous` | Adjusts the operation mode to be uninterruptible |
254+
| GET | `path` | Specifies the location of the resulting files |
255+
| GET | `filename` | Adjusts the output name (extension needed) |
256+
| GET | `segment_duration` | Sets the maximum segment duration (seconds) |
257+
| GET | `segment_size` | Sets the maximum segment size (bytes) |
258+
| GET | `start` | Starts a new recording session |
259+
| GET | `stop` | Stops the current recording session |
260+
261+
**Response**
262+
```json
263+
{
264+
"recording": true,
265+
"start_time": "2025-05-08T14:30:00Z",
266+
"continuous": true,
267+
"path": "/mnt/sdcard/recordings",
268+
"filename": "Entrance.mp4",
269+
"segment_duration": 0,
270+
"segment_size": 10485760
271+
}
272+
```
273+
274+
245275
## Content Streaming
246276

247277
### `/image.jpg`

res/index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,13 @@ <h2 class="unl">Media</h2>
221221
<option value="true">ON</option>
222222
</select></td>
223223
</tr>
224+
<tr>
225+
<td><label for="record_continuous">Continuous</label></td>
226+
<td><select id="record_continuous">
227+
<option value="false">OFF</option>
228+
<option value="true">ON</option>
229+
</select></td>
230+
</tr>
224231
<tr>
225232
<td><label for="record_path">Path</label></td>
226233
<td><input type="text" id="record_path"></td>
@@ -229,6 +236,10 @@ <h2 class="unl">Media</h2>
229236
<td><label for="record_filename">Filename</label></td>
230237
<td><input type="text" id="record_filename"></td>
231238
</tr>
239+
<tr>
240+
<td><label for="record_segment_duration">Segment duration&nbsp;(s)</label></td>
241+
<td><input type="number" id="record_segment_duration"></td>
242+
</tr>
232243
<tr>
233244
<td><label for="record_segment_size">Segment size&nbsp;(bytes)</label></td>
234245
<td><input type="number" id="record_segment_size"></td>

src/app_config.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,10 @@ int save_app_config(void) {
9696

9797
fprintf(file, "record:\n");
9898
fprintf(file, " enable: %s\n", app_config.record_enable ? "true" : "false");
99+
fprintf(file, " continuous: %s\n", app_config.record_continuous ? "true" : "false");
99100
fprintf(file, " path: %s\n", app_config.record_path);
100101
fprintf(file, " filename: %s\n", app_config.record_filename);
102+
fprintf(file, " segment_duration: %d\n", app_config.record_segment_duration);
101103
fprintf(file, " segment_size: %d\n", app_config.record_segment_size);
102104

103105
fprintf(file, "stream:\n");
@@ -205,8 +207,10 @@ enum ConfigError parse_app_config(void) {
205207
app_config.rtsp_auth_pass[0] = '\0';
206208

207209
app_config.record_enable = false;
210+
app_config.record_continuous = false;
208211
app_config.record_filename[0] = '\0';
209212
strcpy(app_config.record_path, "/mnt/sdcard/recordings");
213+
app_config.record_segment_duration = 0;
210214
app_config.record_segment_size = 0;
211215

212216
app_config.stream_enable = false;
@@ -380,10 +384,13 @@ enum ConfigError parse_app_config(void) {
380384
}
381385

382386
parse_bool(&ini, "record", "enable", &app_config.record_enable);
387+
parse_bool(&ini, "record", "continuous", &app_config.record_continuous);
383388
parse_param_value(
384389
&ini, "record", "path", app_config.record_path);
385390
parse_param_value(
386391
&ini, "record", "filename", app_config.record_filename);
392+
parse_int(&ini, "record", "segment_duration", 0, INT_MAX,
393+
&app_config.record_segment_duration);
387394
parse_int(&ini, "record", "segment_size", 0, INT_MAX,
388395
&app_config.record_segment_size);
389396

src/app_config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ struct AppConfig {
6161

6262
// [record]
6363
bool record_enable;
64+
bool record_continuous;
6465
char record_filename[128];
6566
char record_path[128];
67+
int record_segment_duration;
6668
int record_segment_size;
6769

6870
// [stream]

src/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,17 @@ int main(int argc, char *argv[]) {
9292
if (app_config.osd_enable)
9393
start_region_handler();
9494

95+
if (app_config.record_enable && app_config.record_continuous)
96+
record_start();
97+
9598
while (keepRunning) {
9699
watchdog_reset();
97100
sleep(1);
98101
}
99102

103+
if (app_config.record_enable && app_config.record_continuous)
104+
record_stop();
105+
100106
if (app_config.rtsp_enable) {
101107
rtsp_finish(rtspHandle);
102108
HAL_INFO("rtsp", "Server has closed!\n");

src/record.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,25 @@ time_t recordStartTime = 0;
77
char recordOn = 0, recordPath[256];
88

99
static void record_check_segment_size(int upcoming) {
10+
if (app_config.record_segment_size <= 0) return;
1011
if (recordSize + upcoming >= app_config.record_segment_size) {
1112
record_stop();
1213
record_start();
1314
}
1415
}
1516

17+
static void record_check_segment_duration() {
18+
if (app_config.record_segment_duration <= 0) return;
19+
20+
time_t currentTime = time(NULL);
21+
if (currentTime == (time_t)-1 || recordStartTime == (time_t)-1) return;
22+
23+
if (currentTime - recordStartTime >= app_config.record_segment_duration) {
24+
record_stop();
25+
record_start();
26+
}
27+
}
28+
1629
void record_start(void) {
1730
if (recordOn) return;
1831

@@ -113,8 +126,7 @@ void send_mp4_to_record(hal_vidstream *stream, char isH265) {
113126
default_sample_size;
114127
}
115128

116-
err = mp4_set_state(&recordState);
117-
chk_err_continue
129+
err = mp4_set_state(&recordState); chk_err_continue
118130
{
119131
struct BitBuf moof_buf;
120132
err = mp4_get_moof(&moof_buf); chk_err_continue
@@ -131,4 +143,6 @@ void send_mp4_to_record(hal_vidstream *stream, char isH265) {
131143

132144
}
133145
}
146+
147+
record_check_segment_duration();
134148
}

src/server.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,17 +1278,29 @@ void respond_request(http_request_t *req) {
12781278
else if (EQUALS_CASE(value, "false") || EQUALS(value, "0"))
12791279
app_config.record_enable = 0;
12801280
}
1281+
else if (EQUALS(key, "continuous")) {
1282+
if (EQUALS_CASE(value, "true") || EQUALS(value, "1"))
1283+
app_config.record_continuous = 1;
1284+
else if (EQUALS_CASE(value, "false") || EQUALS(value, "0"))
1285+
app_config.record_continuous = 0;
1286+
}
12811287
else if (EQUALS(key, "path"))
12821288
strncpy(app_config.record_path, value, sizeof(app_config.record_path) - 1);
12831289
else if (EQUALS(key, "filename"))
12841290
strncpy(app_config.record_filename, value, sizeof(app_config.record_filename) - 1);
1291+
else if (EQUALS(key, "segment_duration")) {
1292+
short result = strtol(value, &remain, 10);
1293+
if (remain != value)
1294+
app_config.record_segment_duration = result;
1295+
}
12851296
else if (EQUALS(key, "segment_size")) {
12861297
short result = strtol(value, &remain, 10);
12871298
if (remain != value)
12881299
app_config.record_segment_size = result;
12891300
}
12901301

12911302
if (!app_config.record_enable) continue;
1303+
if (app_config.record_continuous) continue;
12921304
if (EQUALS(key, "start"))
12931305
record_start();
12941306
else if (EQUALS(key, "stop"))
@@ -1304,10 +1316,11 @@ void respond_request(http_request_t *req) {
13041316
"Content-Type: application/json;charset=UTF-8\r\n"
13051317
"Connection: close\r\n"
13061318
"\r\n"
1307-
"{\"recording\":%s,\"start_time\":\"%s\",\"path\":\"%s\","
1308-
"\"filename\":\"%s\",\"segment_size\":%d}",
1309-
recordOn ? "true" : "false", recordStartTime,
1310-
app_config.record_path, app_config.record_filename, app_config.record_segment_size);
1319+
"{\"recording\":%s,\"start_time\":\"%s\",\"continuous\":\"%s\",\"path\":\"%s\","
1320+
"\"filename\":\"%s\",\"segment_duration\":%d,\"segment_size\":%d}",
1321+
recordOn ? "true" : "false", recordStartTime, app_config.record_continuous ? "true" : "false",
1322+
app_config.record_path, app_config.record_filename,
1323+
app_config.record_segment_duration, app_config.record_segment_size);
13111324
send_and_close(req->clntFd, response, respLen);
13121325
return;
13131326
}

0 commit comments

Comments
 (0)