imseldrith/TTS-OPENAI-FREE
1
1#!/usr/bin/env python32try:3 import dotenv4 dotenv.load_dotenv()5except ImportError:6 pass7 8import argparse9import os10import pysbd11import queue12import sys13import tempfile14import threading15import shutil16import sys17import tempfile18import contextlib19 20import openai21 22try:23 from playsound import playsound24except ImportError:25 print("Error: missing required package 'playsound'. !pip install playsound")26 sys.exit(1)27 28@contextlib.contextmanager29def tempdir():30 path = tempfile.mkdtemp()31 try:32 yield path33 finally:34 try:35 shutil.rmtree(path)36 except IOError:37 sys.stderr.write('Failed to clean up temp dir {}'.format(path))38 39class SimpleAudioPlayer:40 def __init__(self):41 self._queue = queue.Queue()42 self.running = True43 self._thread = threading.Thread(target=self.__play_audio_loop, daemon=True)44 self._thread.start()45 46 def put(self, file):47 self._queue.put(file)48 49 def stop(self):50 self.running = False51 self._thread.join()52 try:53 while True:54 file = self._queue.get_nowait()55 if os.path.exists(file):56 os.unlink(file)57 except queue.Empty as e:58 pass59 60 def __play_audio_loop(self):61 while self.running:62 try:63 while True:64 file = self._queue.get(block=True, timeout=0.01)65 66 try:67 playsound(file)68 finally:69 os.unlink(file)70 71 except queue.Empty as e:72 continue73 74class OpenAI_tts:75 def __init__(self, model, voice, speed, base_dir):76 self.base_dir = base_dir77 self.openai_client = openai.OpenAI(78 # export OPENAI_API_KEY=sk-1111111111179 # export OPENAI_BASE_URL=http://localhost:8000/v180 api_key = os.environ.get("OPENAI_API_KEY", "sk-ip"),81 base_url = os.environ.get("OPENAI_BASE_URL", "http://localhost:8000/v1"),82 )83 84 self.params = {85 'model': model,86 'voice': voice,87 'speed': speed88 }89 90 def speech_to_file(self, text: str) -> None:91 with self.openai_client.audio.speech.with_streaming_response.create(92 input=text, response_format='opus', **self.params93 ) as response:94 tf, output_filename = tempfile.mkstemp(suffix='.wav', prefix="audio_reader_", dir=self.base_dir)95 response.stream_to_file(output_filename)96 return output_filename97 98 99if __name__ == "__main__":100 parser = argparse.ArgumentParser(101 description='Text to speech player',102 formatter_class=argparse.ArgumentDefaultsHelpFormatter)103 104 parser.add_argument('-m', '--model', action='store', default="tts-1", help="The OpenAI model")105 parser.add_argument('-v', '--voice', action='store', default="alloy", help="The voice to use")106 parser.add_argument('-s', '--speed', action='store', default=1.0, help="How fast to read the audio")107 108 args = parser.parse_args()109 110 try:111 with tempdir() as base_dir:112 player = SimpleAudioPlayer()113 reader = OpenAI_tts(voice=args.voice, model=args.model, speed=args.speed, base_dir=base_dir)114 seg = pysbd.Segmenter(language='en', clean=True) # text is dirty, clean it up.115 116 for raw_line in sys.stdin:117 for line in seg.segment(raw_line):118 if not line:119 continue120 121 print(line)122 player.put(reader.speech_to_file(line))123 124 player.stop()125 126 except KeyboardInterrupt:127 pass128 