"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > Dify API के साथ रीयल-टाइम स्पीच कैसे प्राप्त करें

Dify API के साथ रीयल-टाइम स्पीच कैसे प्राप्त करें

2024-11-01 को प्रकाशित
ब्राउज़ करें:421

Dify एलएलएम वर्कफ़्लो ऑनलाइन बनाने के लिए एक ओपन-सोर्स SaaS प्लेटफ़ॉर्म है। मैं अपने ऐप पर संवादात्मक एआई अनुभव बनाने के लिए एपीआई का उपयोग कर रहा हूं। मैं एपीआई प्रतिक्रिया के रूप में टीटीएस स्ट्रीम प्राप्त करने और इसे चलाने के लिए संघर्ष कर रहा था। यहां मैं दर्शाता हूं कि ऑडियो स्ट्रीम को कैसे संसाधित किया जाए और इसे सही तरीके से कैसे चलाया जाए।

मैं टेक्स्ट चैट के लिए एपीआई एंडपॉइंट https://api.dify.ai/v1/chat-messages का उपयोग कर रहा हूं। यदि हम अपने Dify ऐप्स में टेक्स्ट टू स्पीच सुविधा सक्षम करते हैं तो यह टेक्स्ट प्रतिक्रिया के समान स्ट्रीम में ऑडियो डेटा लौटाता है।

फीचर जोड़ें बटन दबाएं और टेक्स्ट टू स्पीच फीचर जोड़ें।
How to realize Real-Time Speech with Dify API

आप निम्नलिखित कर्ल कमांड के साथ एपीआई से प्रतिक्रिया की जांच कर सकते हैं।

curl -X POST 'https://api.dify.ai/v1/chat-messages' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
    "inputs": {},
    "query": "What are the specs of the iPhone 13 Pro Max?",
    "response_mode": "streaming",
    "conversation_id": "",
    "user": "abc-123",
    "files": []
}'

मैं टाइपस्क्रिप्ट/जावास्क्रिप्ट में प्रदर्शित करता हूं लेकिन आप अपनी प्रोग्रामिंग भाषा में वही तर्क लागू कर सकते हैं।

स्ट्रीम किए गए डेटा का एनाटॉमी

सबसे पहले, आइए समझें कि Dify स्ट्रीम के लिए किस प्रकार का डेटा उपयोग कर रहा है।

स्ट्रीम किया गया डेटा प्रारूप

Dify निम्नलिखित टेक्स्ट डेटा प्रारूप का उपयोग कर रहा है। यह JSON लाइनों की तरह है लेकिन यह बिल्कुल वैसा नहीं है।

data: {"event": "workflow_started", "conversation_id": "065fb118-35d4-4524-a067-a70338ece575", "message_id": "3f0fe3cf-5aa1-4f7c-8abe-2505bf07ae8f", "created_at": 1724478014, "task_id": "dacb2d5c-a6f5-44b5-b5a6-de000f24aeba", "workflow_run_id": "50100b30-e458-4632-ad7d-8dd383823376", "data": {"id": "50100b30-e458-4632-ad7d-8dd383823376", "workflow_id": "debdb4fa-dcab-4233-9413-fd6d17b9e36a", "sequence_number": 334, "inputs": {"sys.query": "What are the specs of the iPhone 13 Pro Max?", "sys.files": [], "sys.conversation_id": "065fb118-35d4-4524-a067-a70338ece575", "sys.user_id": "abc-123"}, "created_at": 1724478014}}

data: {"event": "node_started", "conversation_id": "065fb118-35d4-4524-a067-a70338ece575", "message_id": "3f0fe3cf-5aa1-4f7c-8abe-2505bf07ae8f", "created_at": 1724478014, "task_id": "dacb2d5c-a6f5-44b5-b5a6-de000f24aeba", "workflow_run_id": "50100b30-e458-4632-ad7d-8dd383823376", "data": {"id": "bf912f43-29dd-4ee2-aefa-0fabdf379257", "node_id": "1721365917005", "node_type": "start", "title": "\u958b\u59cb", "index": 1, "predecessor_node_id": null, "inputs": null, "created_at": 1724478013, "extras": {}}}

