How to make this into website?
import argparse
import os
import numpy as np
import speech_recognition as sr
import whisper
import torch

from datetime import datetime, timedelta
from queue import Queue
from time import sleep
from sys import platform

from gen_response import generate
from voice import text_to_speech
from playsound import playsound
import os
import threading
import ast

class AudioPlayer:
    def __init__(self):
        self.current_thread = None
        self.stop_event = threading.Event()

    def play_audio(self, audio_file):
        if self.current_thread and self.current_thread.is_alive():
            self.stop_event.set()  # Signal the current playback to stop
            self.current_thread.join(timeout=0.5)  # Wait for a short time for thread to finish
            if self.current_thread.is_alive():
                # If the thread did not stop, we might need to handle this case
                # However, playsound does not provide a direct way to stop playback
                # You might need to use a different audio library for better control
                print("Warning: Previous audio could not be stopped gracefully.")
        
        self.stop_event.clear()
        self.current_thread = threading.Thread(target=self._play_audio, args=(audio_file,))
        self.current_thread.start()

    def _play_audio(self, audio_file):
        try:
            playsound(audio_file, block=False)
            while self.current_thread and not self.stop_event.is_set():
                self.stop_event.wait(0.1)
        except Exception as e:
            print(f"Error playing audio: {e}")
        finally:
            if os.path.exists(audio_file):
                try:
                    os.remove(audio_file)
                except Exception as e:
                    print(f"Error removing audio file: {e}")

# Create an instance of AudioPlayer
audio_player = AudioPlayer()

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--model", default="medium", help="Model to use",
                        choices=["tiny", "base", "small", "medium", "large"])
    parser.add_argument("--non_english", action='store_true',
                        help="Don't use the english model.")
    parser.add_argument("--energy_threshold", default=1000,
                        help="Energy level for mic to detect.", type=int)
    parser.add_argument("--record_timeout", default=2,
                        help="How real time the recording is in seconds.", type=float)
    parser.add_argument("--phrase_timeout", default=3,
                        help="How much empty space between recordings before we "
                             "consider it a new line in the transcription.", type=float)
    if 'linux' in platform:
        parser.add_argument("--default_microphone", default='pulse',
                            help="Default microphone name for SpeechRecognition. "
                                 "Run this with 'list' to view available Microphones.", type=str)
    args = parser.parse_args()

    # The last time a recording was retrieved from the queue.
    phrase_time = None
    # Thread safe Queue for passing data from the threaded recording callback.
    data_queue = Queue()
    # We use SpeechRecognizer to record our audio because it has a nice feature where it can detect when speech ends.
    recorder = sr.Recognizer()
    recorder.energy_threshold = args.energy_threshold
    # Definitely do this, dynamic energy compensation lowers the energy threshold dramatically to a point where the SpeechRecognizer never stops recording.
    recorder.dynamic_energy_threshold = False

    # Important for linux users.
    # Prevents permanent application hang and crash by using the wrong Microphone
    if 'linux' in platform:
        mic_name = args.default_microphone
        if not mic_name or mic_name == 'list':
            print("Available microphone devices are: ")
            for index, name in enumerate(sr.Microphone.list_microphone_names()):
                print(f"Microphone with name \"{name}\" found")
            return
        else:
            for index, name in enumerate(sr.Microphone.list_microphone_names()):
                if mic_name in name:
                    source = sr.Microphone(sample_rate=16000, device_index=index)
                    break
    else:
        source = sr.Microphone(sample_rate=16000)

    # Load / Download model
    model = args.model
    if args.model != "large" and not args.non_english:
        model = model + ".en"
    audio_model = whisper.load_model('base.en')#model)
    
    
    now = datetime.now()
    name = input('Enter you name: ')
    # Load the conversations
    with open('conversations.txt','a+') as f:
        f.write(str({'role':'system', 'content':f'You are Julia, a cute and humorous girl. You are a girlfriend of user and flirt user to make him feel better. User\'s name is {name}. Current time is {now.year}-{now.month}-{now.day} {now.hour}:{now.minute}. But remember to answer shortly in a sentence.'}) + '\n')
    
    messages = []
    with open('conversations.txt', 'r') as f:
        for x in f.readlines():
            print(x)
            messages.append(ast.literal_eval(x))

    record_timeout = args.record_timeout
    phrase_timeout = args.phrase_timeout

    transcription = ['']

    with source:
        recorder.adjust_for_ambient_noise(source)

    def record_callback(_, audio:sr.AudioData) -> None:
        """
        Threaded callback function to receive audio data when recordings finish.
        audio: An AudioData containing the recorded bytes.
        """
        # Grab the raw bytes and push it into the thread safe queue.
        data = audio.get_raw_data()
        data_queue.put(data)

    # Create a background thread that will pass us raw audio bytes.
    # We could do this manually but SpeechRecognizer provides a nice helper.
    recorder.listen_in_background(source, record_callback, phrase_time_limit=record_timeout)

    os.system('cls')
    
    # Cue the user that we're ready to go.
    print("Model loaded. You may now say.\n")
    
    
    def play_audio(audio_file):
        playsound(audio_file)
        os.remove(audio_file)
    
    while True:
        try:
            now = datetime.now()
            # Pull raw recorded audio from the queue.
            if not data_queue.empty():
                phrase_complete = False
                # If enough time has passed between recordings, consider the phrase complete.
                # Clear the current working audio buffer to start over with the new data.
                if phrase_time and now - phrase_time > timedelta(seconds=phrase_timeout):
                    phrase_complete = True
                # This is the last time we received new audio data from the queue.
                phrase_time = now
                
                # Combine audio data from queue
                audio_data = b''.join(data_queue.queue)
                data_queue.queue.clear()
                
                # Convert in-ram buffer to something the model can use directly without needing a temp file.
                # Convert data from 16 bit wide integers to floating point with a width of 32 bits.
                # Clamp the audio stream frequency to a PCM wavelength compatible default of 32768hz max.
                audio_np = np.frombuffer(audio_data, dtype=np.int16).astype(np.float32) / 32768.0

                # Read the transcription.
                result = audio_model.transcribe(audio_np, fp16=torch.cuda.is_available())
                text = result['text'].strip()

                # If we detected a pause between recordings, add a new item to our transcription.
                # Otherwise edit the existing one.
                if phrase_complete:
                    transcription.append(text)
                else:
                    transcription[-1] = text

                os.system('cls' if os.name=='nt' else 'clear')
                for line in transcription:
                    print(line)
                    
                messages.append({'role':'user', 'content': text})
                with open('conversations.txt','a+') as f:
                    f.write(str({'role':'user', 'content': text}) + '\n')
                
                
                response = generate(messages)
                print(response)
                messages.append({'role':'assistant', 'content': response})
                with open('conversations.txt','a+') as f:
                    f.write(str({'role':'assistant', 'content': response}) + '\n')
                
                audio_file = text_to_speech(response, 'en-US-AvaNeural', 0, 0)
                
                # AudioPlayer를 통한 소리 재생
                audio_player.play_audio(audio_file)
                
                # 앙기모띠
                print('', end='', flush=True)
            else:
                # 0.25초 쉬고 프로세스 다시 시작 ㄱㄱ
                sleep(0.25)
        except KeyboardInterrupt:
            break

    print("\n\nTranscription:")
    for line in transcription:
        print(line)


if __name__ == "__main__":
    main()