120 lines
5.2 KiB
Python
120 lines
5.2 KiB
Python
"""Apply only to a private c726943 code copy, never the reused installation.
|
|
|
|
The extra endpoint destroys one owned peer rather than reusing partially flushed
|
|
queues. The caller must retain the randomly generated session id.
|
|
"""
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("copy", type=Path)
|
|
args = parser.parse_args()
|
|
root = args.copy.resolve()
|
|
if root == Path("/opt/hel715-verify/LiveTalking"):
|
|
raise SystemExit("Refusing to edit reused P10 installation")
|
|
p = root / "server/rtc_manager.py"
|
|
s = p.read_text()
|
|
needle = " self.pcs.add(pc)"
|
|
replacement = needle + "\n pc.hel714_sessionid = sessionid"
|
|
if replacement not in s:
|
|
assert s.count(needle) >= 1
|
|
p.write_text(s.replace(needle, replacement, 1))
|
|
p = root / "app.py"
|
|
s = p.read_text()
|
|
needle = " setup_routes(appasync)"
|
|
replacement = (
|
|
""" async def hel714_close(request):
|
|
params = await request.json()
|
|
sid = params['sessionid']
|
|
session = session_manager.get_session(sid)
|
|
if session:
|
|
session.flush_talk()
|
|
for peer in list(rtc_manager.pcs):
|
|
if getattr(peer, 'hel714_sessionid', None) == sid:
|
|
await peer.close()
|
|
rtc_manager.pcs.discard(peer)
|
|
session_manager.remove_session(sid)
|
|
return web.json_response({'closed': sid})
|
|
|
|
appasync.router.add_post('/hel714/close', hel714_close)
|
|
"""
|
|
+ needle
|
|
)
|
|
if replacement not in s:
|
|
assert s.count(needle) >= 1
|
|
p.write_text(s.replace(needle, replacement, 1))
|
|
print("Installed HEL-714 peer retirement endpoint in private copy:", root)
|
|
|
|
# HEL-718: all edits remain reproducible on a clean pinned driver copy.
|
|
def replace_once(path, before, after):
|
|
text = path.read_text()
|
|
if after in text:
|
|
return
|
|
assert text.count(before) == 1, f"Unexpected c726943 source: {path}"
|
|
path.write_text(text.replace(before, after, 1))
|
|
|
|
|
|
(root / "server/hel718_audio.py").write_text(
|
|
Path(__file__).with_name("driver_audio.py").read_text()
|
|
)
|
|
p = root / "server/webrtc.py"
|
|
replace_once(p, "import queue\n", "import queue\nfrom server.hel718_audio import PendingAudio\n")
|
|
replace_once(p, "self._queue = queue.Queue(maxsize=100)",
|
|
"self._queue = PendingAudio() if kind == 'audio' else queue.Queue(maxsize=100)")
|
|
# Preserve the initial common audio/video origin. Once started, pace BEFORE
|
|
# selecting audio, so fresh speech cannot wait behind a dequeued idle block.
|
|
s = p.read_text()
|
|
start = s.find(" # frame = self.frames[self.counter % 30]")
|
|
end = s.index(" frame.pts = pts", max(0, start))
|
|
replacement = ''' self._player._start(self)
|
|
if self.kind == 'audio' and hasattr(self, '_timestamp'):
|
|
pts, time_base = await self.next_timestamp()
|
|
try:
|
|
frame, eventpoint, _ = self._queue.get_nowait()
|
|
except queue.Empty:
|
|
frame = AudioFrame.from_ndarray(
|
|
np.zeros((1, 320), dtype=np.int16), layout='mono', format='s16')
|
|
frame.sample_rate = SAMPLE_RATE
|
|
eventpoint = None
|
|
else:
|
|
while self.readyState == 'live':
|
|
try:
|
|
frame, eventpoint, *_ = self._queue.get_nowait()
|
|
break
|
|
except queue.Empty:
|
|
await asyncio.sleep(0.005)
|
|
else:
|
|
raise Exception('Track stopped')
|
|
pts, time_base = await self.next_timestamp()
|
|
'''
|
|
if "np.zeros((1, 320), dtype=np.int16), layout='mono'" not in s:
|
|
assert start >= 0, "Unexpected c726943 recv implementation"
|
|
p.write_text(s[:start] + replacement + s[end:])
|
|
replace_once(p, "def push_audio(self, frame, eventpoint=None):",
|
|
"def push_audio(self, frame, eventpoint=None, audio_type=0):")
|
|
replace_once(p, "self.__audio._queue.put((new_frame, eventpoint))",
|
|
"self.__audio._queue.put((new_frame, eventpoint, audio_type))")
|
|
# Wall-clock adjustments must not change packet cadence.
|
|
s = p.read_text()
|
|
start, end = s.index(" async def next_timestamp"), s.index(" async def recv")
|
|
s = s[:start] + s[start:end].replace("time.time()", "time.monotonic()") + s[end:]
|
|
p.write_text(s)
|
|
|
|
p = root / "streamout/webrtc.py"
|
|
replace_once(p, " def get_buffer_size(self) -> int:", ''' def push_audio_data(self, frame, eventpoint, audio_type):
|
|
if self._player:
|
|
self._player.push_audio(frame, eventpoint, audio_type)
|
|
|
|
def get_buffer_size(self) -> int:''')
|
|
p = root / "avatars/base_avatar.py"
|
|
replace_once(p, " self.output.push_audio_frame(frame, audio_frame.userdata)",
|
|
''' if hasattr(self.output, 'push_audio_data'):
|
|
self.output.push_audio_data(frame, audio_frame.userdata, audio_frame.type)
|
|
else:
|
|
self.output.push_audio_frame(frame, audio_frame.userdata)''')
|
|
p = root / "avatars/audio_features/base_asr.py"
|
|
replace_once(p, " for _ in range(self.stride_left_size):\n self.output_queue.get()",
|
|
" for _ in range(self.stride_left_size + self.stride_right_size):\n self.output_queue.get()")
|
|
print("Installed HEL-718 bounded synthetic idle, continuous RTP audio, and warm-up drain")
|