fixed audiwriter service, but need to adjust recording duration properly, to convert from miliseconds to seconds

This commit is contained in:
tdv
2025-12-08 20:00:44 +02:00
parent fe4affd942
commit d49482ea4c

View File

@@ -75,11 +75,11 @@ namespace snoop
if (this->m_writingThread.joinable()) if (this->m_writingThread.joinable())
{ {
this->m_writingThread.join(); this->m_writingThread.join();
} }
if (this->m_uploadThread.joinable()) if (this->m_uploadThread.joinable())
{ {
this->m_uploadThread.join(); this->m_uploadThread.join();
} }
} }
// -------- Public control API (called from DeviceControlService handlers) -------- // -------- Public control API (called from DeviceControlService handlers) --------
@@ -135,9 +135,11 @@ namespace snoop
spdlog::info("StopRecordingNow ignored: not recording"); spdlog::info("StopRecordingNow ignored: not recording");
return; return;
} }
auto stoppedAtMs = NowMs();
// Force-close current segment right away, enqueue, and disable recording. // Force-close current segment right away, enqueue, and disable recording.
this->m_oggWriter->StopWriting(); this->m_oggWriter->StopWriting();
this->MoveToUploadQueue(this->m_currentRecordFilePath); this->MoveToUploadQueue(this->m_currentRecordFilePath,this->m_currentRecordStartedAt,stoppedAtMs);
m_recordingEnabled = false; m_recordingEnabled = false;
m_stopAfterCurrentSegment = false; m_stopAfterCurrentSegment = false;
spdlog::info("Recording stopped immediately (deep sleep)"); spdlog::info("Recording stopped immediately (deep sleep)");
@@ -264,7 +266,8 @@ namespace snoop
void WritingThread() void WritingThread()
{ {
// recording starts ONLY when StartRecording() is called constexpr unsigned long long DEFAULT_SEGMENT_MS = 30'000; // 30 seconds
while (!m_isIntermission) while (!m_isIntermission)
{ {
if (!m_recordingEnabled.load()) if (!m_recordingEnabled.load())
@@ -273,32 +276,52 @@ namespace snoop
continue; continue;
} }
// Start a fresh segment // --- Get segment duration from config ---
auto now = std::chrono::system_clock::now(); unsigned long long segDurationMs = this->m_configService->GetRecordingDuration();
if (segDurationMs < 1000) // anything < 1s is basically useless here
{
spdlog::warn("RecordingDuration={} ms is too small, using default {} ms",
segDurationMs, DEFAULT_SEGMENT_MS);
segDurationMs = DEFAULT_SEGMENT_MS;
}
spdlog::info("Starting new segment with target duration={} ms", segDurationMs);
// --- Mark start times (wall + monotonic) ---
auto wallStart = std::chrono::system_clock::now();
this->m_currentRecordStartedAt = this->m_currentRecordStartedAt =
std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count(); std::chrono::duration_cast<std::chrono::milliseconds>(wallStart.time_since_epoch()).count();
this->m_currentRecordFilePath = this->m_destinationDirectoryPath + std::to_string(this->m_currentRecordStartedAt);
this->m_currentRecordFilePath =
this->m_destinationDirectoryPath + std::to_string(this->m_currentRecordStartedAt);
this->m_oggWriter->StartWriting(this->m_currentRecordFilePath); this->m_oggWriter->StartWriting(this->m_currentRecordFilePath);
spdlog::info("Recording segment started: {}", this->m_currentRecordFilePath); spdlog::info("Recording segment started: {}", this->m_currentRecordFilePath);
// Write until duration elapses auto monoStart = std::chrono::steady_clock::now();
const auto segDurationMs = this->m_configService->GetRecordingDuration(); const auto targetDuration = std::chrono::milliseconds(segDurationMs);
// --- Wait until segment duration elapses ---
while (!m_isIntermission && m_recordingEnabled.load()) while (!m_isIntermission && m_recordingEnabled.load())
{ {
now = std::chrono::system_clock::now(); auto elapsed = std::chrono::steady_clock::now() - monoStart;
auto currentRecordDuration = if (elapsed >= targetDuration)
std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() - this->m_currentRecordStartedAt;
if (currentRecordDuration >= segDurationMs)
{
break; break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::this_thread::sleep_for(std::chrono::milliseconds(50));
} }
// Close current segment and enqueue auto wallStop = std::chrono::system_clock::now();
auto stoppedAtMs =
std::chrono::duration_cast<std::chrono::milliseconds>(wallStop.time_since_epoch()).count();
// --- Close and enqueue ---
this->m_oggWriter->StopWriting(); this->m_oggWriter->StopWriting();
this->MoveToUploadQueue(this->m_currentRecordFilePath); this->MoveToUploadQueue(this->m_currentRecordFilePath,
spdlog::info("Recording segment finished: {}", this->m_currentRecordFilePath); this->m_currentRecordStartedAt,
stoppedAtMs);
spdlog::info("Recording segment finished: {} ({} ms)",
this->m_currentRecordFilePath,
stoppedAtMs - this->m_currentRecordStartedAt);
// If graceful stop requested, stop after finishing this segment // If graceful stop requested, stop after finishing this segment
if (m_stopAfterCurrentSegment.load()) if (m_stopAfterCurrentSegment.load())
@@ -309,28 +332,58 @@ namespace snoop
} }
} }
// If exiting service while in a middle of a segment, ensure clean close // Clean shutdown if we exit while still recording
if (m_recordingEnabled.load()) if (m_recordingEnabled.load())
{ {
auto wallStop = std::chrono::system_clock::now();
auto stoppedAtMs =
std::chrono::duration_cast<std::chrono::milliseconds>(wallStop.time_since_epoch()).count();
this->m_oggWriter->StopWriting(); this->m_oggWriter->StopWriting();
this->MoveToUploadQueue(this->m_currentRecordFilePath); this->MoveToUploadQueue(this->m_currentRecordFilePath,
this->m_currentRecordStartedAt,
stoppedAtMs);
m_recordingEnabled = false; m_recordingEnabled = false;
} }
} }
// Helper: ms since epoch
static unsigned long long NowMs()
{
auto now = std::chrono::system_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
}
void MoveToUploadQueue(const std::string &filePath) void MoveToUploadQueue(const std::string &filePath, unsigned long long startedAt, unsigned long long stoppedAt)
{ {
spdlog::info("MoveToUploadQueue( {} )", filePath); spdlog::info("MoveToUploadQueue( {} )", filePath);
std::lock_guard lock(this->m_fetchFilePathsMutex); std::lock_guard lock(this->m_fetchFilePathsMutex);
auto now = std::chrono::system_clock::now();
auto recordStoppedAt = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
if (std::filesystem::exists(filePath)) if (std::filesystem::exists(filePath))
{ {
auto fileName = std::filesystem::path(filePath).filename().string() + "-" + std::to_string(recordStoppedAt); auto fileName = std::to_string(startedAt) + "-" + std::to_string(stoppedAt);
std::filesystem::rename(filePath, m_queueDirectoryPath + fileName); std::filesystem::rename(filePath, m_queueDirectoryPath + fileName);
} }
} }
// Legacy helper for startup recovery
void MoveToUploadQueue(const std::string &filePath)
{
const auto stoppedAt = NowMs();
unsigned long long startedAt = 0;
auto base = std::filesystem::path(filePath).filename().string();
try
{
startedAt = std::stoull(base);
}
catch (...)
{
// if filename is not pure number, fall back to stoppedAt
startedAt = stoppedAt;
}
MoveToUploadQueue(filePath, startedAt, stoppedAt);
}
void UploadThread() void UploadThread()
{ {
const auto baseUrl = this->m_configService->GetBaseUrl(); const auto baseUrl = this->m_configService->GetBaseUrl();
@@ -341,7 +394,7 @@ namespace snoop
if (!std::filesystem::exists(ca)) if (!std::filesystem::exists(ca))
{ {
ca = "/etc/iot/keys/ca_chain.pem"; ca = "/etc/iot/keys/ca_chain.pem";
} }
const std::filesystem::path crt = "/etc/iot/keys/device.crt.pem"; const std::filesystem::path crt = "/etc/iot/keys/device.crt.pem";
while (!m_isIntermission) while (!m_isIntermission)
@@ -356,7 +409,7 @@ namespace snoop
if (entry.is_regular_file()) if (entry.is_regular_file())
{ {
files.push_back(entry.path()); files.push_back(entry.path());
} }
} }
} }
catch (const std::exception &e) catch (const std::exception &e)