ডেভেলপার

কথা থেকে লেখা তৈরির API

উভয় API সার্ভারে সারিবদ্ধ কাজ, বিনামূল্যের খরচের হিসাব, আইডেমপোটেন্ট জমা ও ব্যবহার পর্যবেক্ষণ দিয়ে সম্পূর্ণ অডিও ফাইল থেকে লেখা তৈরি করুন।

এই পৃষ্ঠায়
  1. এন্ডপয়েন্ট
  2. অডিও ফাইল প্রস্তুত করুন
  3. কথা থেকে লেখা তৈরির কাজ জমা দিন
  4. আইডেমপোটেন্সি কী
  5. কাজ তৈরি না করে খরচের হিসাব নিন
  6. তৈরি হওয়া লেখা পড়ুন
  7. api.multitel.net ব্যবহার

এই API সম্পূর্ণ অডিও ফাইল থেকে লেখা তৈরি করে সারিবদ্ধ কাজ হিসেবে। ফাইল জমা দিন, ফেরত পাওয়া কাজের ID রেখে দিন এবং প্রক্রিয়াকরণ শেষ হওয়া পর্যন্ত কাজের তথ্য আনুন। প্রতিটি অনুরোধ HTTPS দিয়ে আপনার অ্যাকাউন্টের লগইন তথ্যসহ পাঠান: উদাহরণে দেখানো HTTP Basic লগইন তথ্য বা API টোকেন ব্যবহার করে, যেমন প্রমাণীকরণ অংশে বলা হয়েছে। লগইন তথ্য আপনার সার্ভারেই রাখুন।

এন্ডপয়েন্ট

দুটি API সার্ভার, https://api.multi.tel এবং সামঞ্জস্যের জন্য রাখা সার্ভার https://api.multitel.net, একই অ্যাকাউন্টের আওতাধীন কাজ, আইডেমপোটেন্সি কী, সীমা ও বিলিং ভাগ করে নেয়। আপলোডের এনকোডিং এবং প্রতিক্রিয়ার বাইরের কাঠামো আলাদা, তাই উপযুক্ত প্রতিক্রিয়া বিশ্লেষকসহ ধারাবাহিকভাবে একই সার্ভার ব্যবহার করুন।

অপারেশনমেথড ও পাথ
সেবার তথ্যGET /v3/speech_to_text
কাজ জমা দিনPOST /v3/speech_to_text
কাজ তৈরি না করে খরচের হিসাব নিনPOST /v3/speech_to_text/estimate
কাজের তথ্য পড়ুনGET /v3/speech_to_text/JOB_ID
পেমেন্টের অপেক্ষায় থাকা কাজের পেমেন্ট নিষ্পত্তি করুনPOST /v3/speech_to_text/JOB_ID/settle
ব্যবহারGET /v3/speech_to_text/usage

সার্ভার api.multi.tel-এ প্রতিটি পাথের জন্য এই বিকল্প প্রিফিক্সও ব্যবহার করা যায়: /v1/speech-to-text; এটি যে প্রিফিক্সের পরিবর্তে বসবে তা হলো /v3/speech_to_text; উদাহরণস্বরূপ POST /v1/speech-to-text/estimate। সার্ভার api.multitel.net-এ ব্যবহার করুন এই পাথগুলি: /v3/speech_to_text।

সেবার তথ্যের প্রতিক্রিয়ায় থাকে mode (batch), realtime (false), paidEnabled (বর্তমানে নতুন অর্থপ্রদত্ত কাজ জমা নেওয়া হচ্ছে কি না), pricePerMinuteUsd (0.005), billingUnit (audio_second), maxAudioSeconds (7200) এবং maxUploadBytes (26214400), সঙ্গে একটি সংক্ষিপ্ত description। এই তথ্য পড়া বিনামূল্যে এবং অর্থপ্রদত্ত কাজ জমা দেওয়া বন্ধ থাকলেও কাজ করে; কেবল পুরো সেবাটি অনুপলব্ধ থাকলেই 503 transcription_unavailable ফেরত আসে।

অডিও ফাইল প্রস্তুত করুন