data: {"event": "node_finished", "conversation_id": "065fb118-35d4-4524-a067-a70338ece575", "message_id": "3f0fe3cf-5aa1-4f7c-8abe-2505bf07ae8f", "created_at": 1724478014, "task_id": "dacb2d5c-a6f5-44b5-b5a6-de000f24aeba", "workflow_run_id": "50100b30-e458-4632-ad7d-8dd383823376", "data": {"id": "bf912f43-29dd-4ee2-aefa-0fabdf379257", "node_id": "1721365917005", "node_type": "start", "title": "\u958b\u59cb", "index": 1, "predecessor_node_id": null, "inputs": {"sys.query": "What are the specs of the iPhone 13 Pro Max?", "sys.files": [], "sys.conversation_id": "065fb118-35d4-4524-a067-a70338ece575", "sys.user_id": "abc-123", "sys.dialogue_count": 1}, "process_data": null, "outputs": {"sys.query": "What are the specs of the iPhone 13 Pro Max?", "sys.files": [], "sys.conversation_id": "065fb118-35d4-4524-a067-a70338ece575", "sys.user_id": "abc-123", "sys.dialogue_count": 1}, "status": "succeeded", "error": null, "elapsed_time": 0.001423838548362255, "execution_metadata": null, "created_at": 1724478013, "finished_at": 1724478013, "files": []}}

data: {"event": "node_started", "conversation_id": "065fb118-35d4-4524-a067-a70338ece575", "message_id": "3f0fe3cf-5aa1-4f7c-8abe-2505bf07ae8f", "created_at": 1724478014, "task_id": "dacb2d5c-a6f5-44b5-b5a6-de000f24aeba", "workflow_run_id": "50100b30-e458-4632-ad7d-8dd383823376", "data": {"id": "89ed58ab-6157-499b-81b2-92b1336969a5", "node_id": "llm", "node_type": "llm", "title": "LLM", "index": 2, "predecessor_node_id": "1721365917005", "inputs": null, "created_at": 1724478013, "extras": {}}}

...

प्रतिक्रिया में, Dify टेक्स्ट उत्तर और ऑडियो डेटा को आगे बढ़ाता है।

पाठ उत्तर की उदाहरण पंक्ति

data: {"event": "message", "conversation_id": "aa13eb24-e90a-4c5d-a36b-756f0e3be8f8", "message_id": "5be739a9-09ba-4444-9905-a2f37f8c7a21", "created_at": 1724301648, "task_id": "0643f770-e9d3-408f-b771-bb2e9430b4f9", "id": "5be739a9-09ba-4444-9905-a2f37f8c7a21", "answer": "MP"}

ऑडियो डेटा की उदाहरण पंक्ति

