Как реализовать обнаружение голосовой активности и остановить голосового бота Twilio при прерывании клиента?
Я создаю голосового бота, используя Twilio и Django. Я настроил исходящий звонок с медиапотоком, который отлично работает. Однако я хочу реализовать обнаружение голосовой активности, чтобы, если клиент прерывает разговор во время разговора, бот немедленно прекращал разговор. Я ищу руководство по тому, как достичь этого, используя функцию медиапотоков Twilio
Я настроил потоковую передачу мультимедиа для исходящего звонка Twilio, используя глагол в ответе TwiML. Я вижу следующее:
class StartOutboundCallingView(APIView):
client = Client(sid, token)
def post(self, request, format=None):
from_ = request.data.get("from")
to = request.data.get("to")
if "from" not in request.data or "to" not in request.data:
return Response(
{"Required Field": "from and to are required fields"},
status=status.HTTP_400_BAD_REQUEST,
)
resp = VoiceResponse()
call = self.client.calls.create(
twiml=generate_twiml(),
to=to,
from_=from_,
)
return Response({"call_id": call.sid}, status=status.HTTP_200_OK)
вот как я генерирую twiml
def generate_twiml():
return f'''
<Response>
<Connect>
<Stream url="{url}"/>
</Connect>
</Response>
'''
это мой потребитель websocket:
class TwilioWS(WebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.groq_ai = None
self.call_id = None
self.stream_id = None
self.transcriber = None
self.tts = None
self.thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=1)
self.loop = asyncio.get_event_loop()
def connect(self):
self.transcriber: DeepgramSTT = DeepgramSTT(self)
self.transcriber.start_transcription()
asyncio.run(self.init_groq())
return super().connect()
async def init_groq(self) -> None:
self.groq_ai: GroqAI = GroqAI(self)
self.groq_ai.initialize()
def disconnect(self) -> None:
self.transcriber.disconnect()
def receive(self, text_data: str) -> None:
"""
Handle incoming WebSocket message.
Args:
text_data (str): Base64 encoded audio stream.
Returns:
None
"""
if not text_data:
self.transcriber.disconnect()
return
data: dict = json.loads(text_data)
event: str = data.get('event')
if event == "start":
self.streamSid: str = data['start']['streamSid']
self.call_id: str = data['start']['callSid']
if event == "media":
self.handle_transcription(
base64.b64decode(data["media"]["payload"]),
self.call_id,
)
if event == "stop":
self.transcriber.disconnect()
def handle_transcription(self, chunk: bytes, call_id: str) -> None:
"""Handle transcription of a chunk of audio.
Args:
chunk (bytes): The audio chunk to transcribe.
call_id (str): The ID of the call.
"""
self.thread_pool.submit(
self.transcriber.transcribe, chunk, call_id
)
// return response audio to twilio
def handle_transcribed_audio(self, audio_data):
# start_time = time.time()
encoded_audio = base64.b64encode(audio_data).decode('UTF-8')
self.send(json.dumps({
'streamSid': self.streamSid,
'event': 'media',
'media': {
'payload': encoded_audio,
},
}))