Skip to content

Commit f676113

Browse files
Sequence number in dvr file names (#48)
1 parent e48aba9 commit f676113

File tree

3 files changed

+74
-5
lines changed

3 files changed

+74
-5
lines changed

src/dvr.cpp

+63-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include <pthread.h>
22
#include <stdlib.h>
33
#include <stdint.h>
4+
#include <iostream>
5+
#include <filesystem>
6+
#include <regex>
47

58
#include "spdlog/spdlog.h"
69

@@ -12,7 +15,10 @@ extern "C" {
1215
#include "osd.h"
1316
}
1417

18+
namespace fs = std::filesystem;
19+
1520
int dvr_enabled = 0;
21+
const int SEQUENCE_PADDING = 4; // Configurable padding for sequence numbers
1622

1723
int write_callback(int64_t offset, const void *buffer, size_t size, void *token){
1824
FILE *f = (FILE*)token;
@@ -23,6 +29,7 @@ int write_callback(int64_t offset, const void *buffer, size_t size, void *token)
2329
Dvr::Dvr(dvr_thread_params params) {
2430
filename_template = params.filename_template;
2531
mp4_fragmentation_mode = params.mp4_fragmentation_mode;
32+
dvr_filenames_with_sequence = params.dvr_filenames_with_sequence;
2633
video_framerate = params.video_framerate;
2734
video_frm_width = params.video_p.video_frm_width;
2835
video_frm_height = params.video_p.video_frm_height;
@@ -176,11 +183,62 @@ void Dvr::loop() {
176183

177184
int Dvr::start() {
178185
char *fname_tpl = filename_template;
179-
char fname[255];
180-
time_t t = time(NULL);
181-
strftime(fname, sizeof(fname), fname_tpl, localtime(&t));
182-
if ((dvr_file = fopen(fname,"w")) == NULL){
183-
spdlog::error("unable to open DVR file {}", fname);
186+
std::string rec_dir, filename_pattern;
187+
fs::path pathObj(filename_template);
188+
rec_dir = pathObj.parent_path().string();
189+
filename_pattern = pathObj.filename().string();
190+
std::string paddedNumber = "";
191+
192+
// Ensure the directory exists
193+
if (!fs::exists(rec_dir))
194+
{
195+
spdlog::error("Error: Directory does not exist: {}", rec_dir);
196+
return -1;
197+
}
198+
199+
if (dvr_filenames_with_sequence) {
200+
// Get the next file number
201+
std::regex pattern(R"(^(\d+)_.*)"); // Matches filenames that start with digits followed by '_'
202+
int maxNumber = -1;
203+
int nextFileNumber = 0;
204+
205+
for (const auto &entry : fs::directory_iterator(rec_dir)) {
206+
if (entry.is_regular_file())
207+
{
208+
std::string filename = entry.path().filename().string();
209+
std::smatch match;
210+
211+
if (std::regex_match(filename, match, pattern))
212+
{
213+
int number = std::stoi(match[1].str());
214+
maxNumber = std::max(maxNumber, number);
215+
}
216+
}
217+
}
218+
if (maxNumber == -1) {
219+
nextFileNumber = 0;
220+
} else {
221+
nextFileNumber = maxNumber + 1;
222+
}
223+
224+
// Zero-pad the number
225+
std::ostringstream stream;
226+
stream << std::setw(SEQUENCE_PADDING) << std::setfill('0') << nextFileNumber;
227+
paddedNumber = stream.str() + "_";
228+
}
229+
230+
// Generate timestamped filename
231+
std::time_t now = std::time(nullptr);
232+
std::tm *localTime = std::localtime(&now);
233+
234+
char formattedFilename[256];
235+
std::strftime(formattedFilename, sizeof(formattedFilename), filename_pattern.c_str(), localTime);
236+
237+
// Construct final filename
238+
std::string finalFilename = rec_dir + "/" + paddedNumber + formattedFilename;
239+
240+
if ((dvr_file = fopen(finalFilename.c_str(), "w")) == NULL) {
241+
spdlog::error("unable to open DVR file {}", finalFilename);
184242
return -1;
185243
}
186244
osd_vars.enable_recording = 1;

src/dvr.h

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct video_params {
2222
struct dvr_thread_params {
2323
char *filename_template;
2424
int mp4_fragmentation_mode = 0;
25+
bool dvr_filenames_with_sequence = false;
2526
int video_framerate = -1;
2627
video_params video_p;
2728
};
@@ -74,6 +75,7 @@ class Dvr {
7475
std::condition_variable cv;
7576
char *filename_template;
7677
int mp4_fragmentation_mode = 0;
78+
bool dvr_filenames_with_sequence = false;
7779
int video_framerate = -1;
7880
uint32_t video_frm_width;
7981
uint32_t video_frm_height;

src/main.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,8 @@ void printHelp() {
512512
" Supports placeholders %%Y - year, %%m - month, %%d - day,\n"
513513
" %%H - hour, %%M - minute, %%S - second. Ex: /media/DVR/%%Y-%%m-%%d_%%H-%%M-%%S.mp4\n"
514514
"\n"
515+
" --dvr-sequenced-files - Prepend a sequence number to the names of the dvr files\n"
516+
"\n"
515517
" --dvr-start - Start DVR immediately\n"
516518
"\n"
517519
" --dvr-framerate <rate> - Force the dvr framerate for smoother dvr, ex: 60\n"
@@ -539,6 +541,7 @@ int main(int argc, char **argv)
539541
char* dvr_template = NULL;
540542
int video_framerate = -1;
541543
int mp4_fragmentation_mode = 0;
544+
bool dvr_filenames_with_sequence = false;
542545
uint16_t listen_port = 5600;
543546
uint16_t mavlink_port = 14550;
544547
uint16_t mode_width = 0;
@@ -584,6 +587,11 @@ int main(int argc, char **argv)
584587
continue;
585588
}
586589

590+
__OnArgument("--dvr-sequenced-files") {
591+
dvr_filenames_with_sequence = true;
592+
continue;
593+
}
594+
587595
__OnArgument("--dvr-framerate") {
588596
video_framerate = atoi(__ArgValue);
589597
continue;
@@ -777,6 +785,7 @@ int main(int argc, char **argv)
777785
dvr_thread_params args;
778786
args.filename_template = dvr_template;
779787
args.mp4_fragmentation_mode = mp4_fragmentation_mode;
788+
args.dvr_filenames_with_sequence = dvr_filenames_with_sequence;
780789
args.video_framerate = video_framerate;
781790
args.video_p.video_frm_width = output_list->video_frm_width;
782791
args.video_p.video_frm_height = output_list->video_frm_height;

0 commit comments

Comments
 (0)