সর্বোচ্চ 25 MiB (26,214,400 বাইট) এবং সর্বোচ্চ 2 ঘণ্টার (7,200 সেকেন্ড) একটি সম্পূর্ণ অডিও ফাইল ব্যবহার করুন। জমা দেওয়ার সময় ফাইলটি অডিও স্ট্রিমযুক্ত MP3, WAV, Ogg, FLAC, MOV বা Matroska মিডিয়া হিসেবে শনাক্ত হতে হবে, এবং তার মেটাডেটায় সময়কাল শূন্যের বেশি ও সর্বোচ্চ 7,200 সেকেন্ড হতে হবে। শনাক্ত হওয়া ফাইল এই পরীক্ষাগুলিতে ব্যর্থ হলে 422 unsupported_audio দিয়ে প্রত্যাখ্যাত হয়। এই ফরম্যাটগুলির কোনোটিতেই পড়া যায় না এমন ফাইলের ক্ষেত্রে বর্তমানে সার্ভারের ত্রুটি (500) ফেরত আসতে পারে; এমন ফাইল অপরিবর্তিত অবস্থায় আবার জমা দেবেন না। শুধু ফাইলের এক্সটেনশন দিয়ে সামঞ্জস্য নিশ্চিত হয় না।

এই পরীক্ষাগুলিতে উত্তীর্ণ হলেও অডিও ডিকোড করা যাবে তার নিশ্চয়তা নেই। অডিও এক বা দুই চ্যানেলে প্রক্রিয়াকরণ করা হয়। দুইয়ের বেশি অডিও চ্যানেলযুক্ত ফাইল, ডিকোড করার পরে 2 ঘণ্টার বেশি দীর্ঘ অডিও, অথবা প্রক্রিয়াকরণের সময় অন্য কোনো কারণে ডিকোডে ব্যর্থ ফাইলের কাজের শেষ অবস্থা হয় failed; সাধারণত ত্রুটি হয় decode_failed, এবং কোনো চার্জ নেওয়া হয় না। জমা দেওয়ার আগে একাধিক চ্যানেলের অডিও মোনো বা স্টেরিওতে রূপান্তর করুন।

ঐচ্ছিক ভাষার ইঙ্গিত হলো কথ্য ভাষার জন্য ছোট হাতের দুই বা তিন অক্ষরের কোড, যেমন en। কোনো ইঙ্গিত না দিতে চাইলে ফিল্ডটি বাদ দিন; api.multi.tel খালি স্ট্রিং প্রত্যাখ্যান করে। ইঙ্গিতটি প্রক্রিয়াকরণে সহায়তা করে, তবে সমর্থিত ভাষার তালিকার সঙ্গে মিলিয়ে পরীক্ষা করা হয় না, তাই কথ্য ভাষার সঠিক কোড ব্যবহার করুন।

কথা থেকে লেখা তৈরির কাজ জমা দিন

JSON পাঠান এই হেডারসহ: Content-Type: application/json; গন্তব্য POST https://api.multi.tel/v3/speech_to_text। অনুরোধের বডি সর্বোচ্চ 35 MiB হতে পারে, যাতে base64 এনকোডিংয়ের পরে সর্বোচ্চ আকারের ফাইলও ধরে; এর চেয়ে বড় বডি 413 দিয়ে প্রত্যাখ্যাত হয়।

ফিল্ডঅর্থ
audioBase64আবশ্যক। সম্পূর্ণ ফাইলটি প্রচলিত base64-এ (A–Z, a–z, 0–9, +, /), প্রয়োজনে = প্যাডিংসহ। data-URL প্রিফিক্স, লাইন ব্রেক বা স্পেস যোগ করবেন না এবং URL-safe বর্ণমালা ব্যবহার করবেন না। মানটি ডিকোড করলে 1 বাইট থেকে 25 MiB আকারের হতে হবে এবং আবার এনকোড করলে হুবহু একই লেখা হতে হবে।
languageউপরে বর্ণিত ঐচ্ছিক ভাষার ইঙ্গিত।

অন্য যেকোনো JSON প্রপার্টি, যেমন idempotency_key, দিলে 400 invalid_transcription_request দিয়ে প্রত্যাখ্যান করা হয়। কীটি হেডার হিসেবে পাঠান।

আইডেমপোটেন্সি কী

প্রতিবার জমা দেওয়ার সময় প্রয়োজন একটি Idempotency-Key হেডার, যার দৈর্ঘ্য 1 থেকে 190 অক্ষর। ASCII অক্ষর, সংখ্যা, -, _, . ও : ব্যবহার করুন, শুরু বা শেষে স্পেস ছাড়া: সামঞ্জস্যের সার্ভারটি চারপাশের হোয়াইটস্পেস বাদ দেয় এবং কীটির দৈর্ঘ্য বাইটে মাপে, তাই অন্য অক্ষর দুই সার্ভারে ভিন্নভাবে গণনা হতে পারে। কী না থাকলে বা 191 বা তার বেশি অক্ষরের হলে 400 দিয়ে প্রত্যাখ্যান করা হয়।

