tudeplom commited on
Commit
edcef16
·
verified ·
1 Parent(s): 4164780

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -41
app.py CHANGED
@@ -1,10 +1,9 @@
1
  import os
2
  import wave
3
  import json
4
-
5
-
6
  import uuid
7
- import numpy as np
 
8
  from flask import Flask, request, jsonify
9
  from flask_cors import CORS
10
  from vosk import Model, KaldiRecognizer
@@ -17,8 +16,8 @@ model = Model(MODEL_PATH)
17
 
18
  # Khởi tạo Flask app
19
  app = Flask(__name__)
20
- CORS(app)
21
- Swagger(app)
22
 
23
  @app.route("/")
24
  def home():
@@ -38,10 +37,10 @@ def stt():
38
  - multipart/form-data
39
  parameters:
40
  - in: formData
41
- name: audio
42
  type: file
43
  required: true
44
- description: File âm thanh WAV mono PCM
45
  responses:
46
  200:
47
  description: Kết quả chuyển đổi văn bản
@@ -53,55 +52,82 @@ def stt():
53
  example: "Xin chào thế giới"
54
  400:
55
  description: Lỗi nếu file âm thanh không hợp lệ hoặc không tìm thấy
 
 
56
  """
57
- if "audio" not in request.files:
58
- return jsonify({"error": "Không tìm thấy file audio!"}), 400
59
-
60
- audio_file = request.files["audio"]
61
- file_path = f"/tmp/{uuid.uuid4()}.wav" # Lưu vào thư mục tạm để tránh lỗi quyền hạn
62
- audio_file.save(file_path)
63
-
 
 
 
 
 
 
 
 
 
64
  try:
65
- # Mở file âm thanh
66
- wf = wave.open(file_path, "rb")
67
-
68
- # Kiểm tra file có đúng định dạng WAV mono không
 
 
 
 
 
 
 
 
 
 
 
 
69
  if wf.getnchannels() != 1 or wf.getsampwidth() != 2 or wf.getcomptype() != "NONE":
70
- return jsonify({"error": "File audio phải WAV mono PCM!"}), 400
71
 
 
72
  rec = KaldiRecognizer(model, wf.getframerate())
73
  result_text = ""
74
 
 
75
  while True:
76
  data = wf.readframes(4000)
77
  if len(data) == 0:
78
  break
79
  if rec.AcceptWaveform(data):
80
- result_text += json.loads(rec.Result())["text"] + " "
81
-
82
- return jsonify({"text": result_text.strip()})
83
-
 
 
 
 
 
 
 
 
 
 
 
 
84
  except Exception as e:
85
- return jsonify({"error": str(e)}), 500
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
 
99
  finally:
100
- wf.close()
101
- os.remove(file_path) # Xóa file tạm
102
-
103
-
104
-
 
 
105
 
106
  if __name__ == "__main__":
107
  app.run(host="0.0.0.0", port=7860, debug=True)
 
1
  import os
2
  import wave
3
  import json
 
 
4
  import uuid
5
+ import tempfile
6
+ import ffmpeg
7
  from flask import Flask, request, jsonify
8
  from flask_cors import CORS
9
  from vosk import Model, KaldiRecognizer
 
16
 
17
  # Khởi tạo Flask app
18
  app = Flask(__name__)
19
+ CORS(app) # Cho phép CORS để React app truy cập
20
+ Swagger(app) # Khởi tạo Swagger cho tài liệu API
21
 
22
  @app.route("/")
23
  def home():
 
37
  - multipart/form-data
38
  parameters:
39
  - in: formData
40
+ name: file
41
  type: file
42
  required: true
43
+ description: File âm thanh WebM (sẽ được chuyển đổi sang WAV mono PCM)
44
  responses:
45
  200:
46
  description: Kết quả chuyển đổi văn bản
 
52
  example: "Xin chào thế giới"
53
  400:
54
  description: Lỗi nếu file âm thanh không hợp lệ hoặc không tìm thấy
55
+ 500:
56
+ description: Lỗi server nội bộ
57
  """
58
+ # Kiểm tra trường 'file' để khớp với React
59
+ if "file" not in request.files:
60
+ return jsonify({"error": "Không tìm thấy file âm thanh! Vui lòng gửi trường 'file'."}), 400
61
+
62
+ audio_file = request.files["file"]
63
+ if audio_file.filename == "":
64
+ return jsonify({"error": "Không có file được chọn!"}), 400
65
+
66
+ # Lưu file WebM tạm thời
67
+ with tempfile.NamedTemporaryFile(suffix=".webm", delete=False) as temp_webm_file:
68
+ webm_path = temp_webm_file.name
69
+ audio_file.save(webm_path)
70
+
71
+ # Đường dẫn file WAV tạm thời sau khi chuyển đổi
72
+ wav_path = None
73
+ wf = None
74
  try:
75
+ # Chuyển đổi WebM sang WAV mono PCM bằng ffmpeg
76
+ wav_path = tempfile.mktemp(suffix=".wav")
77
+ stream = ffmpeg.input(webm_path)
78
+ stream = ffmpeg.output(
79
+ stream,
80
+ wav_path,
81
+ acodec="pcm_s16le", # PCM 16-bit signed little-endian
82
+ ac=1, # Mono
83
+ ar=16000 # Tần số mẫu 16kHz, phù hợp với Vosk
84
+ )
85
+ ffmpeg.run(stream, overwrite_output=True, quiet=True)
86
+
87
+ # Mở file WAV đã chuyển đổi
88
+ wf = wave.open(wav_path, "rb")
89
+
90
+ # Kiểm tra định dạng WAV mono PCM
91
  if wf.getnchannels() != 1 or wf.getsampwidth() != 2 or wf.getcomptype() != "NONE":
92
+ return jsonify({"error": "Định dạng WAV sau chuyển đổi không đúng!"}), 400
93
 
94
+ # Khởi tạo KaldiRecognizer
95
  rec = KaldiRecognizer(model, wf.getframerate())
96
  result_text = ""
97
 
98
+ # Đọc và xử lý dữ liệu âm thanh
99
  while True:
100
  data = wf.readframes(4000)
101
  if len(data) == 0:
102
  break
103
  if rec.AcceptWaveform(data):
104
+ result = json.loads(rec.Result())
105
+ result_text += result.get("text", "") + " "
106
+ else:
107
+ # Thêm kết quả từng phần để cải thiện độ chính xác
108
+ partial_result = json.loads(rec.PartialResult())
109
+ if partial_result.get("partial", ""):
110
+ result_text += partial_result["partial"] + " "
111
+
112
+ # Trả về kết quả đã xử lý
113
+ final_text = result_text.strip()
114
+ if not final_text:
115
+ final_text = "Không nhận diện được nội dung âm thanh."
116
+ return jsonify({"text": final_text})
117
+
118
+ except ffmpeg.Error as e:
119
+ return jsonify({"error": f"Lỗi chuyển đổi âm thanh từ WebM sang WAV: {str(e.stderr.decode())}"}), 500
120
  except Exception as e:
121
+ return jsonify({"error": f"Lỗi xử lý âm thanh: {str(e)}"}), 500
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  finally:
124
+ # Đóng file WAV nếu đã mở
125
+ if wf is not None:
126
+ wf.close()
127
+ # Xóa các file tạm
128
+ for path in [webm_path, wav_path]:
129
+ if path and os.path.exists(path):
130
+ os.remove(path)
131
 
132
  if __name__ == "__main__":
133
  app.run(host="0.0.0.0", port=7860, debug=True)