CoolFace
Apppublic

imseldrith/TTS-OPENAI-FREE

sourceHugging Facemitupdated 2y agoView on Hugging Face
1likes
audio_reader.py128 linesDownload Raw Back to root
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