1
1
#include < pthread.h>
2
2
#include < stdlib.h>
3
3
#include < stdint.h>
4
+ #include < iostream>
5
+ #include < filesystem>
6
+ #include < regex>
4
7
5
8
#include " spdlog/spdlog.h"
6
9
@@ -12,7 +15,10 @@ extern "C" {
12
15
#include " osd.h"
13
16
}
14
17
18
+ namespace fs = std::filesystem;
19
+
15
20
int dvr_enabled = 0 ;
21
+ const int SEQUENCE_PADDING = 4 ; // Configurable padding for sequence numbers
16
22
17
23
int write_callback (int64_t offset, const void *buffer, size_t size, void *token){
18
24
FILE *f = (FILE*)token;
@@ -23,6 +29,7 @@ int write_callback(int64_t offset, const void *buffer, size_t size, void *token)
23
29
Dvr::Dvr (dvr_thread_params params) {
24
30
filename_template = params.filename_template ;
25
31
mp4_fragmentation_mode = params.mp4_fragmentation_mode ;
32
+ dvr_filenames_with_sequence = params.dvr_filenames_with_sequence ;
26
33
video_framerate = params.video_framerate ;
27
34
video_frm_width = params.video_p .video_frm_width ;
28
35
video_frm_height = params.video_p .video_frm_height ;
@@ -176,11 +183,62 @@ void Dvr::loop() {
176
183
177
184
int Dvr::start () {
178
185
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);
184
242
return -1 ;
185
243
}
186
244
osd_vars.enable_recording = 1 ;
0 commit comments