dbOperate_upload_Uvoice.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. import shutil
  2. import time
  3. import zipfile
  4. from datetime import datetime
  5. from pydub import AudioSegment
  6. from pydub.exceptions import CouldntDecodeError
  7. import uuid
  8. import tempfile
  9. import os
  10. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "aiDogProject.settings")
  11. import django
  12. django.setup()
  13. from aiDogApp.models import *
  14. from .generalRequest import req_url # Importing your generalRequest.py method
  15. # 转换上传的文件流为mp3 并存储在本地
  16. def process_audio_file(file_stream, output_mp3_path):
  17. try:
  18. # 使用临时目录创建临时 WAV 文件路径----old version
  19. # temp_dir = tempfile.gettempdir() # 使用系统临时目录
  20. # temp_wav_path = os.path.join(temp_dir, f"temp_{uuid.uuid4().hex}.wav")
  21. # 文件处理优化:使用内存处理(如io.BytesIO)替代文件 I / O,减少磁盘访问。---new version
  22. temp_wav_path = tempfile.mktemp(suffix='.wav')
  23. # 保存上传的文件流为临时 WAV 文件
  24. with open(temp_wav_path, 'wb') as temp_file:
  25. temp_file.write(file_stream.read())
  26. # 检查临时文件是否有效
  27. if not os.path.exists(temp_wav_path) or os.path.getsize(temp_wav_path) == 0:
  28. # print("Error: Temporary WAV file is empty or not created.")
  29. return False
  30. # 转换 WAV 到 MP3
  31. audio_segment = AudioSegment.from_wav(temp_wav_path)
  32. audio_segment.export(output_mp3_path, format="mp3")
  33. # 清理临时 WAV 文件
  34. os.remove(temp_wav_path)
  35. return True
  36. # return "Success: Audio file converted and saved."
  37. except Exception as e:
  38. print(f"Error processing audio file: {e}")
  39. return False
  40. # return f"Error: {str(e)}"
  41. # 将zip内的wav文件解压出来
  42. # 再转换上传的文件流为mp3 并存储在本地
  43. # 2025/4/1
  44. # author Feng
  45. def process_zip_audio_file(file_stream, output_mp3_path):
  46. try:
  47. # 创建临时目录用于解压文件
  48. temp_dir = tempfile.mkdtemp()
  49. zip_name = output_mp3_path[0:8]
  50. temp_zip_path = os.path.join(temp_dir, f"{zip_name}.zip")
  51. # 保存上传的压缩文件流
  52. with open(temp_zip_path, 'wb') as temp_file:
  53. temp_file.write(file_stream.read())
  54. # 检查临时压缩文件是否有效
  55. if not os.path.exists(temp_zip_path) or os.path.getsize(temp_zip_path) == 0:
  56. print("Error: Temporary ZIP file is empty or not created.")
  57. return False
  58. # return "Error: Temporary ZIP file is empty or not created."
  59. # 解压文件
  60. with zipfile.ZipFile(temp_zip_path, 'r') as zip_ref:
  61. zip_ref.extractall(temp_dir)
  62. # 查找voice.wav文件
  63. wav_file_path = os.path.join(temp_dir, "voice.wav")
  64. if not os.path.exists(wav_file_path):
  65. print("Error: voice.wav not found in the zip archive.")
  66. return False
  67. # return "Error: voice.wav not found in the zip archive."
  68. # 转换WAV到MP3
  69. audio_segment = AudioSegment.from_wav(wav_file_path)
  70. audio_segment.export(output_mp3_path, format="mp3")
  71. # 清理临时文件
  72. shutil.rmtree(temp_dir) # 递归删除临时目录及其内容
  73. return True
  74. except Exception as e:
  75. print(f"Error processing audio file: {e}")
  76. # 确保清理临时文件,即使发生错误
  77. if 'temp_dir' in locals() and os.path.exists(temp_dir):
  78. shutil.rmtree(temp_dir)
  79. return False
  80. # return f"Error processing audio file: {e}"
  81. # Function to insert audio information into MySQL database
  82. def insert_voice_data(uid,mp3_path, feature_id,command_type,record_time):
  83. try:
  84. # 读取 WAV 文件 为二进制数据
  85. # with open(mp3_path, 'rb') as audio_file:
  86. # wav_data = audio_file.read()
  87. wav_data=''
  88. # 插入到声纹信息表中
  89. # 口令类型(0:叫名字 1:坐下,2:站起,3:摇尾巴,4:走过来,5 抬左手,6:抬右手)
  90. if command_type==0:
  91. # 口令类型(0:叫名字
  92. # insert_query = """
  93. # INSERT INTO voice_feature_info (uid, voice_feature_id, voice_name_command,command_type)
  94. # VALUES (%s, %s, %s, %s)
  95. # """
  96. # # cursor.execute(insert_query, (uid, feature_id, wav_data, command_type))
  97. updated_count =VoiceFeatureInfo.objects.filter(uid=uid,command_type=command_type).update(voice_feature_id=feature_id, voice_name_command=wav_data,
  98. record_time=record_time)
  99. if updated_count > 0:
  100. return True
  101. else:
  102. return False
  103. elif command_type==1:
  104. # 口令类型(1:坐下
  105. updated_count =VoiceFeatureInfo.objects.filter(uid=uid,command_type=command_type).update(voice_feature_id=feature_id, voice_sit_command=wav_data,
  106. record_time=record_time)
  107. if updated_count > 0:
  108. return True
  109. else:
  110. return False
  111. elif command_type == 2:
  112. # 口令类型(2:站起
  113. updated_count =VoiceFeatureInfo.objects.filter(uid=uid,command_type=command_type).update(voice_feature_id=feature_id, voice_stand_command=wav_data,
  114. record_time=record_time)
  115. if updated_count > 0:
  116. return True
  117. else:
  118. return False
  119. elif command_type == 3:
  120. # 口令类型(3:摇尾巴
  121. updated_count =VoiceFeatureInfo.objects.filter(uid=uid,command_type=command_type).update(voice_feature_id=feature_id, voice_wagtail_command=wav_data,
  122. record_time=record_time)
  123. if updated_count > 0:
  124. return True
  125. else:
  126. return False
  127. else:
  128. # 口令类型(4:走过来
  129. updated_count =VoiceFeatureInfo.objects.filter(uid=uid,command_type=command_type).update(voice_feature_id=feature_id, voice_come_command=wav_data,
  130. record_time=record_time)
  131. if updated_count > 0:
  132. return True
  133. else:
  134. return False
  135. # conn.commit()
  136. print(f"Data inserted into database for UID: {uid}")
  137. # return True
  138. # 抛出异常
  139. except Exception as err:
  140. print(f"Error: {err}")
  141. return f"Error: {str(err)}"
  142. # return False
  143. # APPId = "527f831f"
  144. # APISecret = "YWE5MjI0MzA4NmM3MTNmNTNiMWJkYzE4"
  145. # APIKey = "be5c37f3db1569737934240a0e3ad02d"
  146. APPId = "ed8eb862"
  147. APISecret = "YzEyMDYyMzljMDViNWJlZDdlOWJhYjVi"
  148. APIKey = "b4c831160d8933221e95bda817547e99"
  149. # 接收声纹录音, 保存在本地, 并插入声纹特征到数据库, 然后调用科大接口识别 req_url()
  150. def process_voice_recording(uid, voice_feature_id, command_type, file_stream,mp3_path):
  151. # 定义本地缓存路径
  152. # cache_directory = "audio_cache"
  153. # os.makedirs(cache_directory, exist_ok=True)
  154. # 创建一个唯一的文件名
  155. timestamp=int(time.time())
  156. dd = datetime.today()
  157. timestamp11 = datetime.strftime(dd, '%Y-%m-%d %H:%M:%S')
  158. record_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  159. # # 按用户ID分目录
  160. # user_directory = os.path.join(cache_directory, f"user_{uid}")
  161. # # 确保目录存在
  162. # os.makedirs(user_directory, exist_ok=True)
  163. # # 文件命名包含必要的标识信息
  164. # file_name = f"voice_{uid}_{voice_feature_id}_{timestamp}.mp3"
  165. #
  166. # mp3_path=os.path.join(user_directory, file_name)
  167. # 接收文件流转成mp3 并存储到cache
  168. # if process_audio_file(file_stream, mp3_path):
  169. if process_zip_audio_file(file_stream, mp3_path):
  170. # 如果转换成功,则插入数据库
  171. # return insert_voice_data(uid,mp3_path,voice_feature_id,command_type,record_time)
  172. # TODO 后续替换为本地声纹识别算法后,map3_path更换为特征值,只存储特征值到数据库,每次比对特征值即可-----TODO
  173. # if insert_voice_data(uid,mp3_path,voice_feature_id,command_type,record_time):
  174. # 调用第三方声纹识别 API
  175. res1 = req_url(
  176. api_name='createFeature', APPId=APPId, APIKey=APIKey, APISecret=APISecret,
  177. file_path=mp3_path, featureId=voice_feature_id, groupId=uid
  178. )
  179. print(f"Audio processing complete. API response: {res1}")
  180. yy = datetime.today()
  181. end_timestamp = datetime.strftime(yy, '%Y-%m-%d %H:%M:%S')
  182. # return (
  183. # f"音频文件缓存在 {mp3_path} 并且传参到 req_url().返回内容为{res}.请求时间为:---{timestamp11}.返回时间为:---{end_timestamp}")
  184. # return f"Audio processed and sent to req_url(). API response: {res}"
  185. # res['status'] = tempResult.get('header').get('message')
  186. # res["msg"] = str(base64.b64decode(fb), 'UTF-8')
  187. # res['response_time'] =datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S')
  188. res = {
  189. "code": 200,
  190. "status": res1['status'],
  191. "msg": res1["msg"],
  192. "response_time": res1['response_time'],
  193. }
  194. return res
  195. # else:
  196. # res = {
  197. # "code": 400,
  198. # "status": "Fail",
  199. # "msg": "Failed to insert voice data into database.",
  200. #
  201. # }
  202. return res
  203. else:
  204. res = {
  205. "code": 400,
  206. "status": "Fail",
  207. "msg": "Failed to process the audio file.",
  208. }
  209. print("Failed to process the audio file.")
  210. return res