Nhà phát triển

API chuyển giọng nói thành văn bản

Chép lời tệp âm thanh hoàn chỉnh bằng tác vụ trong hàng đợi, với ước tính miễn phí, gửi có tính lũy đẳng và theo dõi mức sử dụng trên cả hai máy chủ API.

Trên trang này
  1. Điểm cuối
  2. Chuẩn bị tệp âm thanh
  3. Gửi tác vụ chép lời
  4. Khóa lũy đẳng
  5. Ước tính mà không tạo tác vụ
  6. Đọc bản chép lời
  7. Dùng api.multitel.net

API này chép lời các tệp âm thanh hoàn chỉnh bằng tác vụ trong hàng đợi. Gửi tệp, lưu ID tác vụ được trả về và truy vấn tác vụ cho đến khi xử lý xong. Gửi mọi yêu cầu qua HTTPS bằng thông tin xác thực của tài khoản: thông tin HTTP Basic như trong ví dụ hoặc mã thông báo API, theo hướng dẫn tại Xác thực. Giữ thông tin xác thực trên máy chủ của bạn.

Điểm cuối

Hai máy chủ API, https://api.multi.tel và máy chủ tương thích https://api.multitel.net, dùng chung tác vụ, khóa lũy đẳng, giới hạn và tính phí trong phạm vi tài khoản. Chúng khác nhau về mã hóa tải lên và cấu trúc bao ngoài của phản hồi, vì vậy hãy dùng nhất quán một máy chủ với bộ phân tích phù hợp.

Thao tácPhương thức và đường dẫn
Thông tin dịch vụGET /v3/speech_to_text
Gửi tác vụPOST /v3/speech_to_text
Ước tính mà không tạo tác vụPOST /v3/speech_to_text/estimate
Đọc tác vụGET /v3/speech_to_text/JOB_ID
Thanh toán tác vụ đang chờ trả phíPOST /v3/speech_to_text/JOB_ID/settle
Mức sử dụngGET /v3/speech_to_text/usage

Trên api.multi.tel, mọi đường dẫn cũng có thể dùng tiền tố /v1/speech-to-text thay cho /v3/speech_to_text, ví dụ POST /v1/speech-to-text/estimate. Trên api.multitel.net, hãy dùng các đường dẫn /v3/speech_to_text.

Phản hồi thông tin dịch vụ cung cấp mode (batch), realtime (false), paidEnabled (hiện có chấp nhận lượt gửi trả phí mới hay không), pricePerMinuteUsd (0.005), billingUnit (audio_second), maxAudioSeconds (7200) và maxUploadBytes (26214400), cùng với một description ngắn. Việc đọc là miễn phí và vẫn hoạt động khi lượt gửi trả phí bị tắt; chỉ trả về 503 transcription_unavailable khi toàn bộ dịch vụ không khả dụng.

Chuẩn bị tệp âm thanh

Dùng tệp âm thanh hoàn chỉnh có kích thước tối đa 25 MiB (26,214,400 byte) và thời lượng tối đa 2 giờ (7,200 giây). Khi gửi, tệp phải được nhận diện là nội dung MP3, WAV, Ogg, FLAC, MOV hoặc Matroska chứa luồng âm thanh, với thời lượng trong siêu dữ liệu lớn hơn không và không quá 7,200 giây. Tệp được nhận diện nhưng không đạt các bước kiểm tra này bị từ chối với 422 unsupported_audio. Hiện tại, tệp không đọc được theo bất kỳ định dạng nào kể trên có thể bị từ chối bằng lỗi máy chủ (500); đừng gửi lại tệp đó khi chưa thay đổi. Chỉ phần mở rộng của tệp không đủ để xác định tính tương thích.

Vượt qua các bước kiểm tra không bảo đảm âm thanh có thể được giải mã. Âm thanh được xử lý ở dạng một hoặc hai kênh. Tệp có hơn hai kênh âm thanh, tệp có thời lượng sau giải mã dài hơn 2 giờ hoặc tệp khác không giải mã được trong quá trình xử lý sẽ kết thúc dưới dạng tác vụ failed, thường có mã decode_failed, và không bị tính phí. Chuyển âm thanh đa kênh thành mono hoặc stereo trước khi gửi.

