Kullanım Kılavuzu API Başvuru Kılavuzu

Gerçek zamanlı konuşmadan metne dönüştürme (STT)

WebSockets kullanarak canlı ses akışını gerçek zamanlı olarak metne dönüştürün.

WSS wss://moknah.io/api/v1/stt/ws/

Ham ses verisini sunucularımıza aktarın ve çift yönlü, gerçek zamanlı dökümler alın. Sunucu; kısmi sonuçlar (kullanıcı konuşurken anlık metin) ve nihai sonuçlar (kelime düzeyinde zaman damgaları içeren tamamlanmış cümleler) ile yanıt verir.

💳 Ön Ödemeli Faturalandırma Sayacı (Dakikada 83 Kredi)

Yayınlar canlı ve öngörülemez nitelikte olduğundan, ön ödemeli bir kullanım sistemi kullanıyoruz. Bağlantı kurulduğu anda, (ilk 60 saniyenin ücretini karşılayacak şekilde) 83 krediyi hemen rezerve ediyoruz. Bağlantıyı sonlandırdığınızda ise kullanımınızı saniyesi saniyesine hesaplıyor ve kullanılmayan kredileri otomatik olarak hesabınıza iade ediyoruz!

Kimlik Doğrulama ve Bağlantı

WebSocket bağlantınızın kimlik doğrulamasını yapmalısınız. Yöntem, istemci ortamınıza bağlıdır:

  • Frontend Tarayıcıları: Standart tarayıcı WebSocket’leri özel HTTP başlıklarını desteklemez. API anahtarınızı bir sorgu parametresi (?api_key=YOUR_KEY) olarak eklemelisiniz.
  • Backend / Python / Node.js: Standart HTTP başlığı olan Authorization: Bearer YOUR_API_KEY’i kullanabilirsiniz.
Sorgu Parametresi Gerekli Tür Açıklama
api_key Koşullu ip Moknah API anahtarınız. (Authorization başlığı aracılığıyla iletilmediği takdirde burada gereklidir).
language İsteğe bağlı ip Transkripsiyonu yapılacak dil kodu. Varsayılan değer ar-JO’dur. Desteklenen kodlar arasında ar-SA, ar-EG, en-US vb. yer alır.

Ses Özellikleri

⚠️ KRİTİK: Yalnızca Ham İkili Veri

WebSocket üzerinden sıkıştırılmış ses dosyaları (.mp3, .m4a gibi) veya başlık (header) içeren standart .wav dosyaları göndermeyin. Aksi takdirde yapay zeka rastgele gürültü veya boş dizeler üretecektir. WebSocket yalnızca ham ikili (raw binary) PCM karelerini kabul eder.

Soket üzerinden ikili (binary) çerçeveler göndermeden önce, ses akışınızın şunlarla tam olarak eşleştiğinden emin olun:

  • Örnekleme Hızı: 16.000 Hz (16 kHz)
  • Bit Derinliği: 16-bitlik tamsayı (Int16)
  • Kanallar: 1 (Mono)
  • Parça Boyutu: Küçük parçalar halinde gönderin (ör. 100 ms / 3200 bayt). 256 KB’tan büyük parçalar reddedilecektir.

Sunucu Yanıtları (JSON Olayları)

Sunucuya ikili (binary) ses akışı gönderdiğinizde, sunucu JSON metin çerçeveleriyle asenkron olarak yanıt verecektir.

Etkinlik Türü Yük Örneği
Bağlantı Başarılı
Başarılı kimlik doğrulamanın hemen ardından gönderilir.
{"status": "connected", "message": "Ses akışına hazır..."}
Kısmi Sonuç
Kesintisiz olarak gönderilir. Canlı, yazılan altyazıları görüntülemek için kullanılır.
{"type": "partial", "text": "Platforma hoş geldiniz"}
Nihai Sonuç
Bir cümle tamamlandığında gönderilir. Zaman damgaları içerir.
{
  "type": "final",
  "text": "Makana platformuna hoş geldiniz.",
  "words": [
    {"word": "مرحبا", "start_time_ms": 150, "duration_ms": 300},
    {"word": "بك", "start_time_ms": 460, "duration_ms": 200}
  ]
}

