diff --git a/run_client.py b/run_client.py new file mode 100644 index 0000000..fde26e6 --- /dev/null +++ b/run_client.py @@ -0,0 +1,57 @@ +from pathlib import Path +import sys +from whisper_live.client import TranscriptionClient +import argparse + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--port', '-p', + type=int, + default=9090, + help="Websocket port to run the server on.") + parser.add_argument('--server', '-s', + type=str, + default='localhost', + help='hostname or ip address of server') + parser.add_argument('--files', '-f', + type=str, + nargs='+', + help='hostname or ip address of server') + parser.add_argument('--output_file', '-o', + type=str, + default='./output_recording.wav', + help='hostname or ip address of server') + args = parser.parse_args() + + # Validate audio files + valid_files = [] + for file_path in args.files: + path = Path(file_path) + if path.exists() and path.is_file(): + valid_files.append(str(path)) + else: + print(f"Warning: File not found: {file_path}") + + if not valid_files: + print("Error: No valid audio files found!") + sys.exit(1) + + print(f"Found {len(valid_files)} audio file(s) to stream:") + for file_path in valid_files: + print(f" - {file_path}") + + for f in valid_files: + client = TranscriptionClient( + args.server, + args.port, + lang="en", + translate=False, + model="large-v3", # also support hf_model => `Systran/faster-whisper-small` + use_vad=False, + save_output_recording=False, # Only used for microphone input, False by Default + output_recording_filename=args.output_file, # Only used for microphone input + max_clients=4, + max_connection_time=600, + mute_audio_playback=True, # Only used for file input, False by Default + ) + client(f) diff --git a/whisper_live/client.py b/whisper_live/client.py index 5bd51d6..197afb9 100644 --- a/whisper_live/client.py +++ b/whisper_live/client.py @@ -420,14 +420,18 @@ class TranscriptionTeeClient: # read audio and create pyaudio stream with wave.open(filename, "rb") as wavfile: - self.stream = self.p.open( - format=self.p.get_format_from_width(wavfile.getsampwidth()), - channels=wavfile.getnchannels(), - rate=wavfile.getframerate(), - input=True, - output=True, - frames_per_buffer=self.chunk, - ) + if self.mute_audio_playback: + self.stream = None + else: + self.stream = self.p.open( + format=self.p.get_format_from_width(wavfile.getsampwidth()), + channels=wavfile.getnchannels(), + rate=wavfile.getframerate(), + input=True, + output=True, + frames_per_buffer=self.chunk, + ) + chunk_duration = self.chunk / float(wavfile.getframerate()) try: while any(client.recording for client in self.clients): @@ -448,7 +452,8 @@ class TranscriptionTeeClient: client.wait_before_disconnect() self.multicast_packet(Client.END_OF_AUDIO.encode('utf-8'), True) self.write_all_clients_srt() - self.stream.close() + if self.stream: + self.stream.close() self.close_all_clients() except KeyboardInterrupt: diff --git a/whisper_live/server.py b/whisper_live/server.py index 25ce403..edb5d35 100644 --- a/whisper_live/server.py +++ b/whisper_live/server.py @@ -216,7 +216,8 @@ class TranscriptionServer: try: if self.backend.is_faster_whisper(): from whisper_live.backend.faster_whisper_backend import ServeClientFasterWhisper - if faster_whisper_custom_model_path is not None and os.path.exists(faster_whisper_custom_model_path): + # model is of the form namespace/repo_name and not a filesystem path + if faster_whisper_custom_model_path is not None: logging.info(f"Using custom model {faster_whisper_custom_model_path}") options["model"] = faster_whisper_custom_model_path client = ServeClientFasterWhisper( @@ -380,8 +381,6 @@ class TranscriptionServer: port (int): The port number to bind the server. """ self.cache_path = cache_path - if faster_whisper_custom_model_path is not None and not os.path.exists(faster_whisper_custom_model_path): - raise ValueError(f"Custom faster_whisper model '{faster_whisper_custom_model_path}' is not a valid path.") if whisper_tensorrt_path is not None and not os.path.exists(whisper_tensorrt_path): raise ValueError(f"TensorRT model '{whisper_tensorrt_path}' is not a valid path.") if single_model: