स्पीच टू टेक्स्ट API: पायथन, नोड और स्ट्रीमिंग के लिए एकीकरण गाइड

स्पीच टू टेक्स्ट API: पायथन, नोड और स्ट्रीमिंग के लिए एकीकरण गाइड

एक उच्च बेंचमार्क स्कोर का मतलब यह नहीं है कि आपके उपयोगकर्ताओं के ऑडियो पर विश्वसनीय ट्रांसक्रिप्शन मिलेगा। पल्स एसटीटी (Pulse STT) को सही तरीके से एकीकृत करने का तरीका यहाँ दिया गया है।

एक स्पीच टू टेक्स्ट एपीआई (speech to text api) जो साफ बेंचमार्क ऑडियो पर अच्छा स्कोर करती है और एक स्पीच टू टेक्स्ट एपीआई जो आपके यूजर्स की वास्तविक रिकॉर्डिंग्स पर मजबूती से काम करती है, अक्सर दोनों एक ही चीज नहीं होती हैं। उनके बीच का अंतर आमतौर पर मॉडल नहीं होता है। यह ऑडियो की स्थितियां, भाषा, सैंपल रेट, आपके द्वारा चुना गया मोड और यह है कि क्या आपका रिस्पांस हैंडलर सही फील्ड को पढ़ रहा है।
यह गाइड इन सभी को कवर करती है। पाइथन (Python) और नोड (Node) से Pulse स्पीच टू टेक्स्ट एपीआई को कैसे कॉल करें, बैच और रियल-टाइम स्ट्रीमिंग मोड्स में रिस्पांस को सही तरीके से कैसे संभालें, वास्तविक दुनिया के ऑडियो के साथ सटीकता कैसे बदलती है, और इंटीग्रेशन को प्रोडक्शन में ले जाने से पहले क्या जांचना चाहिए।

Pulse स्पीच टू टेक्स्ट एपीआई क्या है

Pulse, Smallest AI का स्पीच रिकग्निशन मॉडल है। यह ऑडियो को दो मोड्स के माध्यम से टेक्स्ट में बदलता है: प्री-रिकॉर्डेड और रियल-टाइम।

प्री-रिकॉर्डेड ट्रांसक्रिप्शन ऑडियो फाइलों को स्वीकार करता है और एक सिंगल सिंक्रोनस HTTP रिस्पांस में पूरा ट्रांसक्रिप्ट वापस करता है। यह बैच प्रोसेसिंग, आर्काइव की गई रिकॉर्डिंग्स और किसी भी ऐसे वर्कफ़्लो के लिए सही विकल्प है जहां आप पूरे परिणाम का इंतजार कर सकते हैं।

रियल-टाइम ट्रांसक्रिप्शन एक परसिस्टेंट वेबसॉकेट (WebSocket) कनेक्शन पर ऑडियो को स्ट्रीम करता है और मॉडल द्वारा आने वाले ऑडियो को प्रोसेस करने के साथ आंशिक और अंतिम ट्रांसक्रिप्ट इवेंट वापस करता है। यह वॉयस एजेंट्स, लाइव कैप्शनिंग और फोन कॉल एनालिसिस के लिए सही विकल्प है जहां वक्ता के बोलना बंद करने से पहले ट्रांसक्रिप्ट का पहुंचना जरूरी होता है।

दोनों मोड्स एक ही बेस URL शेयर करते हैं। प्री-रिकॉर्डेड रिक्वेस्ट HTTPS POST के रूप में https://api.smallest.ai/waves/v1/pulse/get_text पर जाती हैं। रियल-टाइम रिक्वेस्ट वेबसॉकेट के रूप में wss://api.smallest.ai/waves/v1/pulse/get_text से कनेक्ट होती हैं।

ऑथेंटिकेशन

Smallest AI कंसोल से एक API की (key) प्राप्त करें।



export SMALLEST_API_KEY="your-api-key-here"
export SMALLEST_API_KEY="your-api-key-here"
export SMALLEST_API_KEY="your-api-key-here"

प्रत्येक रिक्वेस्ट ऑथराइजेशन हेडर (Authorization header) में यह की (key) ले जाती है।



पाइथन में प्री-रिकॉर्डेड ट्रांसक्रिप्शन

प्री-रिकॉर्डेड एंडपॉइंट रिक्वेस्ट बॉडी में रॉ ऑडियो बाइट्स लेता है। भाषा और कोई भी वैकल्पिक फीचर्स क्वेरी पैरामीटर्स के रूप में जाते हैं। Content-Type हेडर एपीआई को बताता है कि उसे किस तरह का ऑडियो मिल रहा है।



