دليل المستخدم مرجع الواجهة البرمجية (API)

تحويل النص إلى كلام في الوقت الحقيقي

قم ببث النصوص تدريجيًا واستلم بايتات صوت PCM أو MP3 الخام فورًا

WSS /api/v1/tts/ws/

يقوم بإنشاء اتصال WebSocket ثنائي الاتجاه لبث تحويل النص إلى كلام في الوقت الحقيقي. أرسل مقاطع النص تدريجيًا (مثالي لمخرجات نماذج اللغة الضخمة) واستلم تيارات صوتية ثنائية باستمرار. يتم حساب النقاط بنفس طريقة نقطة نهاية HTTP.

⚡ تحسين وقت الاستجابة (TTFB)

لتحقيق زمن استجابة منخفض للغاية (~ 200 مللي ثانية لأول بايت)، تأكد من انتهاء مقاطع النص بعلامات ترقيم صريحة (نقطة .، علامة تعجب !، أو علامة استفهام ؟). يقوم الذكاء الاصطناعي طبيعيًا بتخزين النص مؤقتًا حتى يكتشف نهاية الجملة لضمان نبرة صوت بشرية مثالية.

المصادقة

قم بالمصادقة باستخدام ترويسة Authorization أثناء مصافحة WebSocket:

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

معلمات التهيئة

Parameter إجراء مطلوب النوع الوصف
type مطلوب نص (string) يجب أن تكون "init" في رسالة التهيئة.
voice_id مطلوب عدد صحيح (integer) معرف الصوت من قائمة الأصوات.
output_format اختياري نص (string) صيغة الصوت المطلوبة. القيمة الافتراضية pcm_24000. الخيارات تشمل:
  • MP3: mp3_22050_32, mp3_44100_32, mp3_44100_64, mp3_44100_96, mp3_44100_128, mp3_44100_192
  • PCM: pcm_8000, pcm_16000, pcm_22050, pcm_24000, pcm_44100
للبث الفوري للتطبيقات بدون تأخير، استخدم PCM. لحفظ الملفات، اطلب MP3.للبث داخل التطبيقات بزمن استجابة صفر، استخدم PCM. لحفظ الملفات، اطلب صيغة MP3.
prerecording اختياري عدد صحيح (integer) 1 (عادي، افتراضي) أو 2 (تحسين بالذكاء الاصطناعي). يؤثر على تكلفة الرصيد.1 (عادي، افتراضي) أو 2 (تحسين بالذكاء الاصطناعي). يؤثر على تكلفة النقاط.
voice_settings اختياري كائن (object) خيارات تخصيص الصوت. راجع قسم إعدادات الصوت أدناه.

كائن إعدادات الصوت

Parameter النوع النطاق افتراضي الوصف
temperature عدد صحيح (integer) 0 – 100 25 أقل = مستقر وقابل للتنبؤ، أعلى = إبداعي ومتنوع.
similarity عدد صحيح (integer) 0 – 100 100 مدى مطابقة الكلام لاستنساخ الصوت الأصلي.
speed عدد عشري (float) 0.5 – 2.0 1.0 مضاعف سرعة التشغيل.
fast_mode عدد صحيح (integer) 0, 1, or 2 0 يقلل وقت الاستجابة بشكل كبير.
  • 0: معطل (أعلى جودة)
  • 1: وضع الفلاش (تقليل متوسط لوقت الاستجابة)
  • 2: وضع التيربو (أقصى تقليل لوقت الاستجابة)

مسار البث

1. إرسال مقاطع النص

أرسل النص تدريجيًا كما يتم توليده من نموذج اللغة:

{"type": "text", "data": "مرحبا بكم."}

سيقوم الخادم بمعالجة المقطع فورًا، وخصم النقاط المحددة لهذا الطول، وبدء بث الصوت مرة أخرى.

2. إشارة الاكتمال (توقف)

عندما ينتهي توليد النص تمامًا، أرسل إشارة التوقف:

{"type": "stop"}

سيقوم الخادم بإنهاء توليف النص المتبقي في الذاكرة المؤقتة، وإرسال آخر بايتات الصوت إليك، ثم إرسال إشارة نهاية البث.

استقبال الرسائل

يقوم الخادم بدفع نوعين من الإطارات عبر WebSocket:

1. مقاطع صوتية ثنائية (PCM / MP3)

بايتات صوت خام يتم بثها بسرعة توليدها. تعتمد الصيغة على output_format المطلوب (الافتراضي PCM 16-بت بتردد 24 كيلوهرتز). إذا طلبت 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 خطأ في التوليد فشل توليد الصوت في واجهة برمجة التطبيقات المصدرية. أعد المحاولة.
4001 مفتاح API مفقود لم يتم توفير مفتاح API في ترويسة Authorization.
4002 فشل المصادقة مفتاح غير صالح، حساب غير نشط، رصيد أولي غير كافٍ، أو قيود على عنوان IP.
4290 حد التزامن المستخدم لديه بالفعل اتصال TTS WebSocket نشط. الحد هو اتصال واحد لكل مستخدم.
دعم واجهة برمجة التطبيقات (API)

للأسئلة أو المشكلات المتعلقة بواجهة برمجة التطبيقات، اتصل بنا على api@moknah.io.