import asyncio
import cv2
import aiohttp
from aiortc import RTCPeerConnection, RTCSessionDescription
WHEP_URL = "http://10.10.10.10:8889/cam/whep"
async def run():
pc = RTCPeerConnection()
# Добавляем трансceiver только для приёма видео
pc.addTransceiver("video", direction="recvonly")
@pc.on("track")
def on_track(track):
if track.kind == "video":
print("Видеопоток WebRTC получен!")
asyncio.ensure_future(display_frames(track))
# Создаем SDP Offer
offer = await pc.createOffer()
await pc.setLocalDescription(offer)
print(f"Отправка WHEP-запроса на {WHEP_URL}...")
async with aiohttp.ClientSession() as session:
headers = {"Content-Type": "application/sdp"}
async with session.post(WHEP_URL, data=pc.localDescription.sdp, headers=headers) as resp:
if resp.status not in (200, 201):
text = await resp.text()
print(f"Ошибка WHEP сервера ({resp.status}): {text}")
await pc.close()
return
answer_sdp = await resp.text()
# Применяем SDP Answer от MediaMTX
answer = RTCSessionDescription(sdp=answer_sdp, type="answer")
await pc.setRemoteDescription(answer)
print("Соединение WebRTC установлено! Ждем кадры...")
# Держим соединение активным
while True:
await asyncio.sleep(1)
async def display_frames(track):
while True:
try:
frame = await track.recv()
# Конвертируем PyAV VideoFrame в numpy-массив BGR для OpenCV
img = frame.to_ndarray(format="bgr24")
cv2.imshow("RoboMarvel WebRTC Camera", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
except Exception as e:
print(f"Ошибка получения кадра: {e}")
break
cv2.destroyAllWindows()
if __name__ == "__main__":
try:
asyncio.run(run())
except KeyboardInterrupt:
print("Остановлено пользователем")