data: {"event": "tts_message", "conversation_id": "aa13eb24-e90a-4c5d-a36b-756f0e3be8f8", "message_id": "5be739a9-09ba-4444-9905-a2f37f8c7a21", "created_at": 1724301648, "task_id": "0643f770-e9d3-408f-b771-bb2e9430b4f9", "audio": "//PkxABhvDm0DVp4ACUUfvWc1CFlh0tR9Oh7LxzHRsGBuGx155x3JqTJiwKKZf8wIcxpMzJU0h4zhgyQwwwIsgWQMAALQMkanBTjfCPgZwFsDOGGIYJoJoJoJoPQPQLYEgAOwM4SMXMW8TcNWGrEPEME0HoIQTg0DQNA0C5k7IOLeJuDnDVi5nWyJwgghAagQwTQQgJAGrDVibiFhqw1YR8HOEjBUA5AcgagQwTQTQQgJAAtgLYKsQ8hZc0PV7OrE4SgQgFIAsAQAwA6H0Uv4t4m4m49Yt4uYOQHIBkAyAqAkAuB0Mm6UeKxDGRrIODkByBqBNBCA1ARwHIEgBVg5wkY41W2GgdEVDFBNe HicQw0ydk7HrHrIWXM62d48ePNfCkNATcTcNWGrCRhqxDxcwMYBwBkByCGC4EILgoJTQUDeW8W8TcTchZ1qBWIYchOBbBCA1AhgSMJGGrFzLmh6fL LeBkAyAZAcgSAXAhB0Kxnj4YDkJwXA6FAzwj8IIJoJoPQXA6EPOcg4R8FOBnCRljRAwlwoh4EUwLhFTCVA MR0R8wyxOhgAwwDgJjBUABMM0hMxBgnTPtMrMBEEcwJQCzIXIdMZMG821DmjDKHJAwLDKHRMQsJkwbwVRoFs//PkxEx5dDnwAZ7wANHgEUFJHGCUCQp3LWCQQYGAATI5QzwHBJF4UFktpfATT2l0goAGNADLOU64HAMCQCK50szABAIkDS2/j8gl6l6Di7QgBEiAfMEADBnyZBgeAWCMK4xvBbhoRZj1M ktsNMTrMNcHEwHQEzAjAHMGQAQwRQZTBHALMGMDkzhh2jGhLtMgsMMwfhOzCnGLMMcKgwOw8pqHMoGtvdDzos0AIAiXIsBAmGsRFtYcBABmB0AUYjQfhhDAfjoCrETAGArMOAJ4iAAMCMFkwXwh5fffuhpYMhyP2bl3MVAJQrSYQDsna7G2 fx/GvyAwUQbTAdAFCAHVKyIAduTXHZZXDjNS57/VeVJ5 JBJ 0kATkCSells8/NBt/2/5Dj1s chDBYSINutNS9FQwDwBWHjgASKRgAAJOyYC4Ao0CMNAKBgB6KK1hYBkAAHROM9mLsknb8avTcB0MerV6jl7llE70egOerRh9WcP/FoHqtVsO/In2f G2tsdnH L/KSSvBQB4OATam27Yi4jiBgBFOpq15bTQU6k1G4LoWo1mMAwDQwlBEzEnKsMkA7c5JYuTOzK2MvAbEysSPTM dOOn1XEzGgIzXzmPODVvs1cyNTJxQ9MsAWwy//PkxDlz7DIMAd7gAek5EwnjcjX9QVN1N0czFyijQKOmMi4IYw8RvzFvCHMHYBQwdQlTRxVNvm8ycGjLYlMTAQ=="}

हम इवेंट प्रॉपर्टी की जांच करके ऑडियो डेटा की JSON लाइनों को अलग कर सकते हैं। ऑडियो JSON का मान tts_message है। ऑडियो एमपी3 बाइनरी को JSONs की ऑडियो प्रॉपर्टी में बेस64 प्रारूप में संग्रहीत किया जाता है।

डेटा संभालने में समस्याएँ

जब हम टीटीएस ऑडियो रीयल-टाइम चलाते हैं तो पहली समस्या यह होती है कि JSON लाइनें पैकेट में विभाजित हो जाती हैं और प्रत्येक पैकेट वैध JSON डेटा नहीं होता है।

उदाहरण पैकेट जो बीच में कटा हुआ है