import os
import requests
<p>def transcribe(file_path: str, language: str = "en") -> dict:<br>with open(file_path, "rb") as f:<br>audio_data = f.read()</p>
<pre><code>response = requests.post(
    "https://api.smallest.ai/waves/v1/pulse/get_text",
    params={
        "language": language,
        "word_timestamps": "true",
    },
    headers={
        "Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",
        "Content-Type": "audio/wav",
    },
    data=audio_data,
)
import os
import requests
<p>def transcribe(file_path: str, language: str = "en") -> dict:<br>with open(file_path, "rb") as f:<br>audio_data = f.read()</p>
<pre><code>response = requests.post(
    "https://api.smallest.ai/waves/v1/pulse/get_text",
    params={
        "language": language,
        "word_timestamps": "true",
    },
    headers={
        "Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",
        "Content-Type": "audio/wav",
    },
    data=audio_data,
)
import os
import requests
<p>def transcribe(file_path: str, language: str = "en") -> dict:<br>with open(file_path, "rb") as f:<br>audio_data = f.read()</p>
<pre><code>response = requests.post(
    "https://api.smallest.ai/waves/v1/pulse/get_text",
    params={
        "language": language,
        "word_timestamps": "true",
    },
    headers={
        "Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",
        "Content-Type": "audio/wav",
    },
    data=audio_data,
)

एक बात तुरंत ध्यान देने योग्य है: रिस्पांस फील्ड transcription है, न कि transcript। यह अंतर तब मायने रखता है जब आप रिस्पांस हैंडलर बना रहे होते हैं। एक सफल रिस्पांस इस तरह दिखता है।



