From ad928d12794f15692ab97bb5e6bb001f1fd938b6 Mon Sep 17 00:00:00 2001 From: Sudo-Ivan Date: Sun, 4 Jan 2026 16:02:32 -0600 Subject: [PATCH] feat(voicemail): add silence file generation for missing recordings and improve logging for voicemail saving --- meshchatx/src/backend/voicemail_manager.py | 64 ++++++++++++++++++---- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/meshchatx/src/backend/voicemail_manager.py b/meshchatx/src/backend/voicemail_manager.py index 591b9d1..3b2e883 100644 --- a/meshchatx/src/backend/voicemail_manager.py +++ b/meshchatx/src/backend/voicemail_manager.py @@ -454,20 +454,30 @@ class VoicemailManager: filepath = os.path.join(self.recordings_dir, self.recording_filename) self._fix_recording(filepath) + # If recording is missing or empty (no frames), synthesize a small silence file + if (not os.path.exists(filepath)) or os.path.getsize(filepath) == 0: + self._write_silence_file(filepath, max(duration, 1)) + remote_name = self.get_name_for_identity_hash( self.recording_remote_identity.hash.hex(), ) - self.db.voicemails.add_voicemail( - remote_identity_hash=self.recording_remote_identity.hash.hex(), - remote_identity_name=remote_name, - filename=self.recording_filename, - duration_seconds=duration, - timestamp=self.recording_start_time, - ) - RNS.log( - f"Saved voicemail from {RNS.prettyhexrep(self.recording_remote_identity.hash)} ({duration}s)", - RNS.LOG_DEBUG, - ) + if os.path.exists(filepath) and os.path.getsize(filepath) > 0: + self.db.voicemails.add_voicemail( + remote_identity_hash=self.recording_remote_identity.hash.hex(), + remote_identity_name=remote_name, + filename=self.recording_filename, + duration_seconds=duration, + timestamp=self.recording_start_time, + ) + RNS.log( + f"Saved voicemail from {RNS.prettyhexrep(self.recording_remote_identity.hash)} ({duration}s)", + RNS.LOG_DEBUG, + ) + else: + RNS.log( + f"Voicemail: Recording missing for {self.recording_filename}, skipping DB insert", + RNS.LOG_ERROR, + ) if self.on_new_voicemail_callback: self.on_new_voicemail_callback( @@ -535,6 +545,38 @@ class VoicemailManager: if os.path.exists(temp_path): os.remove(temp_path) + def _write_silence_file(self, filepath, seconds=1): + """Creates a minimal OGG/Opus file with silence if recording is missing.""" + if not self.has_ffmpeg: + return False + + try: + cmd = [ + self.ffmpeg_path, + "-y", + "-f", + "lavfi", + "-i", + f"anullsrc=r=48000:cl=mono", + "-t", + str(max(1, seconds)), + "-c:a", + "libopus", + "-b:a", + "16k", + filepath, + ] + result = subprocess.run(cmd, capture_output=True, text=True, check=False) # noqa: S603 + if result.returncode == 0 and os.path.exists(filepath): + return True + RNS.log( + f"Voicemail: Failed to create silence file for {filepath}: {result.stderr}", + RNS.LOG_ERROR, + ) + except Exception as e: + RNS.log(f"Voicemail: Error creating silence file for {filepath}: {e}", RNS.LOG_ERROR) + return False + def start_greeting_recording(self): telephone = self.telephone_manager.telephone if not telephone: