diff --git a/main.py b/main.py index c7a0d38..986a9dc 100644 --- a/main.py +++ b/main.py @@ -26,6 +26,18 @@ def playback_thread(file_path, state): stream = container.streams.audio[0] resampler = av.AudioResampler(format='s16', layout='stereo', rate=48000) + def build_graph(): + graph = av.filter.Graph() + src = graph.add_abuffer(template=stream) + loudnorm = graph.add("loudnorm", "I=-16:TP=-1.5:LRA=11") + sink = graph.add("abuffersink") + src.link_to(loudnorm) + loudnorm.link_to(sink) + graph.configure() + return graph + + graph = build_graph() + with open(fifo_path, 'wb') as fifo: iterator = container.decode(stream) while state.running: @@ -41,6 +53,7 @@ def playback_thread(file_path, state): with state.lock: state.seek_request = None iterator = container.decode(stream) + graph = build_graph() # Reset filter graph on seek continue if paused: @@ -57,17 +70,24 @@ def playback_thread(file_path, state): with state.lock: state.time_pos = float(frame.pts * stream.time_base) - resampled_frames = resampler.resample(frame) - for r_frame in resampled_frames: - arr = r_frame.to_ndarray() - - # Apply volume - if vol != 100.0: - multiplier = max(0.0, vol / 100.0) - arr = arr.astype(np.float32) * multiplier - arr = np.clip(arr, -32768, 32767).astype(np.int16) + graph.push(frame) + while True: + try: + filtered_frame = graph.pull() + except (av.AVError, BlockingIOError): + break - fifo.write(arr.tobytes()) + resampled_frames = resampler.resample(filtered_frame) + for r_frame in resampled_frames: + arr = r_frame.to_ndarray() + + # Apply volume + if vol != 100.0: + multiplier = max(0.0, vol / 100.0) + arr = arr.astype(np.float32) * multiplier + arr = np.clip(arr, -32768, 32767).astype(np.int16) + + fifo.write(arr.tobytes()) def handle_ipc_client(conn, state): buffer = ""