mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-25 08:48:13 +02:00
fix: send OutputAudio frame and let transport chunk it
This commit is contained in:
parent
0b2437a800
commit
c1901490ae
3 changed files with 18 additions and 51 deletions
|
|
@ -1643,7 +1643,7 @@ async def complete_transfer_function_call(transfer_id: str, request: Request):
|
||||||
conference_name = transfer_context.conference_name if transfer_context else None
|
conference_name = transfer_context.conference_name if transfer_context else None
|
||||||
|
|
||||||
# Determine the result based on call status with user-friendly messaging
|
# Determine the result based on call status with user-friendly messaging
|
||||||
if call_status in ("answered", "completed"):
|
if call_status in ("in-progress", "answered"):
|
||||||
result = {
|
result = {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"message": "Great! The destination number answered. Let me transfer you now.",
|
"message": "Great! The destination number answered. Let me transfer you now.",
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ from typing import TYPE_CHECKING, Any, Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
|
from api.constants import APP_ROOT_DIR
|
||||||
from api.db import db_client
|
from api.db import db_client
|
||||||
from api.enums import ToolCategory
|
from api.enums import ToolCategory
|
||||||
from api.services.telephony.call_transfer_manager import get_call_transfer_manager
|
from api.services.telephony.call_transfer_manager import get_call_transfer_manager
|
||||||
|
|
@ -548,65 +549,31 @@ class CustomToolManager:
|
||||||
sample_rate: Sample rate for the hold music (default 8000Hz for Twilio)
|
sample_rate: Sample rate for the hold music (default 8000Hz for Twilio)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
import os
|
|
||||||
|
|
||||||
# Path to hold music file based on sample rate
|
# Path to hold music file based on sample rate
|
||||||
assets_dir = os.path.join(
|
hold_music_file = (
|
||||||
os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "assets"
|
APP_ROOT_DIR / "assets" / f"transfer_hold_ring_{sample_rate}.wav"
|
||||||
)
|
)
|
||||||
|
hold_audio_data = load_hold_audio(hold_music_file, sample_rate)
|
||||||
# Select appropriate hold music file
|
num_samples = len(hold_audio_data) // 2
|
||||||
if sample_rate == 16000:
|
duration = int(num_samples / sample_rate)
|
||||||
hold_music_file = os.path.join(
|
|
||||||
assets_dir, "transfer_hold_ring_16000.wav"
|
|
||||||
)
|
|
||||||
else: # Default to 8000Hz for Twilio
|
|
||||||
hold_music_file = os.path.join(
|
|
||||||
assets_dir, "transfer_hold_ring_8000.wav"
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(f"Starting hold music loop with file: {hold_music_file}")
|
logger.info(f"Starting hold music loop with file: {hold_music_file}")
|
||||||
|
|
||||||
# Load hold music audio data
|
|
||||||
hold_audio_data = load_hold_audio(hold_music_file, sample_rate)
|
|
||||||
if not hold_audio_data:
|
|
||||||
logger.error("Failed to load hold music data")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Convert bytes to audio frames - each frame should be about 20ms worth of audio
|
|
||||||
# For 8000Hz: 20ms = 160 samples = 320 bytes (16-bit)
|
|
||||||
# For 16000Hz: 20ms = 320 samples = 640 bytes (16-bit)
|
|
||||||
frame_size = 320 if sample_rate == 8000 else 640
|
|
||||||
|
|
||||||
audio_data = hold_audio_data
|
|
||||||
total_length = len(audio_data)
|
|
||||||
position = 0
|
|
||||||
|
|
||||||
logger.info(
|
|
||||||
f"Hold music loaded: {total_length} bytes, frame size: {frame_size}"
|
|
||||||
)
|
|
||||||
|
|
||||||
while not stop_event.is_set():
|
while not stop_event.is_set():
|
||||||
# Extract audio chunk
|
# Queue the hold audio frame
|
||||||
if position + frame_size > total_length:
|
frame = OutputAudioRawFrame(
|
||||||
# Reached end of audio, loop back to beginning
|
audio=hold_audio_data,
|
||||||
position = 0
|
|
||||||
|
|
||||||
audio_chunk = audio_data[position : position + frame_size]
|
|
||||||
position += frame_size
|
|
||||||
|
|
||||||
# Create audio frame
|
|
||||||
audio_frame = OutputAudioRawFrame(
|
|
||||||
audio=audio_chunk,
|
|
||||||
sample_rate=sample_rate,
|
sample_rate=sample_rate,
|
||||||
num_channels=1,
|
num_channels=1,
|
||||||
)
|
)
|
||||||
|
await self._engine.task.queue_frame(frame)
|
||||||
|
|
||||||
# Queue the frame
|
# Wait for the audio to play or until stopped
|
||||||
await self._engine.task.queue_frame(audio_frame)
|
try:
|
||||||
|
await asyncio.wait_for(stop_event.wait(), timeout=duration + 1.5)
|
||||||
# Sleep for frame duration (20ms)
|
break # Stop event was set
|
||||||
await asyncio.sleep(0.02)
|
except asyncio.TimeoutError:
|
||||||
|
pass # Continue looping
|
||||||
|
|
||||||
logger.info("Hold music loop stopped")
|
logger.info("Hold music loop stopped")
|
||||||
|
|
||||||
|
|
|
||||||
2
pipecat
2
pipecat
|
|
@ -1 +1 @@
|
||||||
Subproject commit ff7d4c19bf02bf0e14bfe7ae20e016e04b8ba27d
|
Subproject commit c37cedc16fa9a9a72fe2dcb270fcc1ffe0071480
|
||||||
Loading…
Add table
Add a link
Reference in a new issue