File size: 2,642 Bytes
23590ba
 
 
4943521
23590ba
 
 
 
cbab8dc
23590ba
981b713
 
 
 
 
4943521
981b713
 
4943521
981b713
 
de1cb80
23590ba
 
4943521
23590ba
981b713
 
cbab8dc
 
 
 
 
 
4943521
23590ba
981b713
 
cbab8dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
981b713
 
23590ba
981b713
4943521
981b713
 
4943521
 
 
981b713
4943521
 
 
23590ba
4943521
 
981b713
4943521
 
 
 
 
 
23590ba
4943521
 
 
 
 
 
 
 
23590ba
 
981b713
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import os
import wave
import json
import uuid
import numpy as np
from flask import Flask, request, jsonify
from flask_cors import CORS
from vosk import Model, KaldiRecognizer
from flasgger import Swagger

# Thư mục chứa model
MODEL_PATH = "model/vosk-model"

# Kiểm tra model đã tải chưa
if not os.path.exists(MODEL_PATH):
    raise Exception(f"\u274C Model Vosk không tìm thấy tại {MODEL_PATH}! Kiểm tra lại.")

# Load model
print("\u2705 Đang tải model Vosk...")
model = Model(MODEL_PATH)

# Khởi tạo Flask app
app = Flask(__name__)
CORS(app)
Swagger(app)

@app.route("/")
def home():
    """API Home
    ---
    responses:
      200:
        description: API đang chạy
    """
    return "\u2705 Vosk STT API đang chạy!"

@app.route("/stt", methods=["POST"])
def stt():
    """Chuyển đổi giọng nói thành văn bản (Speech-to-Text)
    ---
    consumes:
      - multipart/form-data
    parameters:
      - in: formData
        name: audio
        type: file
        required: true
        description: File âm thanh WAV mono PCM
    responses:
      200:
        description: Kết quả chuyển đổi văn bản
        schema:
          type: object
          properties:
            text:
              type: string
              example: "Xin chào thế giới"
      400:
        description: Lỗi nếu file âm thanh không hợp lệ hoặc không tìm thấy
    """
    if "audio" not in request.files:
        return jsonify({"error": "Không tìm thấy file audio!"}), 400

    audio_file = request.files["audio"]
    file_path = f"/tmp/{uuid.uuid4()}.wav"  # Lưu vào thư mục tạm để tránh lỗi quyền hạn
    audio_file.save(file_path)

    try:
        # Mở file âm thanh
        wf = wave.open(file_path, "rb")

        # Kiểm tra file có đúng định dạng WAV mono không
        if wf.getnchannels() != 1 or wf.getsampwidth() != 2 or wf.getcomptype() != "NONE":
            return jsonify({"error": "File audio phải là WAV mono PCM!"}), 400

        rec = KaldiRecognizer(model, wf.getframerate())
        result_text = ""

        while True:
            data = wf.readframes(4000)
            if len(data) == 0:
                break
            if rec.AcceptWaveform(data):
                result_text += json.loads(rec.Result())["text"] + " "

        return jsonify({"text": result_text.strip()})
    
    except Exception as e:
        return jsonify({"error": str(e)}), 500
    
    finally:
        wf.close()
        os.remove(file_path)  # Xóa file tạm

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=7860, debug=True)