euimRrhsPMZiMAl BqSZMDmIkQEcDb/8 TEtHm8MhwA3p/p8dA0CCpAxwMMPABoYMIWwUDG6BRmiYZg2G6gRidGanOm5i5iaIYmfkH8Z/FmEopqJGZKXihYEIRxCKYKtlQuMvPjPQIwUVFFECDRnRCYEimGmA6cji41yQMImMEmhaHrVKpCxo2OYx6Q5RcJKAKkah4X6MckHEqdwKgHGHltDUjCy46HMgTCpwodAM8KijREwSSEk5hB4gRGFfC0ouYoeDiYtNREDgKQsTT6EI4egmMMBxpQZmoUJmAAg6YPDmQISgSECAZQOLfAUEQAG/dgxAVkxfFHGorEHB4CS Yugwk2gq8akIwMsZIuIzUSrCAGm1iBnoYA8lcoYSlaIJ5RjCblwbsh8sB3skA7Gcx3zmSOKnXNJO6ObKklhuYjlVL1dSMhgwVJtFzMeWFufNKy3ODmCExBTUUzLjEwMKqqqqqqqqqqqqqqqqqqCIEWFIAA4DAWKkMDDIBA4lBqGDdmZwzAkGJFoYiwEV0IQOQHg1AATJiUM6F0z2fDE6PMvlc6DhTMJ MNH4xWwzBwKMMCgHAwwUFQwjGEgMgovgIBMIMECYxYSDKAwSoMOBC4Ez682pEZIB8kBuiawZEaSnFAjIEwSFRxGUJIXMGRMmfNCPApcKL/8 TEiVdEKlJm5pM9gz0MyScwo04BgqjEFh489MGKVw=="}

पैकेट JSON लाइन के मध्य से प्रारंभ हो रहा है। वैध JSON लाइन प्राप्त करने के लिए हमें कई पैकेटों को संयोजित करना होगा।

दूसरी समस्या यह है कि JSON में ऑडियो डेटा खंड वैध ऑडियो डेटा नहीं है। डेटा को एमपी3 फ्रेम के बीच में काटा जाता है।

कार्यान्वयन

JSON और mp3 के स्प्लिट डेटा को संभालने के लिए हमें कुछ स्मार्ट तरीके अपनाने होंगे। प्रक्रिया का प्रवाह इस प्रकार है:

How to realize Real-Time Speech with Dify API

सबसे पहले, हमें वैध JSON डेटा प्राप्त करना होगा और पैकेट प्राप्त करते समय JSON में विभाजित करना होगा। जब हमें अंत में \n वाला एक पैकेट मिलता है, तो हम कह सकते हैं कि अब तक प्राप्त पैकेटों का संयोजन बीच में नहीं काटा गया है। छद्म कोड इस प्रकार है।

let packets = []
stream.on('data', (bytes) => {
   const text = bytes.toString()
   packets.push(text)
   if (text.endsWith('\n')) {
      // Extract audio data from the packets.
      const audioChunks = extractAudioChunks(packets.join(''))
      // Clear the packet array
      packets = []
   }
})

दूसरा, हमें ऑडियो हिस्सों को एमपी3 फ्रेम में विभाजित करना होगा। हम ऑडियो खंडों को एक बाइनरी में जोड़ते हैं और उसमें प्रत्येक एमपी3 फ़्रेम ढूंढते हैं।

const mp3Frames = []
const binaryToProcess = Buffer.concat([...audioChunks])
let frameStartIndex = 0
for (let i = 0; i 



यह एमपी3 फ्रेम में विभाजन का पूर्ण कार्यान्वयन नहीं है। वास्तविक प्रक्रिया में, हमें उन मामलों पर विचार करना होगा जब हमने ऑडियो बाइनरी से एमपी3 फ्रेम निकाले थे और शेष बाइट्स को अगले पुनरावृत्ति में ऑडियो बाइट्स की शुरुआत के रूप में उपयोग किया था। पूर्ण कार्यान्वयन के लिए कृपया मेरा जीथब रेपो जांचें।

विज्ञप्ति वक्तव्य यह लेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/ku6ryo/how-to-realize-real-time-speech-with-dify-api-4ii1?1 यदि कोई उल्लंघन है, तो कृपया स्टडी_गोलंग@163.com पर संपर्क करें। इसे हटाने के लिए
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3