Gợi ý ngôn ngữ không bắt buộc là mã gồm hai hoặc ba chữ cái viết thường của ngôn ngữ được nói, chẳng hạn en. Để không đưa ra gợi ý, hãy bỏ trường này; api.multi.tel từ chối chuỗi rỗng. Gợi ý định hướng xử lý nhưng không được đối chiếu với danh sách ngôn ngữ hỗ trợ, vì vậy hãy dùng mã hợp lệ cho ngôn ngữ được nói.

Gửi tác vụ chép lời

Gửi JSON với Content-Type: application/json đến POST https://api.multi.tel/v3/speech_to_text. Nội dung yêu cầu có thể tối đa 35 MiB, đủ chứa tệp kích thước tối đa sau mã hóa base64; nội dung lớn hơn bị từ chối với 413.

TrườngÝ nghĩa
audioBase64Bắt buộc. Toàn bộ tệp ở dạng base64 chuẩn (A–Z, a–z, 0–9, +, /), dùng ký tự đệm = khi cần. Không thêm tiền tố data-URL, dấu xuống dòng hoặc khoảng trắng, và không dùng bảng ký tự an toàn cho URL. Giá trị sau giải mã phải từ 1 byte đến 25 MiB và khi mã hóa lại phải cho ra đúng văn bản ban đầu.
languageGợi ý ngôn ngữ không bắt buộc, như mô tả ở trên.

Mọi thuộc tính JSON khác, kể cả idempotency_key, đều bị từ chối với 400 invalid_transcription_request. Gửi khóa dưới dạng tiêu đề HTTP.

Khóa lũy đẳng

Mỗi lần gửi đều cần tiêu đề Idempotency-Key dài từ 1 đến 190 ký tự. Dùng chữ cái ASCII, chữ số, -, _, . và :, không có khoảng trắng đầu hoặc cuối: máy chủ tương thích loại bỏ khoảng trắng xung quanh và đo khóa theo byte, nên các ký tự khác có thể được đếm khác nhau trên từng máy chủ. Thiếu khóa hoặc khóa dài từ 191 ký tự trở lên bị từ chối với 400.

Khóa có phạm vi là tài khoản của bạn và dịch vụ chuyển giọng nói thành văn bản, trên cả hai máy chủ và mọi thông tin xác thực của tài khoản. Gửi lại cùng khóa với cùng tệp và ngôn ngữ sẽ trả về tác vụ hiện có với HTTP 200 và duplicate: true, bất kể trạng thái tác vụ, kể cả khi cơ chế xử lý đã được cập nhật sau lúc tạo tác vụ, mà không tính phí lần nữa. Dùng lại khóa với tệp hoặc ngôn ngữ khác trả về 409 idempotency_conflict. Khóa mới tạo tác vụ mới ngay cả với tệp giống hệt, và tính phí riêng nếu xử lý hoàn tất thành công.

API_USER="your-api-username"
API_PASSWORD="your-api-password"

node -e 'process.stdout.write(JSON.stringify({audioBase64:require("node:fs").readFileSync("completed-call.mp3").toString("base64"),language:"en"}))' > completed-call.json

curl --fail-with-body --silent --show-error --user "$API_USER:$API_PASSWORD" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: speech-call-001" \
  --data-binary @completed-call.json \
  -o speech-job.json \
  https://api.multi.tel/v3/speech_to_text

node -p 'JSON.parse(require("node:fs").readFileSync("speech-job.json","utf8")).data.id'

Tác vụ mới trả về HTTP 202 với các trường bên dưới; gửi lại cùng yêu cầu trả về HTTP 200 với toàn bộ đối tượng tác vụ được mô tả trong Đọc bản chép lời. Đọc ID tác vụ, là một UUID, từ data.id. Phản hồi của tác vụ mới có dạng sau (mã định danh và giá trị chỉ là ví dụ):

{
  "status": "success",
  "data": {
    "id": "3f6c1b2e-8a4d-4e7f-9c21-5b0d7e4a9f13",
    "status": "queued",
    "mode": "batch",
    "realtime": false,
    "source": "api",
    "durationSeconds": 90.5,
    "billedSeconds": 91,
    "costUsd": "0.007583334",
    "pricePerMinuteUsd": "0.005"
  }
}

Khi tác vụ đang trong hàng đợi hoặc đang chạy, durationSeconds, billedSeconds và costUsd là các ước tính từ siêu dữ liệu của tệp. Phí cuối cùng dùng thời lượng sau giải mã.

