नेविगेशन पर जाएँ

स्पीकर डायरीकरण

यह गाइड बताती है कि Realtime स्पीच टू टेक्स्ट API के साथ रीयलटाइम ट्रांसक्रिप्ट में कौन बोल रहा है, इसे कैसे लेबल करें।

कैसे करें गाइड · यह मानकर चलता है कि आपने क्लाइंट-साइड या सर्वर-साइड स्ट्रीमिंग गाइड पूरी कर ली है।

अवलोकन

स्पीकर डायरीकरण शब्दों को स्पीकर ID असाइन करता है, ताकि आप पहचान सकें कि किसने क्या कहा। डायरीकरण चालू होने पर, आंशिक ट्रांसक्रिप्ट में ड्राफ़्ट स्पीकर लेबल शामिल होते हैं और हर कमिट किए गए ट्रांसक्रिप्ट के बाद अलग diarized_transcript इवेंट आता है। ज़्यादा ऑडियो आने पर स्पीकर लेबल बदल सकते हैं।

डायरीकरण चालू करना

model_id=scribe_v3_live के साथ WebSocket कनेक्शन खोलते समय बूलियन क्वेरी पैरामीटर diarize=true सेट करें। डायरीकरण डिफ़ॉल्ट रूप से false होता है।

नीचे दिए गए सर्वर-साइड उदाहरण कनेक्शन खोलते हैं और इवेंट प्राप्त करते हैं। Python के लिए websockets, या TypeScript के लिए ws और डेवलपमेंट डिपेंडेंसी @types/ws इंस्टॉल करें। अपने सर्वर के एनवायरनमेंट में ELEVENLABS_API_KEY सेट करें; उदाहरण इसे xi-api-key हेडर में भेजते हैं। इस कुंजी को सर्वर पर रखें, ब्राउज़र कोड में नहीं।

ये उदाहरण ऑडियो नहीं भेजते। इन्हें सर्वर-साइड स्ट्रीमिंग गाइड में दिए अपने ऑडियो प्रोड्यूसर के साथ इंटीग्रेट करें: इवेंट प्राप्त करते समय उसी कनेक्शन पर input_audio_chunk मैसेज भेजें। उदाहरण pcm_16000 चुनते हैं, इसलिए उससे मेल खाता ऑडियो इस्तेमाल करें। Python में, ऑडियो भेजने वाला टास्क रिसीव लूप के साथ एक साथ चलाएं; TypeScript में, कनेक्शन खुलने के बाद ऑडियो भेजें।

import asyncio
import json
import os
from websockets.asyncio.client import connect
async def main():
url = (
"wss://api.elevenlabs.io/v1/speech-to-text/realtime"
"?model_id=scribe_v3_live&audio_format=pcm_16000&diarize=true"
)
headers = {"xi-api-key": os.environ["ELEVENLABS_API_KEY"]}
async with connect(url, additional_headers=headers) as websocket:
async for message in websocket:
event = json.loads(message)
print(event)
if __name__ == "__main__":
asyncio.run(main())

इवेंट हैंडल करना

आंशिक ट्रांसक्रिप्ट

डायरीकरण चालू होने पर, हर partial_transcript में बैच ट्रांसक्रिप्शन के समान वर्ड शेप में ड्राफ़्ट words शामिल होते हैं। स्पीकर की पहचान होने पर हर शब्द का speaker_id speaker_0, speaker_1 वगैरह होता है, या समाधान न होने तक null रहता है।

इन शब्दों को अस्थायी मानें: ज़्यादा ऑडियो मिलने पर स्पीकर ID और टाइमस्टैम्प बदल सकते हैं। जो शब्द अभी अलाइन नहीं हुए हैं, उनके पास टाइमस्टैम्प नहीं होते (start और end null होते हैं या मौजूद नहीं होते)।

कमिट किए गए और डायरीकृत ट्रांसक्रिप्ट

डायरीकरण committed_transcript में देरी नहीं करता। डायरीकरण चालू होने पर, यह इवेंट शून्य से शुरू होने वाला पूर्णांक segment_index जोड़ता है:

