Как реализовать обнаружение голосовой активности и остановить голосового бота 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,
            },
        }))

Вернуться на верх