Lần gửi cũng có thể trả về 402 insufficient_balance khi số dư trả trước không đủ chi trả tác vụ cùng các tác vụ chưa thanh toán khác, 429 transcription_queue_full khi tài khoản hoặc dịch vụ có quá nhiều tác vụ chưa hoàn tất, 429 audio_validation_busy khi công suất kiểm tra tệp đã đầy và 503 paid_transcription_not_enabled khi chép lời trả phí bị tắt. Thử lại các phản hồi 429 và 503 sau bằng cùng khóa.

Ước tính mà không tạo tác vụ

Gửi cùng nội dung JSON đến POST https://api.multi.tel/v3/speech_to_text/estimate. Không cần khóa lũy đẳng. Ước tính kiểm tra và đo tệp nhưng không chép lời, tạo tác vụ, giữ tiền, kiểm tra số dư hoặc tính phí tài khoản. Gợi ý language được chấp nhận nhưng không ảnh hưởng đến ước tính.

Ước tính thành công trả về HTTP 200 với estimate: true, charged: false, mode, realtime, durationSeconds, billedSeconds, pricePerMinuteUsd và costUsd nằm trong data. Ước tính dùng thời lượng trong siêu dữ liệu của tệp, trong khi tác vụ hoàn tất được tính phí theo thời lượng sau giải mã, nên hai giá trị có thể khác nhau. Ước tính áp dụng cùng bước kiểm tra tệp như khi gửi. Chỉ dùng được khi chép lời trả phí được bật (nếu không sẽ trả về 503 paid_transcription_not_enabled). Có thể trả về 429 audio_validation_busy khi công suất kiểm tra tệp đã đầy; đợi một chút rồi thử lại.

Đọc bản chép lời

Thăm dò GET /v3/speech_to_text/JOB_ID theo mô tả trong hướng dẫn quy trình tác vụ. Đối tượng tác vụ chứa các trường sau:

TrườngÝ nghĩa
idUUID của tác vụ.
statusqueued, running, completed, failed hoặc awaiting_payment.
progressPhần trăm từ 0 đến 99 khi đang chạy, nếu có; 100 khi hoàn tất; nếu không là null.
durationSeconds, billedSecondsThời lượng âm thanh và số giây nguyên được tính phí. Đây là ước tính từ siêu dữ liệu khi tác vụ đang chờ hoặc đang chạy; dùng thời lượng sau giải mã khi đã hoàn tất hoặc đang chờ thanh toán.
costUsd, costIsEstimateChi phí bằng đô la Mỹ, dưới dạng chuỗi thập phân có chín chữ số sau dấu thập phân. costIsEstimate là true khi tác vụ đang chờ hoặc đang chạy. Tác vụ thất bại không bị tính phí, dù costUsd vẫn hiển thị ước tính.
pricePerMinuteUsd0.005 cho tác vụ API và 0.000 cho tác vụ ghi âm Hosted PBX miễn phí.
failureCodeVới tác vụ thất bại: decode_failed (không giải mã được âm thanh, chẳng hạn do có hơn hai kênh hoặc dài hơn 2 giờ sau giải mã), inference_timeout (xử lý quá lâu), service_error hoặc worker_lease_lost (xử lý bị gián đoạn). Các mã unsupported_audio và quality_check_failed cũng được định nghĩa. Tác vụ chờ thanh toán hiển thị insufficient_balance, mã này có thể vẫn còn sau khi thanh toán.
source, modelVersion, createdAtsource là api với lượt gửi API, hoặc hpbx với tác vụ ghi âm Hosted PBX của tài khoản. modelVersion là chuỗi phiên bản xử lý nội bộ, không dùng để diễn giải. createdAt là thời điểm gửi.
duplicatetrue trên phản hồi trả về tác vụ hiện có.
resultChỉ có khi status là completed.
Trường kết quảÝ nghĩa
textToàn bộ bản chép lời: văn bản của mọi đoạn được nối bằng dấu xuống dòng, theo thứ tự đoạn.
segmentsMảng các đoạn theo thứ tự thời gian bắt đầu. Mỗi đoạn bao phủ một phần âm thanh dài tối đa khoảng 29 giây. start và end của đoạn (số giây tính từ đầu âm thanh) đánh dấu phần đó, không phải từng từ hay câu; các phần liên tiếp có thể chồng lấn tối đa 1 giây. Mỗi đoạn cũng có text và language (mã ngôn ngữ, có thể rỗng), cùng channel cho kết quả hai kênh.
channelCount1 hoặc 2. Có trong kết quả hiện tại; kết quả cũ có thể bỏ qua.
audioDurationMsThời lượng sau giải mã tính bằng mili giây. Khi tính phí, giá trị được làm tròn lên số giây nguyên.
qualityFlagsRỗng, hoặc review_recommended cùng với repetition_detected (một cụm từ lặp lại thường xuyên bất thường trong một phần), no_speech (không có lời nói nào được chép lại), hoặc cả hai.
pipelineVersionCó thể xuất hiện. Mã định danh xử lý nội bộ, không dùng để diễn giải.

