Skip to content
This repository was archived by the owner on Jan 16, 2026. It is now read-only.

Commit 9c8c57a

Browse files
committed
Add audio processing features: implement silence removal and audio length calculation
1 parent c25dd62 commit 9c8c57a

4 files changed

Lines changed: 51 additions & 3 deletions

File tree

audio_file.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from pydub import AudioSegment
2+
3+
4+
def get_audio_length(file_path: str) -> float:
5+
file_format = file_path.split(".")[-1]
6+
audio = AudioSegment.from_file(file_path, format=file_format)
7+
duration_minutes = len(audio) / (1000.0 * 60.0) # milliseconds to minutes
8+
return duration_minutes

main.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
from tornado.ioloop import IOLoop
1919
from tornado.web import Application, RequestHandler
2020

21+
import audio_file
2122
import filebrowser_uploader
2223
import firebase_android_notification
2324
import firebase_web_notification
25+
import remove_silence
2426
import send_email
2527
import zip_file
2628

@@ -168,8 +170,10 @@ def convert_delta_time(self, duration: timedelta) -> str:
168170
)
169171

170172
def process_file(self):
173+
self.backup_stream(self.recording_file_name)
171174
app_log.info(f"Processing {self.recording_file_name}")
172-
self.audio_file_length = self.get_recording_time_minutes()
175+
remove_silence.remove_silence_everywhere(self.recording_file_path)
176+
self.audio_file_length = audio_file.get_audio_length(self.recording_file_path)
173177

174178
time_delta = timedelta(minutes=self.audio_file_length)
175179
final_delta_time = self.convert_delta_time(time_delta)
@@ -241,9 +245,16 @@ def delayed_notification():
241245
)
242246
app_log.info(f"Notification sent for {self.host}")
243247

248+
email_body = f"""
249+
URL: {self.url}<br>
250+
Title: {self.title}<br>
251+
Description: {self.description}<br>
252+
Host: {self.host}<br>
253+
Date: {self.starting_time.strftime('%B %d, %A %I:%M %p')}<br>
254+
"""
244255
send_email.send(
245256
f"{self.title} just started a stream!",
246-
f"{self.description}<br>{self.url}",
257+
email_body,
247258
)
248259

249260
if "test" in self.title.lower():
@@ -318,7 +329,7 @@ def run(self):
318329
is_recording = source.get("genre", "various") == "RECORDING"
319330

320331
if (
321-
host not in self.active_streams and "test" not in host.lower() and "test" not in description.lower() and not is_private
332+
host not in self.active_streams
322333
# and not is_recording # It is being recorded by HBNI Audio
323334
):
324335
stream = Stream(

remove_silence.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from pydub import AudioSegment, silence
2+
3+
4+
def remove_silence_everywhere(file_path: str, silence_thresh: float = -40.0, min_silence_len: int = 1000, keep_silence_ms: int = 500):
5+
print(f"Removing silence inside {file_path}")
6+
file_format = file_path.split(".")[-1]
7+
sound = AudioSegment.from_file(file_path, format=file_format)
8+
9+
chunks = silence.split_on_silence(
10+
sound,
11+
min_silence_len=min_silence_len, # only cut silences longer than 500ms
12+
silence_thresh=silence_thresh, # treat anything below -35dBFS as silence
13+
keep_silence=keep_silence_ms # leave 200ms of silence at each cut
14+
)
15+
16+
if not chunks:
17+
print("No sound detected above silence threshold. Skipping.")
18+
return
19+
20+
combined = AudioSegment.empty()
21+
for chunk in chunks:
22+
combined += chunk
23+
24+
combined.export(file_path, format=file_format)
25+
print(f"Silence removed inside and saved to {file_path}")
26+
27+
if __name__ == "__main__":
28+
file_path = r"CURRENTLY_RECORDING\Test - Pineland - April 25 Friday 2025 09_14 PM - 0m 19s.mp3"
29+
remove_silence_everywhere(file_path)

requirements.txt

-989 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)