{<br>"status": "success",<br>"transcription": "Hello, this is a test transcription.",<br>"words": [<br>{"start": 0.48, "end": 1.12, "word": "Hello,"},<br>{"start": 1.12, "end": 1.28, "word": "this"},<br>{"start": 1.28, "end": 1.44, "word": "is"},<br>{"start": 1.44, "end": 2.16, "word": "a"},<br>{"start": 2.16, "end": 2.96, "word": "test"},<br>{"start": 2.96, "end": 3.76, "word": "transcription."}<br>],<br>"utterances": [<br>{"start": 0.48, "end": 3.76, "text": "Hello, this is a test transcription."}<br>]<br>
{<br>"status": "success",<br>"transcription": "Hello, this is a test transcription.",<br>"words": [<br>{"start": 0.48, "end": 1.12, "word": "Hello,"},<br>{"start": 1.12, "end": 1.28, "word": "this"},<br>{"start": 1.28, "end": 1.44, "word": "is"},<br>{"start": 1.44, "end": 2.16, "word": "a"},<br>{"start": 2.16, "end": 2.96, "word": "test"},<br>{"start": 2.96, "end": 3.76, "word": "transcription."}<br>],<br>"utterances": [<br>{"start": 0.48, "end": 3.76, "text": "Hello, this is a test transcription."}<br>]<br>
{<br>"status": "success",<br>"transcription": "Hello, this is a test transcription.",<br>"words": [<br>{"start": 0.48, "end": 1.12, "word": "Hello,"},<br>{"start": 1.12, "end": 1.28, "word": "this"},<br>{"start": 1.28, "end": 1.44, "word": "is"},<br>{"start": 1.44, "end": 2.16, "word": "a"},<br>{"start": 2.16, "end": 2.96, "word": "test"},<br>{"start": 2.96, "end": 3.76, "word": "transcription."}<br>],<br>"utterances": [<br>{"start": 0.48, "end": 3.76, "text": "Hello, this is a test transcription."}<br>]<br>



words एरे आपको प्रति-शब्द समय (timing) देता है, जो कैप्शन जनरेशन, सबटाइटल ट्रैक्स और कॉन्फिडेंस-आधारित रिव्यू वर्कफ़्लोज़ के लिए उपयोगी है। utterances एरे आपको टाइमिंग के साथ वाक्य-स्तर के सेगमेंट देता है, जो व्यवस्थित कॉल समरी और पठनीय ट्रांसक्रिप्ट के लिए उपयोगी है।

जब आपका ऑडियो पहले से ही किसी सुलभ स्थान पर होस्ट किया गया हो, तो आप रॉ बाइट्स के बजाय एक URL भेज सकते हैं।



import os<br>import requests<p></p><br><p>def transcribe_from_url(audio_url: str, language: str = "en") -> dict:<br>response = requests.post(<br>"<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;",&lt;br&gt;params={"language</a>": language, "word_timestamps": "true"},<br>headers={<br>"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",<br>"Content-Type": "application/json",<br>},<br>json={"url": audio_url},<br>)</p><br><pre><code>response.raise_for_status()<br>return response.json()<br></code></pre>
import os<br>import requests<p></p><br><p>def transcribe_from_url(audio_url: str, language: str = "en") -> dict:<br>response = requests.post(<br>"<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;",&lt;br&gt;params={"language</a>": language, "word_timestamps": "true"},<br>headers={<br>"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",<br>"Content-Type": "application/json",<br>},<br>json={"url": audio_url},<br>)</p><br><pre><code>response.raise_for_status()<br>return response.json()<br></code></pre>
import os<br>import requests<p></p><br><p>def transcribe_from_url(audio_url: str, language: str = "en") -> dict:<br>response = requests.post(<br>"<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;",&lt;br&gt;params={"language</a>": language, "word_timestamps": "true"},<br>headers={<br>"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",<br>"Content-Type": "application/json",<br>},<br>json={"url": audio_url},<br>)</p><br><pre><code>response.raise_for_status()<br>return response.json()<br></code></pre>

यह तब उपयोगी होता है जब ऑडियो फाइलें S3 या Google Cloud Storage जैसे क्लाउड स्टोरेज में मौजूद हों, जहां रॉ बाइट्स भेजने के लिए पहले फाइल को स्थानीय रूप से डाउनलोड करना होगा।

नोड में प्री-रिकॉर्डेड ट्रांसक्रिप्शन

node-fetch का उपयोग करके नोड में यही कॉल इस प्रकार होगी।



const fs = require("fs");<br>const fetch = require("node-fetch");<p></p><br><p>async function transcribe(filePath, language = "en") {<br>const audioData = fs.readFileSync(filePath);</p><br><pre><code>const url = new URL("<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>");<br>url.searchParams.set("language", language);<br>url.searchParams.set("word_timestamps", "true");<p></p>
<p>const response = await fetch(url.toString(), {<br>method: "POST",<br>headers: {<br>Authorization: <code>Bearer ${process.env.SMALLEST_API_KEY}</code>,<br>"Content-Type": "audio/wav",<br>},<br>body: audioData,<br>});</p>
<p>if (!response.ok) {<br>const error = await response.text();<br>throw new Error(<code>Transcription failed: ${error}</code>);<br>}</p>
const fs = require("fs");<br>const fetch = require("node-fetch");<p></p><br><p>async function transcribe(filePath, language = "en") {<br>const audioData = fs.readFileSync(filePath);</p><br><pre><code>const url = new URL("<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>");<br>url.searchParams.set("language", language);<br>url.searchParams.set("word_timestamps", "true");<p></p>
<p>const response = await fetch(url.toString(), {<br>method: "POST",<br>headers: {<br>Authorization: <code>Bearer ${process.env.SMALLEST_API_KEY}</code>,<br>"Content-Type": "audio/wav",<br>},<br>body: audioData,<br>});</p>
<p>if (!response.ok) {<br>const error = await response.text();<br>throw new Error(<code>Transcription failed: ${error}</code>);<br>}</p>
const fs = require("fs");<br>const fetch = require("node-fetch");<p></p><br><p>async function transcribe(filePath, language = "en") {<br>const audioData = fs.readFileSync(filePath);</p><br><pre><code>const url = new URL("<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>");<br>url.searchParams.set("language", language);<br>url.searchParams.set("word_timestamps", "true");<p></p>
<p>const response = await fetch(url.toString(), {<br>method: "POST",<br>headers: {<br>Authorization: <code>Bearer ${process.env.SMALLEST_API_KEY}</code>,<br>"Content-Type": "audio/wav",<br>},<br>body: audioData,<br>});</p>
<p>if (!response.ok) {<br>const error = await response.text();<br>throw new Error(<code>Transcription failed: ${error}</code>);<br>}</p>

और रिमोट URL से।



async function transcribeFromUrl(audioUrl, language = "en") {<br>const url = new URL("<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22);&lt;br&gt;url.searchParams.set(%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22);&lt;br&gt;url.searchParams.set(%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;");&lt;br&gt;url.searchParams.set("language</a>", language);<br>url.searchParams.set("word_timestamps", "true");<p></p><br><pre><code>const response = await fetch(url.toString(), {<br>method: "POST",<br>headers: {<br>Authorization: <code>Bearer ${process.env.SMALLEST_API_KEY}</code>,<br>"Content-Type": "application/json",<br>},<br>body: JSON.stringify({ url: audioUrl }),<br>});<p></p>
<p>if (!response.ok) {<br>const error = await response.text();<br>throw new Error(<code>Transcription failed: ${error}</code>);<br>}</p>
async function transcribeFromUrl(audioUrl, language = "en") {<br>const url = new URL("<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22);&lt;br&gt;url.searchParams.set(%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22);&lt;br&gt;url.searchParams.set(%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;");&lt;br&gt;url.searchParams.set("language</a>", language);<br>url.searchParams.set("word_timestamps", "true");<p></p><br><pre><code>const response = await fetch(url.toString(), {<br>method: "POST",<br>headers: {<br>Authorization: <code>Bearer ${process.env.SMALLEST_API_KEY}</code>,<br>"Content-Type": "application/json",<br>},<br>body: JSON.stringify({ url: audioUrl }),<br>});<p></p>
<p>if (!response.ok) {<br>const error = await response.text();<br>throw new Error(<code>Transcription failed: ${error}</code>);<br>}</p>
async function transcribeFromUrl(audioUrl, language = "en") {<br>const url = new URL("<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22);&lt;br&gt;url.searchParams.set(%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22);&lt;br&gt;url.searchParams.set(%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;");&lt;br&gt;url.searchParams.set("language</a>", language);<br>url.searchParams.set("word_timestamps", "true");<p></p><br><pre><code>const response = await fetch(url.toString(), {<br>method: "POST",<br>headers: {<br>Authorization: <code>Bearer ${process.env.SMALLEST_API_KEY}</code>,<br>"Content-Type": "application/json",<br>},<br>body: JSON.stringify({ url: audioUrl }),<br>});<p></p>
<p>if (!response.ok) {<br>const error = await response.text();<br>throw new Error(<code>Transcription failed: ${error}</code>);<br>}</p>

वैकल्पिक एनरिचमेंट फीचर्स

सभी एनरिचमेंट फीचर्स उसी एंडपॉइंट पर क्वेरी पैरामीटर्स के रूप में काम करते हैं। रिक्वेस्ट के किसी भी अन्य हिस्से को बदले बिना किसी भी संयोजन (combination) को सक्षम करें।



response = requests.post(<br>"<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B&lt;br&gt;%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B&lt;br&gt;%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;",&lt;br&gt;params={&lt;br&gt;"language</a>": "en",<br>"word_timestamps": "true",<br>"emotion_detection": "true",<br>"age_detection": "true",<br>"gender_detection": "true",<br>"diarization": "true",<br>},<br>headers={<br>"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",<br>"Content-Type": "audio/wav",<br>},<br>data=open("call_recording.wav", "rb").read(),<br>)<p></p>
response = requests.post(<br>"<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B&lt;br&gt;%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B&lt;br&gt;%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;",&lt;br&gt;params={&lt;br&gt;"language</a>": "en",<br>"word_timestamps": "true",<br>"emotion_detection": "true",<br>"age_detection": "true",<br>"gender_detection": "true",<br>"diarization": "true",<br>},<br>headers={<br>"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",<br>"Content-Type": "audio/wav",<br>},<br>data=open("call_recording.wav", "rb").read(),<br>)<p></p>
response = requests.post(<br>"<a href="<a href="https://api.smallest.ai/waves/v1/pulse/get_text" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text</a>" data-framer-link="Link:{"url":"<a href="https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B&lt;br&gt;%22language" data-framer-link="Link:{"url":"https://api.smallest.ai/waves/v1/pulse/get_text%22,%22type%22:%22url%22%7D%22&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;%22,&lt;br&gt;params=%7B&lt;br&gt;%22language","type":"url"}">https://api.smallest.ai/waves/v1/pulse/get_text","type":"url"}"&gt;https://api.smallest.ai/waves/v1/pulse/get_text&lt;/a&gt;",&lt;br&gt;params={&lt;br&gt;"language</a>": "en",<br>"word_timestamps": "true",<br>"emotion_detection": "true",<br>"age_detection": "true",<br>"gender_detection": "true",<br>"diarization": "true",<br>},<br>headers={<br>"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}",<br>"Content-Type": "audio/wav",<br>},<br>data=open("call_recording.wav", "rb").read(),<br>)<p></p>

प्रत्येक फीचर के बारे में एक संक्षिप्त जानकारी जिन्हें इनेबल करना फायदेमंद है।

Word timestamps आपको हर शब्द का स्टार्ट और एंड टाइम देते हैं। इसे इनेबल करना सस्ता है और बाद में सटीक रूप से रिकंस्ट्रक्ट करना कठिन होता है। इसे डिफ़ॉल्ट रूप से किसी भी ऐसे उपयोग के मामले के लिए सक्षम करें जहां ट्रांसक्रिप्ट टाइमिंग महत्वपूर्ण हो।

Utterances आपको टाइमिंग के साथ वाक्य-स्तर के सेगमेंट देते हैं। यह कैप्शन डिस्प्ले करने, प्लेबैक सिंक करने और व्यवस्थित बातचीत रिकॉर्ड स्टोर करने के लिए उपयोगी है।

Diarization ट्रांसक्रिप्ट को बोलने वाले के अनुसार अलग-अलग भागों (speaker turns) में विभाजित करता है। कॉल रिकॉर्डिंग्स या मीटिंग ट्रांसक्रिप्ट जैसी बहु-वक्ता (multi-speaker) ऑडियो के लिए, यह टेक्स्ट की एक बड़ी दीवार को एक स्पष्ट बातचीत में बदल देता है।

Emotion detection पांच मूल भावना प्रकारों में तीव्रता संकेतकों के साथ प्रत्येक सेगमेंट का भावनात्मक टोन वापस करता है। कस्टमर सर्विस के संदर्भों में, ग्राहक क्या कहता है और कैसे कहता है, इसके बीच का अंतर अक्सर शब्दों से भी अधिक महत्वपूर्ण होता है।

Age and gender detection प्रति वक्ता जनसांख्यिकीय (demographic) अनुमान प्रदान करते हैं। ये प्रोबेबिलिस्टिक सिग्नल्स हैं जो एग्रीगेट में अच्छा प्रदर्शन करते हैं। व्यक्तिगत परिणामों को तथ्यों के बजाय केवल संकेत के रूप में देखें।

सटीकता, वर्ड एरर रेट (WER) और उन्हें प्रभावित करने वाले कारक

वर्ड एरर रेट (Word Error Rate - WER) ट्रांसक्रिप्शन की सटीकता मापने का मानक पैमाना है। यह आउटपुट में उन शब्दों के प्रतिशत को मापता है जो ओरिजिनल ट्रांसक्रिप्ट से भिन्न होते हैं। 5% WER का मतलब है कि लगभग बीस में से एक शब्द गलत है। साफ स्टूडियो ऑडियो पर, आधुनिक मॉडल आमतौर पर 3 से 5 प्रतिशत का स्कोर प्राप्त करते हैं। वहीं, शोर-शराबे वाले फोन कॉल पर, यही मॉडल 15 से 20 प्रतिशत तक की त्रुटि दिखा सकता है।

वास्तविक दुनिया के ऑडियो में सबसे महत्वपूर्ण कारक हैं बैकग्राउंड नॉइज़ लेवल, वक्ता का उच्चारण (accent), ऑडियो सैंपल रेट और डोमेन-विशिष्ट शब्दावली। आखिरी वाले को अक्सर कम करके आंका जाता है। जो मॉडल सामान्य अंग्रेजी को अच्छी तरह से संभालता है, वह भी मेडिकल शब्दावली, कानूनी भाषा या उन प्रॉडक्ट नामों पर काफी अधिक एरर रेट दे सकता है जो उसके ट्रेनिंग डेटा में शायद ही कभी आए हों।

अपने वास्तविक उपयोगकर्ताओं का प्रतिनिधित्व करने वाले ऑडियो के साथ परीक्षण करना किसी भी प्रकाशित बेंचमार्क की तुलना में अधिक जानकारीपूर्ण है। साफ अंग्रेजी ब्रॉडकास्ट ऑडियो पर 3% का WER आपको यह नहीं बताता कि मॉडल मुंबई या साओ पाउलो से आने वाली कॉल सेंटर रिकॉर्डिंग्स के साथ क्या करेगा।

सैंपल रेट पर: 16kHz से नीचे जाने पर सटीकता明显 रूप से गिरती है। यदि आपकी पाइपलाइन पुराने टेलीफोनी इंफ्रास्ट्रक्चर से 8kHz का ऑडियो जनरेट कर रही है, तो भेजने से पहले इसे 16kHz पर रीसैंपल करना अतिरिक्त ओवरहेड के लायक है।



भाषा समर्थन

language क्वेरी पैरामीटर में ISO 639-1 भाषा कोड पास करें। ऐसे ऑडियो के लिए जहां बोलने वाले बातचीत के बीच में भाषाएं बदलते हैं, ऑटोमैटिक लैंग्वेज डिटेक्शन और स्विचिंग के लिए language=multi का उपयोग करें।

कोड

भाषा

कोड

भाषा

en

अंग्रेजी

hi

हिंदी

de

जर्मन

fr

फ्रेंच

es

स्पैनिश

it

इटैलियन

pt

पुर्तगाली

ru

रूसी

pl

पोलिश

nl

डच

ta

तमिल

bn

बंगाली

gu

गुजराती

kn

कन्नड़

ml

मलयालम

mr

मराठी

te

तेलुगु

pa

पंजाबी

uk

यूक्रेनी

sv

स्वीडिश

fi

फिनिश

da

डेनिष

ro

रोमानियाई

bg

बुल्गारियाई

cs

चेक

sk

स्लोवाक

hu

हंगेरियन

lv

लातवियाई

lt

लिथुआनियाई

et

एस्टोनियाई

mt

माल्टीज़

or

ओड़िया

multi

ऑटो-डिटेक्ट





हाई-रिसोर्स भाषाओं में लो-रिसोर्स भाषाओं की तुलना में कम एरर रेट होते हैं। यदि आपके उपयोगकर्ता किसी विशिष्ट भाषा समुदाय में केंद्रित हैं, तो समग्र WER आंकड़ों के बजाय उस समुदाय के ऑडियो नमूनों के साथ परीक्षण करें।



रियल-टाइम स्ट्रीमिंग ट्रांसक्रिप्शन

बैच ट्रांसक्रिप्शन पूरा होने के बाद परिणाम वापस करने के सिद्धांत पर काम करता है। रियल-टाइम ट्रांसक्रिप्शन ऑडियो के आने के दौरान लगातार परिणाम वापस करने के सिद्धांत पर काम करता है। यह अंतर आपके इसे बनाने के पूरे तरीके को बदल देता है।

रियल-टाइम एपीआई वेबसॉकेट (WebSocket) के माध्यम से wss://api.smallest.ai/waves/v1/pulse/get_text से कनेक्ट होता है। ऑडियो 4096 बाइट्स के रॉ बाइनरी फ्रेम्स के रूप में अंदर जाता है। ट्रांसक्रिप्ट इवेंट्स JSON संदेशों के रूप में वापस आते हैं जिनमें एक is_final फ्लैग होता है जो आपको बताता है कि परिणाम अनंतिम (provisional) है या अंतिम (committed)।

जब आप वेबसॉकेट स्थापित करते हैं तो कनेक्शन पैरामीटर URL क्वेरी पैरामीटर के रूप में जाते हैं।



const API_KEY = process.env.SMALLEST_API_KEY;<p></p><br><p>const url = new URL("wss://api.smallest.ai/waves/v1/pulse/get_text");<br>url.searchParams.append("language", "en");<br>url.searchParams.append("encoding", "linear16");<br>url.searchParams.append("sample_rate", "16000");<br>url.searchParams.append("word_timestamps", "true");</p><br><p>const ws = new WebSocket(url.toString(), {<br>headers: {<br>Authorization: <code>Bearer ${API_KEY}</code>,<br>},<br>});</p><br><p>ws.onopen = () => {<br>console.log("Connected to Pulse STT");<br>};</p><br><p>ws.onmessage = (event) => {<br>const data = JSON.parse(event.data);<br>if (data.is_final) {<br>console.log("\n[FINAL]", data.transcript);<br>console.log("[FULL SESSION]", data.full_transcript);<br>} else {<br>process.stdout.write(<code>\r${data.transcript}</code>);<br>}<br>};</p><br><p>function sendAudioChunk(audioBuffer) {<br>if (ws.readyState === WebSocket.OPEN) {<br>ws.send(audioBuffer);<br>}<br>}</p>
const API_KEY = process.env.SMALLEST_API_KEY;<p></p><br><p>const url = new URL("wss://api.smallest.ai/waves/v1/pulse/get_text");<br>url.searchParams.append("language", "en");<br>url.searchParams.append("encoding", "linear16");<br>url.searchParams.append("sample_rate", "16000");<br>url.searchParams.append("word_timestamps", "true");</p><br><p>const ws = new WebSocket(url.toString(), {<br>headers: {<br>Authorization: <code>Bearer ${API_KEY}</code>,<br>},<br>});</p><br><p>ws.onopen = () => {<br>console.log("Connected to Pulse STT");<br>};</p><br><p>ws.onmessage = (event) => {<br>const data = JSON.parse(event.data);<br>if (data.is_final) {<br>console.log("\n[FINAL]", data.transcript);<br>console.log("[FULL SESSION]", data.full_transcript);<br>} else {<br>process.stdout.write(<code>\r${data.transcript}</code>);<br>}<br>};</p><br><p>function sendAudioChunk(audioBuffer) {<br>if (ws.readyState === WebSocket.OPEN) {<br>ws.send(audioBuffer);<br>}<br>}</p>
const API_KEY = process.env.SMALLEST_API_KEY;<p></p><br><p>const url = new URL("wss://api.smallest.ai/waves/v1/pulse/get_text");<br>url.searchParams.append("language", "en");<br>url.searchParams.append("encoding", "linear16");<br>url.searchParams.append("sample_rate", "16000");<br>url.searchParams.append("word_timestamps", "true");</p><br><p>const ws = new WebSocket(url.toString(), {<br>headers: {<br>Authorization: <code>Bearer ${API_KEY}</code>,<br>},<br>});</p><br><p>ws.onopen = () => {<br>console.log("Connected to Pulse STT");<br>};</p><br><p>ws.onmessage = (event) => {<br>const data = JSON.parse(event.data);<br>if (data.is_final) {<br>console.log("\n[FINAL]", data.transcript);<br>console.log("[FULL SESSION]", data.full_transcript);<br>} else {<br>process.stdout.write(<code>\r${data.transcript}</code>);<br>}<br>};</p><br><p>function sendAudioChunk(audioBuffer) {<br>if (ws.readyState === WebSocket.OPEN) {<br>ws.send(audioBuffer);<br>}<br>}</p>

प्रत्येक इवेंट के रिस्पांस में ये फ़ील्ड होते हैं।



{<br>"session_id": "sess_12345abcde",<br>"transcript": "Hello, how are you?",<br>"full_transcript": "Hello, how are you?",<br>"is_final": true,<br>"is_last": false,<br>"language": "en"<br>
{<br>"session_id": "sess_12345abcde",<br>"transcript": "Hello, how are you?",<br>"full_transcript": "Hello, how are you?",<br>"is_final": true,<br>"is_last": false,<br>"language": "en"<br>
{<br>"session_id": "sess_12345abcde",<br>"transcript": "Hello, how are you?",<br>"full_transcript": "Hello, how are you?",<br>"is_final": true,<br>"is_last": false,<br>"language": "en"<br>

transcript में वर्तमान सेगमेंट होता है। full_transcript में पूरे सेशन का संचयी (cumulative) ट्रांसक्रिप्ट होता है। जब is_final ट्रू (true) हो, तो अपने रनिंग सेशन लॉग को बनाए रखने के लिए full_transcript का उपयोग करें।

माइक्रोफ़ोन कैप्चर के लिए websockets और sounddevice का उपयोग करने वाला पाइथन समकक्ष इस प्रकार है।



import asyncio<br>import json<br>import os<br>import websockets<br>import sounddevice as sd<p></p><br><p>SAMPLE_RATE = 16000<br>CHUNK_BYTES = 4096</p><br><p>async def stream_microphone():<br>url = (<br>"wss://api.smallest.ai/waves/v1/pulse/get_text"<br>f"?language=en&encoding=linear16&sample_rate={SAMPLE_RATE}&word_timestamps=true"<br>)<br>headers = {"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}"}</p><br><pre><code>async with websockets.connect(url, extra_headers=headers) as ws:<br>loop = asyncio.get_event_loop()<br>audio_queue = asyncio.Queue()<p></p>
<pre><code>def audio_callback(indata, frames, time, status):
    loop.call_soon_threadsafe(audio_queue.put_nowait, bytes(indata))

with sd.RawInputStream(
    samplerate=SAMPLE_RATE,
    channels=1,
    dtype="int16",
    blocksize=CHUNK_BYTES // 2,
    callback=audio_callback,
):
    async def send_audio():
        while True:
            chunk = await audio_queue.get()
            await ws.send(chunk)

    async def receive_events():
        async for message in ws:
            data = json.loads(message)
            if data.get("is_final"):
                print(f"\n[FINAL] {data['transcript']}")
            else:
                print(f"\r{data['transcript']}", end="", flush=True)

    await asyncio.gather(send_audio(), receive_events())
</code></pre

import asyncio<br>import json<br>import os<br>import websockets<br>import sounddevice as sd<p></p><br><p>SAMPLE_RATE = 16000<br>CHUNK_BYTES = 4096</p><br><p>async def stream_microphone():<br>url = (<br>"wss://api.smallest.ai/waves/v1/pulse/get_text"<br>f"?language=en&encoding=linear16&sample_rate={SAMPLE_RATE}&word_timestamps=true"<br>)<br>headers = {"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}"}</p><br><pre><code>async with websockets.connect(url, extra_headers=headers) as ws:<br>loop = asyncio.get_event_loop()<br>audio_queue = asyncio.Queue()<p></p>
<pre><code>def audio_callback(indata, frames, time, status):
    loop.call_soon_threadsafe(audio_queue.put_nowait, bytes(indata))

with sd.RawInputStream(
    samplerate=SAMPLE_RATE,
    channels=1,
    dtype="int16",
    blocksize=CHUNK_BYTES // 2,
    callback=audio_callback,
):
    async def send_audio():
        while True:
            chunk = await audio_queue.get()
            await ws.send(chunk)

    async def receive_events():
        async for message in ws:
            data = json.loads(message)
            if data.get("is_final"):
                print(f"\n[FINAL] {data['transcript']}")
            else:
                print(f"\r{data['transcript']}", end="", flush=True)

    await asyncio.gather(send_audio(), receive_events())
</code></pre

import asyncio<br>import json<br>import os<br>import websockets<br>import sounddevice as sd<p></p><br><p>SAMPLE_RATE = 16000<br>CHUNK_BYTES = 4096</p><br><p>async def stream_microphone():<br>url = (<br>"wss://api.smallest.ai/waves/v1/pulse/get_text"<br>f"?language=en&encoding=linear16&sample_rate={SAMPLE_RATE}&word_timestamps=true"<br>)<br>headers = {"Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}"}</p><br><pre><code>async with websockets.connect(url, extra_headers=headers) as ws:<br>loop = asyncio.get_event_loop()<br>audio_queue = asyncio.Queue()<p></p>
<pre><code>def audio_callback(indata, frames, time, status):
    loop.call_soon_threadsafe(audio_queue.put_nowait, bytes(indata))

with sd.RawInputStream(
    samplerate=SAMPLE_RATE,
    channels=1,
    dtype="int16",
    blocksize=CHUNK_BYTES // 2,
    callback=audio_callback,
):
    async def send_audio():
        while True:
            chunk = await audio_queue.get()
            await ws.send(chunk)

    async def receive_events():
        async for message in ws:
            data = json.loads(message)
            if data.get("is_final"):
                print(f"\n[FINAL] {data['transcript']}")
            else:
                print(f"\r{data['transcript']}", end="", flush=True)

    await asyncio.gather(send_audio(), receive_events())
</code></pre

जब आप स्ट्रीमिंग समाप्त कर लें, तो कनेक्शन बंद करने से पहले फ़ाइनलाइज़ सिग्नल भेजें। इसके बिना, मॉडल का इंटरनल बफ़र फ़्लश नहीं हो सकता है और ऑडियो का आखिरी सेगमेंट खो जाएगा।



await ws.send(json.dumps({"type": "finalize"}))
await ws.send(json.dumps({"type": "finalize"}))
await ws.send(json.dumps({"type": "finalize"}))



बैच बनाम रियल-टाइम: निर्णायक कारक

मोड्स के बीच चयन इस बात पर निर्भर करता है कि क्या आपका एप्लिकेशन पूरे परिणाम का इंतजार कर सकता है या ऑडियो आने के दौरान आंशिक परिणामों की आवश्यकता है।

प्री-रिकॉर्डेड ट्रांसक्रिप्शन का उपयोग तब करें जब आप पहले से मौजूद ऑडियो फाइलों को प्रोसेस कर रहे हों, जब एक सेकंड से कम समय में परिणामों की आवश्यकता न हो, जब आप वेबसॉकेट लाइफसाइकिल मैनेजमेंट के बजाय सरल HTTP रिक्वेस्ट-रिस्पांस कोड पसंद करते हैं, या जब आप हाई-वॉल्यूम ऑफलाइन बैच जॉब्स चला रहे हों।

रियल-टाइम स्ट्रीमिंग का उपयोग तब करें जब आप एक वॉयस एजेंट बना रहे हों जहां रिस्पांस लेटेंसी यह तय करती है कि बातचीत स्वाभाविक लगती है या नहीं, जब आपको उपयोगकर्ता के बोलने के दौरान ही आंशिक ट्रांसक्रिप्ट दिखाने की आवश्यकता हो, जब आपको डाउनस्ट्रीम लॉजिक चलाने के लिए टर्न डिटेक्शन की आवश्यकता हो, या जब आप लाइव फोन कॉल या माइक्रोफोन इनपुट को ट्रांसक्राइब कर रहे हों।

दोनों मोड्स अलग-अलग रिस्पांस स्ट्रक्चर भी लौटाते हैं, और काम शुरू करने से पहले इसके बारे में योजना बनाना उचित है। प्री-रिकॉर्डेड transcription, words, और utterances के साथ एक सिंगल JSON ऑब्जेक्ट लौटाता है। रियल-टाइम इवेंट्स की एक स्ट्रीम लौटाता है जहां प्रत्येक संदेश में transcript, full_transcript, और is_final होता है। यदि आपका रिस्पांस हैंडलर उनके साथ एक जैसा व्यवहार करता है, तो आपको ऐसी त्रुटियां मिलेंगी जो आसानी से पकड़ में नहीं आएंगी।



अगले कदम

Smallest AI कुकबुक देखें, जो Smallest AI के APIs के साथ निर्माण करने के लिए वास्तविक दुनिया के उदाहरणों और ट्यूटोरियल्स का एक व्यापक संग्रह है, जिसमें बुनियादी ट्रांसक्रिप्शन, वॉयस एजेंट और उन्नत सुविधाएं शामिल हैं।

स्पीच-टू-टेक्स्ट उदाहरण:

  1. शुरुआत कैसे करें: पाइथन और जावास्क्रिप्ट के लिए बुनियादी ट्रांसक्रिप्शन उदाहरण

  2. जार्विस वॉयस असिस्टेंट: वेक वर्ड डिटेक्शन, LLM रीजनिंग और TTS इंटीग्रेशन के साथ हमेशा ऑन रहने वाला पूरा असिस्टेंट

  3. मीटिंग नोट्स बॉट: इंटेलिजेंट स्पीकर आइडेंटिफिकेशन और स्ट्रक्चर्ड नोट जनरेशन के साथ ऑटोमेटेड मीटिंग ट्रांसक्रिप्शन

  4. इमोशन एनालाइज़र: इंटरएक्टिव चार्ट्स के साथ बातचीत में वक्ता की भावनाओं को विज़ुअलाइज़ करें

API संदर्भ: Pulse STT क्विकस्टार्ट, प्री-रिकॉर्डेड API, रियल-टाइम वेबसॉकेट API



पल्स को विशेष रूप से उन ऑडियो स्थितियों के लिए बनाया गया है जिनका आपके उपयोगकर्ता वास्तव में सामना करते हैं

पल्स एसटीटी (Pulse STT) का निःशुल्क प्रयास करें

एआई (AI) के साथ सारांशित करें

पल्स को विशेष रूप से उन ऑडियो स्थितियों के लिए बनाया गया है जिनका आपके उपयोगकर्ता वास्तव में सामना करते हैं

पल्स एसटीटी (Pulse STT) का निःशुल्क प्रयास करें

लेख सुनें
2:00
लेख सुनें
2:00

एआई (AI) के साथ सारांशित करें

पल्स को विशेष रूप से उन ऑडियो स्थितियों के लिए बनाया गया है जिनका आपके उपयोगकर्ता वास्तव में सामना करते हैं

पल्स एसटीटी (Pulse STT) का निःशुल्क प्रयास करें

वॉयस एजेंट ऑर्केस्ट्रेशन के भविष्य का निर्माण करें

311 कैलिफ़ोर्निया स्ट्रीट, सुइट 320
सैन फ्रांसिस्को, सीए 94104

वॉयस एजेंट ऑर्केस्ट्रेशन के भविष्य का निर्माण करें

311 कैलिफ़ोर्निया स्ट्रीट, सुइट 320
सैन फ्रांसिस्को, सीए 94104

वॉयस एजेंट ऑर्केस्ट्रेशन के भविष्य का निर्माण करें

311 कैलिफ़ोर्निया स्ट्रीट, सुइट 320
सैन फ्रांसिस्को, सीए 94104