Bản chép lời, dấu thời gian, nhãn ngôn ngữ và nhãn kênh được tạo tự động và không được bảo đảm chính xác. Hãy coi mọi cờ chất lượng là lý do để rà soát kết quả và đối chiếu tên, số liệu, cam kết quan trọng với âm thanh gốc. Khoảng im lặng dài và phần có âm lượng rất nhỏ được bỏ qua, không tạo đoạn. Kết quả không nhận diện từng người nói. Khi kết quả báo channelCount là 2, mỗi đoạn có channel là A (kênh đầu tiên, hay kênh trái) hoặc B (kênh thứ hai, hay kênh phải). Cách này chỉ tách người nói khi mỗi người được ghi trên một kênh riêng. Âm thanh hai kênh được tính phí một lần theo thời lượng trôi qua, không tính theo từng kênh. Kết quả mono không có nhãn kênh.

Dùng api.multitel.net

Điểm cuối tương thích POST https://api.multitel.net/v3/speech_to_text chấp nhận multipart/form-data với phần tệp audio và trường language không bắt buộc, thay vì JSON audioBase64. Giá trị language rỗng được coi là không có gợi ý. Gửi cùng tiêu đề Idempotency-Key. Nếu không có tiêu đề, máy chủ này cũng chấp nhận trường biểu mẫu idempotency_key. Các trường có tên source, free, billing_source, realtime hoặc stream bị từ chối với 400 unsupported_transcription_option; các trường biểu mẫu khác bị bỏ qua. Máy chủ này cũng trả về các lỗi sau:

  • 400 idempotency_key_required khi thiếu khóa hoặc khóa quá dài.
  • 400 audio_upload_required khi thiếu tệp tải lên hoặc chưa nhận đủ tệp.
  • 400 invalid_language khi ngôn ngữ không hợp lệ.
  • 413 invalid_audio_size khi tệp rỗng hoặc quá lớn.
  • 400 invalid_job khi ID tác vụ sai định dạng.

Phản hồi từ dịch vụ chuyển giọng nói thành văn bản của máy chủ này dùng cấu trúc bao ngoài {"status":{"code":HTTP_STATUS},"response":{...}}. Lưu ý status là đối tượng, không phải chuỗi. Khi thành công, response chứa cùng đối tượng như data trên máy chủ chính, nên ID tác vụ là response.id. Khi có lỗi, response.code chứa mã lỗi; không có thông điệp hoặc ID yêu cầu. Lỗi xác thực (401) do bước kiểm tra đăng nhập chung của máy chủ trả về và có thể có nội dung khác, vì vậy hãy kiểm tra trạng thái HTTP trước khi phân tích. Không dùng lẫn mã hóa tải lên hoặc bộ phân tích phản hồi giữa các máy chủ.

Để ước tính trên máy chủ này, POST cùng các trường multipart đến /v3/speech_to_text/estimate. Không cần khóa lũy đẳng, và ước tính nằm trong response.

API_USER="your-api-username"
API_PASSWORD="your-api-password"

curl --fail-with-body --silent --show-error --user "$API_USER:$API_PASSWORD" \
  -H "Idempotency-Key: speech-call-001" \
  -F "audio=@completed-call.mp3" -F "language=en" \
  -o speech-job.json \
  https://api.multitel.net/v3/speech_to_text

node -p 'JSON.parse(require("node:fs").readFileSync("speech-job.json","utf8")).response.id'