रियल-टाइम टेक्स्ट-टू-स्पीच (TTS)
टेक्स्ट को धीरे-धीरे स्ट्रीम करें और तुरंत रॉ PCM या MP3 ऑडियो बाइट्स प्राप्त करें।
यह रियल-टाइम टेक्स्ट-टू-स्पीच स्ट्रीमिंग के लिए एक टू-वे (दोनों तरफ़ से काम करने वाला) WebSocket कनेक्शन बनाता है। इसमें टेक्स्ट के हिस्से धीरे-धीरे भेजे जा सकते हैं (जो LLM आउटपुट के लिए बहुत अच्छा है) और लगातार बाइनरी ऑडियो स्ट्रीम प्राप्त की जा सकती हैं। क्रेडिट की गिनती HTTP एंडपॉइंट की तरह ही की जाती है।
बहुत कम लेटेंसी (~200ms टाइम-टू-फर्स्ट-बाइट) पाने के लिए, पक्का करें कि आपके टेक्स्ट के हिस्से हार्ड पंक्चुएशन (जैसे फुल स्टॉप ., विस्मयादिबोधक चिह्न !, या प्रश्नवाचक चिह्न ؟) पर खत्म हों। AI स्वाभाविक रूप से टेक्स्ट को तब तक बफ़र करता है जब तक उसे वाक्य का अंत पता न चल जाए, ताकि बोलने का अंदाज़ बिल्कुल इंसानों जैसा हो।
प्रमाणीकरण
WebSocket हैंडशेक के दौरान Authorization हेडर का इस्तेमाल करके ऑथेंटिकेट करें:
Authorization: Bearer YOUR_API_KEY
कनेक्शन सेटअप
कनेक्ट करने के बाद, अपने मनचाहे कॉन्फ़िगरेशन के साथ एक इनिशियलाइज़ेशन मैसेज भेजें:
{
"type": "init",
"voice_id": 1710,
"prerecording": 1,
"output_format": "pcm_24000",
"voice_settings": {
"temperature": 25,
"similarity": 100,
"expressiveness": 0,
"speed": 1.0,
"fast_mode": 2
}
}
इनिट पैरामीटर्स
| पैरामीटर | आवश्यक | टाइप | विवरण |
|---|---|---|---|
| type | ज़रूरी | डोरी | प्रारंभिक संदेश के लिए "init" होना चाहिए। |
| voice_id | ज़रूरी | पूर्णांक | से वॉइस ID आवाज़ों की सूची. |
| output_format | वैकल्पिक | डोरी | ज़रूरी ऑडियो फ़ॉर्मैट। डिफ़ॉल्ट रूप से pcm_24000। विकल्पों में शामिल हैं:
|
| prerecording | वैकल्पिक | पूर्णांक | 1 (सामान्य, डिफ़ॉल्ट) या 2 (AI एन्हांसमेंट)। इससे क्रेडिट की लागत पर असर पड़ता है। |
| voice_settings | वैकल्पिक | वस्तु | आवाज़ को अपनी पसंद के अनुसार बदलने के विकल्प। नीचे ’आवाज़ की सेटिंग्स’ (Voice Settings) वाला सेक्शन देखें। |
वॉइस सेटिंग्स ऑब्जेक्ट
| पैरामीटर | टाइप | रेंज | डिफ़ॉल्ट | विवरण |
|---|---|---|---|---|
| temperature | पूर्णांक | 0 – 100 | 25 | कम = स्थिर और अनुमान लगाने योग्य, ज़्यादा = रचनात्मक और विविध। |
| similarity | पूर्णांक | 0 – 100 | 100 | स्पीच ओरिजिनल वॉइस क्लोन से कितनी मिलती-जुलती है। |
| speed | तैरना | 0.5 – 2.0 | 1.0 | प्लेबैक स्पीड मल्टीप्लायर |
| fast_mode | पूर्णांक | 0, 1, or 2 | 0 |
लेटेंसी को काफी कम करता है।
|
स्ट्रीमिंग पाइपलाइन
1. टेक्स्ट के हिस्से भेजें
जैसे-जैसे आपका LLM टेक्स्ट बनाता जाए, उसे वैसे-वैसे भेजते रहें:
{"type": "text", "data": "مرحبا بكم."}
सर्वर तुरंत उस हिस्से (चंक) को प्रोसेस करेगा, उस अवधि के लिए तय क्रेडिट्स काट लेगा और ऑडियो की स्ट्रीमिंग शुरू कर देगा।
2. सिग्नल पूरा होना (रुकना)
जब आपका टेक्स्ट जनरेशन पूरी तरह से पूरा हो जाए, तो स्टॉप सिग्नल भेजें:
{"type": "stop"}
सर्वर अपने बफ़र में बचे हुए टेक्स्ट को सिंथेसाइज़ करना पूरा करेगा, फ़ाइनल ऑडियो बाइट्स आपको भेजेगा और ’एंड ऑफ़ स्ट्रीम’ सिग्नल भेजेगा।
संदेश प्राप्त करना
सर्वर WebSocket पर दो तरह के फ़्रेम भेजता है:
1. बाइनरी ऑडियो चंक्स (PCM / MP3)
रॉ ऑडियो बाइट्स वैसे ही स्ट्रीम किए जाते हैं जैसे वे बनते हैं। फ़ॉर्मेट आपके द्वारा मांगे गए output_format पर निर्भर करता है (डिफ़ॉल्ट रूप से 24kHz पर 16-बिट PCM)। अगर आपने MP3 मांगा है, तो आप इन बाइट्स को सीधे किसी फ़ाइल में लिख सकते हैं।
2. JSON कंट्रोल मैसेज
इनिट तैयार:
{"status": "ready", "message": "इनिशियलाइज़ हो गया है और टेक्स्ट लेने के लिए तैयार है।"}
स्ट्रीम का अंत (सुरक्षित रूप से बंद करने का सिग्नल):
{"type": "end_of_stream"}
जब आपको यह संदेश मिलता है, तो यह गणितीय रूप से गारंटी देता है कि 100% ऑडियो चंक्स डिलीवर हो चुके हैं। अब आप क्लाइंट साइड पर WebSocket कनेक्शन सुरक्षित रूप से बंद कर सकते हैं।
बीच में आई गड़बड़ी:
{"error": "स्ट्रीम के दौरान अपर्याप्त क्रेडिट"}
प्रोडक्शन के लिए तैयार उदाहरण
# pip install websockets
import asyncio
import websockets
import json
API_KEY = "YOUR_API_KEY"
url = "wss://api.moknah.io/api/v1/tts/ws/"
async def stream_tts():
headers = {"Authorization": f"Bearer {API_KEY}"}
async with websockets.connect(url, additional_headers=headers) as ws:
# 1. Initialize session (Requesting MP3 so we can save to file)
await ws.send(json.dumps({
"type": "init",
"voice_id": 1710,
"output_format": "mp3_44100_128",
"voice_settings": {"fast_mode": 2}
}))
print(f"Server: {await ws.recv()}")
# 2. Receiver Task
async def receive_audio():
with open("audio.mp3", "wb") as f:
async for msg in ws:
if isinstance(msg, bytes):
f.write(msg)
else:
data = json.loads(msg)
if data.get("type") == "end_of_stream":
print("✅ Stream finished safely.")
await ws.close()
break
receiver = asyncio.create_task(receive_audio())
# 3. Send Text
for chunk in ["مرحبا بكم.", "في منصة مُكنة."]:
await ws.send(json.dumps({"type": "text", "data": chunk}))
await asyncio.sleep(0.5)
# 4. Signal Stop
await ws.send(json.dumps({"type": "stop"}))
await receiver
asyncio.run(stream_tts())
// npm install ws
const WebSocket = require('ws');
const fs = require('fs');
const API_KEY = "YOUR_API_KEY";
const ws = new WebSocket('wss://api.moknah.io/api/v1/tts/ws/', {
headers: { "Authorization": `Bearer ${API_KEY}` }
});
const audioStream = fs.createWriteStream('audio.mp3');
ws.on('open', function open() {
// Requesting MP3 to safely write to an MP3 file
ws.send(JSON.stringify({
type: "init",
voice_id: 1710,
output_format: "mp3_44100_128",
voice_settings: { fast_mode: 2 }
}));
});
ws.on('message', function incoming(data, isBinary) {
if (isBinary) {
audioStream.write(data); // Save MP3 chunks
} else {
const msg = JSON.parse(data.toString());
if (msg.status === 'ready') {
console.log("Ready! Sending text...");
ws.send(JSON.stringify({ type: "text", data: "مرحبا بكم." }));
setTimeout(() => ws.send(JSON.stringify({ type: "text", data: "في منصة مُكة." })), 500);
setTimeout(() => ws.send(JSON.stringify({ type: "stop" })), 1000);
} else if (msg.type === 'end_of_stream') {
console.log("✅ All audio received. Closing connection.");
ws.close();
}
}
});
<?php
// composer require textalk/websocket
require 'vendor/autoload.php';
use WebSocket\Client;
$apiKey = "YOUR_API_KEY";
$client = new Client("wss://api.moknah.io/api/v1/tts/ws/", [
'headers' => ['Authorization' => "Bearer $apiKey"],
'timeout' => 60
]);
// 1. Initialize (Requesting MP3 format)
$client->text(json_encode([
"type" => "init",
"voice_id" => 1710,
"output_format" => "mp3_44100_128",
"voice_settings" => ["fast_mode" => 2]
]));
echo "Server: " . $client->receive() . "\n";
// 2. Send Text Chunks
$client->text(json_encode(["type" => "text", "data" => "مرحبا بكم."]));
$client->text(json_encode(["type" => "text", "data" => "في منصة مُكنة."]));
$client->text(json_encode(["type" => "stop"]));
// 3. Receive Audio & Control Messages
$audioFile = fopen("audio.mp3", "wb");
while (true) {
$message = $client->receive();
$decoded = json_decode($message, true);
if ($decoded && isset($decoded['type']) && $decoded['type'] == 'end_of_stream') {
echo "✅ Stream finished successfully.\n";
break;
} elseif (!$decoded) {
// If it can't be decoded as JSON, it's our binary MP3 audio chunk
fwrite($audioFile, $message);
}
}
fclose($audioFile);
$client->close();
?>
# Standard cURL does not support bidirectional WebSockets easily.
# Use 'websocat' to test WebSockets from the command line:
websocat wss://api.moknah.io/api/v1/tts/ws/ \
-H "Authorization: Bearer YOUR_API_KEY"
# Once connected, paste the JSON payloads interactively:
{"type": "init", "voice_id": 1710, "output_format": "mp3_44100_128"}
{"type": "text", "data": "مرحبا بكم."}
{"type": "stop"}
कोड और एरर बंद करें
WebSocket कनेक्शन इनमें से किसी एक स्टैंडर्ड कोड के साथ बंद हो सकता है:
| कोड | टाइप | विवरण |
|---|---|---|
1000 |
सफलता | स्ट्रीम स्वाभाविक रूप से पूरी हो गई। |
3011 |
जनरेशन_एरर | अपस्ट्रीम API पर ऑडियो जनरेशन फ़ेल हो गया। अनुरोध को फिर से करें। |
4001 |
API_KEY_गायब_है | ऑथराइज़ेशन हेडर में कोई API की (API key) नहीं दी गई है। |
4002 |
ऑथेंटिकेशन फ़ेल हो गया | अमान्य की (key), निष्क्रिय खाता, अपर्याप्त शुरुआती क्रेडिट, या IP प्रतिबंध। |
4290 |
एक साथ चलने की सीमा | यूज़र के पास पहले से ही एक एक्टिव TTS WebSocket कनेक्शन है। प्रति यूज़र लिमिट 1 है। |
API से जुड़े सवालों या समस्याओं के लिए, हमसे संपर्क करें api@moknah.io.