|
@@ -0,0 +1,238 @@
|
|
|
+import os
|
|
|
+
|
|
|
+
|
|
|
+from selenium.webdriver.common.by import By
|
|
|
+
|
|
|
+import time
|
|
|
+
|
|
|
+import undetected_chromedriver as uc
|
|
|
+from datetime import datetime
|
|
|
+import random
|
|
|
+import string
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+from dotenv import load_dotenv
|
|
|
+import os
|
|
|
+import shutil
|
|
|
+import logging
|
|
|
+from fastapi import APIRouter, FastAPI
|
|
|
+import uvicorn
|
|
|
+from fastapi.middleware.cors import CORSMiddleware
|
|
|
+from supabase import create_client, Client
|
|
|
+
|
|
|
+load_dotenv()
|
|
|
+
|
|
|
+logging.basicConfig(level=logging.INFO)
|
|
|
+
|
|
|
+SUPABASE_URL: str = os.environ.get('SUPABASE_URL')
|
|
|
+SUPABASE_KEY: str = os.environ.get('SUPABASE_KEY')
|
|
|
+supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
|
|
|
+
|
|
|
+def download_blob(browser, blob_url, filename='output.mp3'):
|
|
|
+
|
|
|
+ js_code = f"""
|
|
|
+ fetch('{blob_url}')
|
|
|
+ .then(response => response.blob())
|
|
|
+ .then(blob => {{
|
|
|
+ const url = URL.createObjectURL(blob);
|
|
|
+ const a = document.createElement('a');
|
|
|
+ a.href = url;
|
|
|
+ a.download = '{filename}';
|
|
|
+ document.body.appendChild(a);
|
|
|
+ a.click();
|
|
|
+ document.body.removeChild(a);
|
|
|
+ }})
|
|
|
+ .catch(error => console.error('Error downloading file:', error));
|
|
|
+ """
|
|
|
+ browser.execute_script(js_code)
|
|
|
+
|
|
|
+def tts_downloadfile(text):
|
|
|
+ start_time = time.time()
|
|
|
+ print(f'text長度: {len(text)}')
|
|
|
+ num = random.randint(3,5)
|
|
|
+ url = 'http://tts001.iptcloud.net:8804/'
|
|
|
+
|
|
|
+ default_download_folder = os.path.join(os.path.expanduser('~'), 'Downloads')
|
|
|
+ download_folder = '/var/www/html/innolux/tts_folder'
|
|
|
+ file_name = datetime.now().strftime(f"%Y%m%d%H%M%S_{''.join(random.sample(string.ascii_lowercase, 3))}.mp3")
|
|
|
+
|
|
|
+ os.makedirs(download_folder, exist_ok=True)
|
|
|
+
|
|
|
+ options = uc.ChromeOptions()
|
|
|
+ options.add_argument('--ignore-certificate-errors')
|
|
|
+ prefs = {
|
|
|
+ "download.default_directory": download_folder,
|
|
|
+ "download.prompt_for_download": False,
|
|
|
+ "safebrowsing.enabled": True,
|
|
|
+ }
|
|
|
+ options.add_experimental_option("prefs", prefs)
|
|
|
+
|
|
|
+ options.add_argument('--headless')
|
|
|
+ options.add_argument("--disable-gpu")
|
|
|
+
|
|
|
+
|
|
|
+ with uc.Chrome(options=options, version_main=129) as browser:
|
|
|
+ try:
|
|
|
+ browser.get(url)
|
|
|
+
|
|
|
+ time.sleep(num)
|
|
|
+
|
|
|
+ browser.find_element(By.XPATH, '//*[@id="js-input"]').send_keys(text)
|
|
|
+ time.sleep(0.1)
|
|
|
+ browser.find_element(By.XPATH, '//*[@id="js-translate"]').click()
|
|
|
+ time.sleep(0.1 + len(text)*0.01)
|
|
|
+
|
|
|
+ browser.execute_script('window.scrollBy(0, 200);')
|
|
|
+
|
|
|
+
|
|
|
+ browser.find_element(By.XPATH, '//*[@id="button1"]').click()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ audio_src = None
|
|
|
+ while not audio_src:
|
|
|
+ if time.time() - start_time > 45:
|
|
|
+ return 'Time exceeded'
|
|
|
+
|
|
|
+ audio_element = browser.find_element(By.XPATH, '//*[@id="audio1"]')
|
|
|
+ audio_src = audio_element.get_attribute('src')
|
|
|
+
|
|
|
+ if audio_src:
|
|
|
+ print("音頻來源:", audio_src)
|
|
|
+ download_blob(browser, audio_src, file_name)
|
|
|
+ else:
|
|
|
+ print("尚未檢測到音頻,繼續等待...")
|
|
|
+ time.sleep(0.3)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ is_default = False
|
|
|
+
|
|
|
+ file_path = '/var/www/html/innolux/tts_folder' + '/' + file_name
|
|
|
+ default_file_path = '/root/Downloads' + '/' + file_name
|
|
|
+ while not os.path.exists(file_path):
|
|
|
+ print('...')
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ time.sleep(0.001)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ print(f"下載完成: {file_path}")
|
|
|
+ file_path = file_path.split('html/')[1]
|
|
|
+ print(file_path)
|
|
|
+ print(time.time() - start_time)
|
|
|
+
|
|
|
+ return file_path
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print(f'Error: {e}')
|
|
|
+ return e
|
|
|
+
|
|
|
+
|
|
|
+app = FastAPI()
|
|
|
+
|
|
|
+app.add_middleware(
|
|
|
+ CORSMiddleware,
|
|
|
+ allow_origins=["*"],
|
|
|
+ allow_credentials=True,
|
|
|
+ allow_methods=["*"],
|
|
|
+ allow_headers=["*"],
|
|
|
+)
|
|
|
+
|
|
|
+
|
|
|
+@app.post('/tts')
|
|
|
+async def tts(answer: str):
|
|
|
+ file_path = tts_downloadfile(answer)
|
|
|
+
|
|
|
+
|
|
|
+ if file_path:
|
|
|
+ return {'message': {'mp3_url': file_path}}
|
|
|
+ else:
|
|
|
+ return {"message": "tts processing failed."}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ uvicorn.run("台語tts:app", reload=False, port=8093, host='cmm.ai', ssl_keyfile="/etc/letsencrypt/live/cmm.ai/privkey.pem", ssl_certfile="/etc/letsencrypt/live/cmm.ai/fullchain.pem")
|