কীগুলি আপনার অ্যাকাউন্ট এবং কথা থেকে লেখা সেবার আওতায় থাকে, উভয় সার্ভার ও আপনার অ্যাকাউন্টের সব লগইন তথ্য জুড়ে। একই কী দিয়ে একই ফাইল ও ভাষা আবার পাঠালে বিদ্যমান কাজটি HTTP 200 এবং duplicate: true সহ ফেরত আসে, তার অবস্থা যা-ই হোক এবং কাজ তৈরির পরে প্রক্রিয়াকরণ হালনাগাদ হলেও, আর কোনো চার্জ ছাড়া। একই কী ভিন্ন ফাইল বা ভাষার সঙ্গে ব্যবহার করলে 409 idempotency_conflict ফেরত আসে। একই ফাইল হলেও নতুন কী নতুন কাজ তৈরি করে, যার প্রক্রিয়াকরণ সফলভাবে শেষ হলে আলাদা চার্জ নেওয়া হয়।

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'

নতুন কাজ নিচে দেখানো ফিল্ডসহ HTTP 202 ফেরত দেয়, আর একই অনুরোধ আবার পাঠালে HTTP 200-এর সঙ্গে এই অংশে বর্ণিত সম্পূর্ণ কাজের অবজেক্ট ফেরত আসে: তৈরি হওয়া লেখা পড়ুন। কাজের ID, অর্থাৎ UUID, পড়ুন এই ফিল্ড থেকে: data.id। নতুন কাজের প্রতিক্রিয়া এমন হয় (শনাক্তকারী ও মানগুলি উদাহরণ):

{
  "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"
  }
}

কাজ সারিতে থাকলে বা চলমান থাকলে durationSeconds, billedSeconds ও costUsd ফাইলের মেটাডেটা থেকে নেওয়া আনুমানিক মান। চূড়ান্ত চার্জ ডিকোড করা সময়কালের ভিত্তিতে হয়।

জমা দেওয়ার প্রতিক্রিয়ায় আরও আসতে পারে 402 insufficient_balance যখন প্রিপেইড ব্যালান্স দিয়ে অন্য অসমাপ্ত কাজসহ এই কাজের খরচ মেটানো যায় না, 429 transcription_queue_full যখন আপনার অ্যাকাউন্ট বা সেবায় অনেক বেশি অসমাপ্ত কাজ থাকে, 429 audio_validation_busy যখন ফাইল যাচাইয়ের ক্ষমতা পূর্ণ থাকে, এবং 503 paid_transcription_not_enabled যখন অর্থপ্রদত্ত কথা থেকে লেখা সেবা বন্ধ থাকে। 429 ও 503 প্রতিক্রিয়ার পরে একই কী দিয়ে পরে চেষ্টা করুন।

কাজ তৈরি না করে খরচের হিসাব নিন

একই JSON বডি পাঠান এই ঠিকানায়: POST https://api.multi.tel/v3/speech_to_text/estimate। আইডেমপোটেন্সি কী লাগে না। হিসাব নেওয়ার সময় ফাইল যাচাই ও পরিমাপ করা হয়, কিন্তু লেখা তৈরি, কাজ তৈরি, অর্থ সংরক্ষণ, ব্যালান্স পরীক্ষা বা অ্যাকাউন্টে চার্জ করা হয় না। language ইঙ্গিত গ্রহণ করা হয়, তবে তা হিসাবকে প্রভাবিত করে না।

সফল হিসাবের প্রতিক্রিয়ায় HTTP 200-এর সঙ্গে estimate: true, charged: false, mode, realtime, durationSeconds, billedSeconds, pricePerMinuteUsd ও costUsd এই ফিল্ডের মধ্যে থাকে: data। ফাইলের মেটাডেটার সময়কাল দিয়ে হিসাব করা হয়, কিন্তু সম্পূর্ণ কাজের চার্জ ডিকোড করা সময়কালের ভিত্তিতে হয়, যা ভিন্ন হতে পারে। হিসাব নেওয়ার সময়ও কাজ জমা দেওয়ার মতো একই ফাইল পরীক্ষা প্রযোজ্য। অর্থপ্রদত্ত কথা থেকে লেখা সেবা চালু থাকলেই হিসাব পাওয়া যায় (অন্যথায় 503 paid_transcription_not_enabled)। ফাইল যাচাইয়ের ক্ষমতা পূর্ণ থাকলে 429 audio_validation_busy আসতে পারে; অল্প অপেক্ষার পরে আবার চেষ্টা করুন।

তৈরি হওয়া লেখা পড়ুন