Yayın sonlandırılıyor: When the user stops speaking, send a JSON text frame: {"command": "stop"} to safely close the connection and calculate the final refund.


Örnek Entegrasyon

# pip install websockets pyaudio
import asyncio
import websockets
import json
import pyaudio
import sys

API_KEY = "YOUR_API_KEY"
URL = "wss://moknah.io/api/v1/stt/ws/?language=ar-SA"

# 16kHz, 16-bit, Mono (100ms chunks)
CHUNK = 1600

async def stream_live_microphone(ws):
    audio = pyaudio.PyAudio()
    stream = audio.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=CHUNK)

    print("🎤 Microphone is LIVE. Start speaking!")
    loop = asyncio.get_running_loop()

    try:
        while True:
            data = await loop.run_in_executor(None, stream.read, CHUNK, False)
            await ws.send(data)
            await asyncio.sleep(0.001)
    except asyncio.CancelledError:
        await ws.send(json.dumps({"command": "stop"}))
    finally:
        stream.stop_stream()
        stream.close()
        audio.terminate()

async def receive_transcriptions(ws):
    async for message in ws:
        data = json.loads(message)
        if data.get('type') == 'partial':
            sys.stdout.write(f"\r⏳ {data['text']}")
            sys.stdout.flush()
        elif data.get('type') == 'final':
            sys.stdout.write(f"\r✅ {data['text']}\n")
            sys.stdout.flush()

async def main():
    headers = {"Authorization": f"Bearer {API_KEY}"}
    async with websockets.connect(URL, additional_headers=headers) as ws:
        await asyncio.gather(
            asyncio.create_task(stream_live_microphone(ws)),
            asyncio.create_task(receive_transcriptions(ws))
        )

asyncio.run(main())
// 1. Connect to WebSocket
const ws = new WebSocket('wss://moknah.io/api/v1/stt/ws/?api_key=YOUR_API_KEY&language=ar-SA');

ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.type === 'partial') {
        console.log("Live:", data.text);
    } else if (data.type === 'final') {
        console.log("Final:", data.text);
    }
};

// 2. Capture Microphone Audio on Connection
ws.onopen = async () => {
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });

    // Force 16kHz sample rate for the AudioContext
    const audioCtx = new AudioContext({ sampleRate: 16000 });
    const source = audioCtx.createMediaStreamSource(stream);
    const processor = audioCtx.createScriptProcessor(4096, 1, 1);

    processor.onaudioprocess = (e) => {
        if (ws.readyState === WebSocket.OPEN) {
            const float32Data = e.inputBuffer.getChannelData(0);

            // Convert Browser Float32 to Int16 PCM (Required by Server)
            const pcm16 = new Int16Array(float32Data.length);
            for (let i = 0; i < float32Data.length; i++) {
                pcm16[i] = Math.max(-1, Math.min(1, float32Data[i])) * 0x7FFF;
            }

            // Send binary PCM audio chunk to server
            ws.send(pcm16.buffer);
        }
    };

    source.connect(processor);
    processor.connect(audioCtx.destination);
};

// 3. Handle graceful shutdown
function stopRecording() {
    ws.send(JSON.stringify({ command: "stop" }));
}

Bağlantı Kesilmesi ve Hata Kodları

Bağlantı reddedilir veya kesilirse, WebSocket bu belirli kodlardan biriyle kapanacaktır:

Kodu Kapat İsim Açıklama
1000 NORMAL_CLOSURE Yayın başarıyla sona erdi. Kullanım kaydı oluşturuldu ve gerekli iade işlemi yapıldı.
4001 MISSING_API_KEY ?api_key= parametresi sağlanmadı veya geçersiz.
4002 UNAUTHORIZED Geçersiz API anahtarı, kısıtlanmış IP veya yayını başlatmak/sürdürmek için yetersiz kredi.
4009 PAYLOAD_TOO_LARGE 256 KB’tan daha büyük bir ses parçası gönderdiniz. Daha küçük arabellekler kullanarak akış gerçekleştirin.
4290 CONCURRENT_LIMIT Hesabınızda çok fazla aktif WebSocket bağlantısı bulunuyor. Sınır, 1 aktif akıştır.
API Desteği

API ile ilgili soru veya sorunlarınız için bizimle şu adresten iletişime geçin: api@moknah.io.