fix RTP packet pacing
management-images / build-and-publish (push) Successful in 34s

This commit is contained in:
2026-09-17 18:46:51 +08:00
parent 576cc95dab
commit 758c0a29e6
2 changed files with 41 additions and 1 deletions
+11 -1
View File
@@ -340,6 +340,7 @@ class RTPMedia:
self.sequence = 0
self.timestamp = 0
self.ssrc = uuid.uuid4().int & 0xFFFFFFFF
self._next_send_at: float | None = None
self._send_lock = threading.Lock()
@property
@@ -399,11 +400,18 @@ class RTPMedia:
)
payload = pcm16_to_alaw(raw, input_rate_hz, 8000)
sent = 0
packet_interval_s = 0.02
with self._send_lock:
now = time.monotonic()
if self._next_send_at is None or self._next_send_at < now - packet_interval_s:
self._next_send_at = now
for offset in range(0, len(payload), 160):
frame = payload[offset : offset + 160]
if not frame:
continue
delay = self._next_send_at - time.monotonic()
if delay > 0:
time.sleep(delay)
header = struct.pack(
"!BBHII",
0x80,
@@ -421,7 +429,9 @@ class RTPMedia:
self.sequence += 1
self.timestamp += 160
sent += len(frame)
time.sleep(0.02)
self._next_send_at = max(
self._next_send_at + packet_interval_s, time.monotonic()
)
return sent
@staticmethod
+30
View File
@@ -10,6 +10,7 @@ import wave
from pathlib import Path
from types import SimpleNamespace
from typing import Any, cast
from unittest.mock import patch
from agent_call.real_cell import (
CellCallConfig,
@@ -154,6 +155,35 @@ class RealCellTests(unittest.TestCase):
self.assertEqual(fake_ari.record_requests, 0)
self.assertNotIn("opening", order)
def test_rtp_send_keeps_packet_clock_across_frames(self) -> None:
media = RTPMedia("127.0.0.1", 0)
receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
receiver.bind(("127.0.0.1", 0))
media.peer = ("127.0.0.1", receiver.getsockname()[1])
clock = [0.0]
sleeps: list[float] = []
def monotonic() -> float:
return clock[0]
def sleep(seconds: float) -> None:
sleeps.append(seconds)
clock[0] += seconds
try:
with (
patch("agent_call.real_cell.time.monotonic", monotonic),
patch("agent_call.real_cell.time.sleep", sleep),
):
media.send_pcm16(bytes([0, 0]) * 160, 8000)
media.send_pcm16(bytes([0, 0]) * 160, 8000)
self.assertEqual(sleeps, [0.02])
self.assertEqual(len(receiver.recvfrom(512)[0]), 172)
self.assertEqual(len(receiver.recvfrom(512)[0]), 172)
finally:
media.close()
receiver.close()
def test_pcma_decode_and_rtp_payload(self) -> None:
media = RTPMedia("127.0.0.1", 0)
receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)