বারবার তথ্য আনুন এই এন্ডপয়েন্ট থেকে: GET /v3/speech_to_text/JOB_ID, যেমন বলা হয়েছে এই অংশে: কাজের প্রবাহের নির্দেশিকা। কাজের অবজেক্টে এই ফিল্ডগুলি থাকে:

ফিল্ডঅর্থ
idকাজের UUID।
statusqueued, running, completed, failed বা awaiting_payment।
progressচলমান অবস্থায়, পাওয়া গেলে 0 থেকে 99 শতাংশ; সম্পূর্ণ হলে 100; অন্যথায় null।
durationSeconds, billedSecondsঅডিওর সময়কাল এবং বিলের জন্য পূর্ণ সেকেন্ড। কাজ সারিতে থাকলে বা চলমান থাকলে এগুলি মেটাডেটা থেকে আনুমানিক মান, এবং সম্পূর্ণ হলে বা পেমেন্টের অপেক্ষায় থাকলে ডিকোড করা সময়কাল ব্যবহৃত হয়।
costUsd, costIsEstimateমার্কিন ডলারে খরচ, দশমিকের পরে নয় ঘরযুক্ত দশমিক স্ট্রিং হিসেবে। costIsEstimate হলো true যখন কাজ সারিতে বা চলমান থাকে। ব্যর্থ কাজে চার্জ হয় না, যদিও তার costUsd তখনও আনুমানিক খরচ দেখায়।
pricePerMinuteUsd0.005 API কাজের জন্য, এবং 0.000 বিনামূল্যের Hosted PBX রেকর্ডিং কাজের জন্য।
failureCodeব্যর্থ কাজের জন্য: decode_failed (অডিও ডিকোড করা যায়নি, যেমন দুইয়ের বেশি চ্যানেল থাকলে বা ডিকোডের পরে 2 ঘণ্টার বেশি দীর্ঘ হলে), inference_timeout (প্রক্রিয়াকরণে অতিরিক্ত সময় লেগেছে), service_error বা worker_lease_lost (প্রক্রিয়াকরণ বাধাগ্রস্ত হয়েছে)। এই কোডগুলিও সংজ্ঞায়িত আছে: unsupported_audio ও quality_check_failed। পেমেন্টের অপেক্ষায় থাকা কাজ দেখায় insufficient_balance, যা পেমেন্ট নিষ্পত্তির পরেও থাকতে পারে।
source, modelVersion, createdAtsource হলো api API দিয়ে জমা দেওয়া কাজের জন্য, অথবা hpbx আপনার অ্যাকাউন্টের Hosted PBX রেকর্ডিং কাজের জন্য। modelVersion প্রক্রিয়াকরণ সংস্করণের একটি অস্বচ্ছ স্ট্রিং। createdAt জমা দেওয়ার সময়।
duplicatetrue বিদ্যমান কাজ ফেরত দেওয়া প্রতিক্রিয়ায় থাকে।
resultকেবল তখনই থাকে যখন status হলো completed।
ফলাফলের ফিল্ডঅর্থ
textসম্পূর্ণ তৈরি হওয়া লেখা: সব অংশের লেখা অংশের ক্রমে লাইন ব্রেক দিয়ে যুক্ত করা।
segmentsশুরুর সময় অনুযায়ী সাজানো অংশগুলির অ্যারে। প্রতিটি অংশ প্রায় সর্বোচ্চ 29 সেকেন্ড দীর্ঘ অডিওর একটি অংশকে অন্তর্ভুক্ত করে। তার start ও end (অডিওর শুরু থেকে সেকেন্ডে) ওই অংশ চিহ্নিত করে, আলাদা শব্দ বা বাক্য নয়, এবং পরপর অংশগুলির মধ্যে সর্বোচ্চ 1 সেকেন্ড ওভারল্যাপ হতে পারে। প্রতিটি অংশে আরও থাকে text ও language (ভাষার কোড, যা খালি হতে পারে), এবং দুই চ্যানেলের ফলাফলে থাকে channel।
channelCount1 অথবা 2। বর্তমান ফলাফলে থাকে; পুরোনো ফলে নাও থাকতে পারে।
audioDurationMsমিলিসেকেন্ডে ডিকোড করা সময়কাল। বিলিংয়ের জন্য পূর্ণ সেকেন্ডে ঊর্ধ্বমুখী রাউন্ড করা হয়।
qualityFlagsখালি, অথবা review_recommended এর সঙ্গে repetition_detected (কোনো অংশে একটি বাক্যাংশ অস্বাভাবিকভাবে বারবার আসে), no_speech (কোনো কথা লেখা হিসেবে তৈরি হয়নি), অথবা উভয়ই।
pipelineVersionথাকতে পারে। প্রক্রিয়াকরণের একটি অস্বচ্ছ শনাক্তকারী।

