ttspy.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import pyttsx3
  2. import requests
  3. from openai import OpenAI
  4. import openai
  5. import random
  6. import os
  7. import time
  8. import json
  9. import threading
  10. from itertools import chain
  11. from gtts import gTTS
  12. import os
  13. client = OpenAI()
  14. def txt_to_speach(text):
  15. # text_list_1 = text.replace(" ","").replace(",",",").split("。")
  16. text_list = text.replace(" ","").replace(",",",").split("。")
  17. filename = f"static/tts/mp3/output{random.randint(1,25)}.mp3"
  18. filenames = []
  19. text_list = [item.split(',') if len(item) > 30 else [item] for item in text_list ]
  20. text_list = list(chain.from_iterable(text_list ))
  21. # 建立存放執行序的list(存放thread)
  22. threads = []
  23. # 放入執行序
  24. for i,text_split in enumerate(text_list):
  25. text_split = text_split.strip()
  26. # 檢查字串是否為空
  27. if not text_split:
  28. continue
  29. t = threading.Thread(target=text_split_to_text, args=(text_split,i,filename))
  30. threads.append(t) # 將程序放入threads
  31. filenames.append(f"/home/mia/101/{filename}-{i}.mp3")
  32. print(filenames)
  33. # 開始
  34. for t in threads:
  35. t.start()
  36. # 等待所有子執行緒結束
  37. for t in threads:
  38. t.join()
  39. merge_audio_files(filenames, f"/home/mia/101/{filename}")
  40. return filename,text_list
  41. def text_split_to_text(text_split,i,filename):
  42. response = client.audio.speech.create(
  43. model="tts-1",
  44. voice="nova",
  45. input=text_split
  46. )
  47. filename_tmp = f"/home/mia/101/{filename}-{i}.mp3"
  48. response.stream_to_file(filename_tmp)
  49. import subprocess
  50. from pydub import AudioSegment
  51. from moviepy.editor import VideoFileClip, AudioFileClip, concatenate_videoclips
  52. def merge_audio_files(files, output_file):
  53. # 生成 ffmpeg 的命令
  54. cmd = ['ffmpeg', '-i', 'concat:' + '|'.join(files), '-c', 'copy', '-y',output_file]
  55. # 执行命令
  56. subprocess.run(cmd)
  57. # 刪除暫時生成的音頻文件
  58. for filename in files:
  59. os.remove(filename)
  60. # combined = AudioSegment.empty()
  61. # # 逐一載入每個音頻文件並合併
  62. # for file in files:
  63. # audio = AudioSegment.from_file(file, format="mp3")
  64. # combined += audio
  65. # # 將合併後的音頻保存為新文件
  66. # combined.export(output_file, format="mp3")
  67. def download_voice(text,voice="zh-TW-HsiaoChenNeural", pronunciations=None):
  68. output_url = f"static/tts/mp/output{random.randint(1,25)}.mp3"
  69. output = "/home/mia/101/" + output_url
  70. my_data = {
  71. "voice": voice,
  72. "content": [str(text)] #["你好,很高興認識你","喜歡","討厭"]
  73. # "ssml": string[]
  74. # "title": string, // Optional
  75. # "narrationStyle": string, // Optional
  76. # "globalSpeed": string, // Optional
  77. # "pronunciations": { key: string, value: string }[], // Optional
  78. # "trimSilence": boolean, // Optional
  79. }
  80. headers = {
  81. # 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36',
  82. "Authorization":"61ddf2a47cdd42548671be21ccdcf285",
  83. "X-User-ID":'HEQLQR1WgpYtN0SEyKoWBsLiZXX2',
  84. "Content-Type": "application/json"
  85. }
  86. start_time = time.time()
  87. # 將資料加入 POST 請求中
  88. r = requests.post('https://play.ht/api/v1/convert',headers=headers,data=json.dumps(my_data))
  89. c1 = r.json()
  90. print(c1)
  91. c1 = r.json()['transcriptionId']
  92. # print(c1)
  93. time.sleep(len(text))
  94. success_flag = False
  95. r =''
  96. while True:
  97. r = requests.post('https://play.ht/api/v1/convert',headers=headers,data=json.dumps(my_data))
  98. c1 = r.json()['transcriptionId']
  99. print(f"{text}:{c1}")
  100. # time.sleep(0.5+(len(text)/4))
  101. counter = 0
  102. while True:
  103. r = requests.get('https://play.ht/api/v1/articleStatus?transcriptionId=%s'%c1, headers=headers)
  104. if 'json' not in r.headers.get('content-type') or r.json()['converted'] == False:
  105. print(f"audio {c1} is not ready.")
  106. # time.sleep(0.5)
  107. counter += 1
  108. if counter == 6:
  109. break
  110. else:
  111. success_flag = True
  112. break
  113. if success_flag:
  114. break
  115. else:
  116. print('redownload')
  117. file = requests.get(r.json()['audioUrl'])
  118. with open(output,"wb") as f:
  119. for chunk in file.iter_content(chunk_size=1024):
  120. if chunk:
  121. f.write(chunk)
  122. end_time = time.time()
  123. execution_time = end_time - start_time
  124. print("reply time:", execution_time, "s")
  125. return output_url,execution_time