{
"message_type": "committed_transcript",
"segment_index": 0,
"text": "Hello."
}

हर कमिट के बाद, मेल खाते segment_index, text, और words वाला अलग diarized_transcript इवेंट आता है:

{
"message_type": "diarized_transcript",
"segment_index": 0,
"text": "Hello.",
"words": [
{
"text": "Hello.",
"speaker_id": "speaker_0"
}
]
}

ऊपर दिया शब्द सिर्फ़ टेक्स्ट और स्पीकर लेबल दिखाता है। पूरे वर्ड शेप में speaker_id के साथ बैच ट्रांसक्रिप्शन जैसे ही start, end, type, logprob, और characters फ़ील्ड होते हैं। समाधान न हुए स्पीकर की स्पीकर ID null होती है।

डायरीकृत ट्रांसक्रिप्ट कमिट क्रम में भेजे जाते हैं। उन्हें टेक्स्ट या अगले प्राप्त इवेंट के बजाय segment_index का उपयोग करके कमिट किए गए ट्रांसक्रिप्ट से जोड़ें। हर कमिट के लिए हमेशा diarized_transcript भेजा जाता है, भले ही स्पीकर की पहचान न हो पाए; उस स्थिति में, समाधान न हुई स्पीकर ID null होती हैं।

स्पीकर मर्ज

speakers_merged इवेंट का मतलब है कि दो स्पीकर ID एक ही व्यक्ति को दर्शाती हैं:

{
"message_type": "speakers_merged",
"from_speaker_id": "speaker_1",
"to_speaker_id": "speaker_0"
}

आंशिक और डायरीकृत, दोनों ट्रांसक्रिप्ट में from_speaker_id के हर पुराने उपयोग को to_speaker_id से बदलें। स्पीकर ID का दोबारा इस्तेमाल कभी नहीं होता। मर्ज की चेन बन सकती है, इसलिए उन्हें प्राप्त क्रम में लागू करें: अगर speaker_2, speaker_1 में मर्ज होता है और फिर speaker_1, speaker_0 में मर्ज होता है, तो दोनों ID के सभी पुराने शब्दों पर आखिर में speaker_0 लेबल होना चाहिए।

उदाहरण के लिए, हर प्राप्त इवेंट के लिए इस हैंडलर को कॉल करें। यहाँ transcript_history में एप्लिकेशन द्वारा रखे गए हर आंशिक और डायरीकृत ट्रांसक्रिप्ट, जिनमें पुराने आंशिक स्नैपशॉट भी शामिल हैं, स्टोर होते हैं। हर मर्ज सभी स्टोर किए गए शब्दों को उसी जगह अपडेट करता है, इसलिए चेन वाले मर्ज पहले मर्ज किए गए शब्दों को भी अपडेट करते हैं। अपडेट किए गए इस स्टोरेज से स्पीकर लेबल रेंडर करें; null लेबल null ही रहते हैं।

transcript_history = []
def handle_event(event):
if event["message_type"] in ("partial_transcript", "diarized_transcript"):
transcript_history.append(event)
elif event["message_type"] == "speakers_merged":
for transcript in transcript_history:
for word in transcript.get("words") or []:
if word.get("speaker_id") == event["from_speaker_id"]:
word["speaker_id"] = event["to_speaker_id"]

सीमाएं

  • डायरीकरण सिर्फ़ scribe_v3_live द्वारा समर्थित है। अन्य मॉडल "The 'diarize' parameter is only supported by scribe_v3_live." मैसेज के साथ invalid_request त्रुटि लौटाते हैं, फिर कनेक्शन बंद कर देते हैं।
  • डायरीकरण को filter_background_audio के साथ इस्तेमाल नहीं किया जा सकता। यह संयोजन ऐसे invalid_request त्रुटि लौटाता है जिसके मैसेज में "cannot be combined with filter_background_audio" होता है, फिर कनेक्शन बंद कर देता है।
  • स्पीकर लेबल समाधान रहित (null) रह सकते हैं और बाद के speakers_merged इवेंट पुराने लेबल बदल सकते हैं। ये मर्ज इवेंट केवल डायरीकरण चालू होने पर भेजे जाते हैं।