তৈরি হওয়া লেখা এবং তার টাইমস্ট্যাম্প, ভাষার লেবেল ও চ্যানেলের লেবেল স্বয়ংক্রিয়ভাবে তৈরি হয় এবং সঠিক হওয়ার নিশ্চয়তা নেই। যেকোনো গুণমানের সংকেত দেখলে ফল পর্যালোচনা করুন এবং গুরুত্বপূর্ণ নাম, সংখ্যা ও প্রতিশ্রুতি মূল অডিওর সঙ্গে মিলিয়ে নিন। দীর্ঘ নীরবতা এবং খুব নিচু শব্দের অংশ বাদ যায়, তাই সেগুলির জন্য কোনো অংশ তৈরি হয় না। ফলাফল আলাদা বক্তা শনাক্ত করে না। কোনো ফলাফলে channelCount এর মান 2 হলে প্রতিটি অংশে channel এর মান থাকে A (প্রথম বা বাম চ্যানেল) অথবা B (দ্বিতীয় বা ডান চ্যানেল)। প্রত্যেক বক্তাকে আলাদা চ্যানেলে রেকর্ড করা হলেই কেবল এভাবে বক্তাদের আলাদা করা যায়। দুই চ্যানেলের অডিওতে অতিবাহিত সময়কালের জন্য একবারই বিল হয়, প্রতি চ্যানেলের জন্য নয়। মোনো ফলাফলে চ্যানেলের লেবেল থাকে না।

api.multitel.net ব্যবহার

সামঞ্জস্যের জন্য রাখা এন্ডপয়েন্ট POST https://api.multitel.net/v3/speech_to_text গ্রহণ করে multipart/form-data, যার মধ্যে থাকে একটি audio ফাইল অংশ এবং ঐচ্ছিক language ফিল্ড, JSON-এর audioBase64 ফিল্ডের পরিবর্তে। খালি language মানকে কোনো ইঙ্গিত নেই বলে ধরা হয়। একই Idempotency-Key হেডার পাঠান। হেডার না থাকলে এই সার্ভার একটি idempotency_key ফর্ম ফিল্ডও গ্রহণ করে। এই নামের ফিল্ডগুলি: source, free, billing_source, realtime বা stream দিলে 400 unsupported_transcription_option দিয়ে প্রত্যাখ্যান করা হয়; অন্য ফর্ম ফিল্ড উপেক্ষা করা হয়। এই সার্ভার আরও এই ত্রুটিগুলি ফেরত দেয়:

  • 400 idempotency_key_required কী না থাকলে বা অতিরিক্ত দীর্ঘ হলে।
  • 400 audio_upload_required আপলোড না থাকলে বা সম্পূর্ণভাবে না পৌঁছালে।
  • 400 invalid_language ভাষা অবৈধ হলে।
  • 413 invalid_audio_size ফাইল খালি বা অতিরিক্ত বড় হলে।
  • 400 invalid_job ভুলভাবে গঠিত কাজের ID-এর জন্য।

এই সার্ভারের কথা থেকে লেখা সেবার প্রতিক্রিয়া এই বাইরের কাঠামো ব্যবহার করে: {"status":{"code":HTTP_STATUS},"response":{...}}। লক্ষ করুন, status একটি অবজেক্ট, স্ট্রিং নয়। সফল হলে response একই অবজেক্ট ধারণ করে, যা প্রধান সার্ভারে থাকে data ফিল্ডে, তাই কাজের ID হলো response.id। ত্রুটি হলে response.code ত্রুটির কোড ধারণ করে; কোনো বার্তা বা অনুরোধের ID থাকে না। প্রমাণীকরণ ব্যর্থতা (401) সার্ভারের সাধারণ সাইন-ইন পরীক্ষা থেকে ফেরত আসে এবং বডি আলাদা হতে পারে, তাই বিশ্লেষণের আগে HTTP স্ট্যাটাস পরীক্ষা করুন। দুই সার্ভারের আপলোড এনকোডিং বা প্রতিক্রিয়া বিশ্লেষক অদলবদল করবেন না।

এই সার্ভারে হিসাব নিতে একই multipart ফিল্ড POST করুন এই পাথে: /v3/speech_to_text/estimate। আইডেমপোটেন্সি কী লাগে না, এবং হিসাবটি থাকে 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'