Files
olcrtc/code/wbstream_poc_datachannel.py

111 lines
4.0 KiB
Python
Executable File

#!/usr/bin/env python3
"""PoC: WB Stream DataChannel over LiveKit."""
import asyncio
import logging
import uuid
import requests
try:
from livekit import rtc
except ImportError:
print("[!] Error: livekit library not installed.\nRun: pip install livekit requests")
exit(1)
logging.getLogger("livekit").setLevel(logging.WARNING)
API_BASE = "https://stream.wb.ru"
WS_URL = "wss://wbstream01-el.wb.ru:7880"
TEST_MESSAGES = ["Hello WB Stream!", "Hello world", "X" * 100, "Final test"]
def _get_room_token(room_id: str, display_name: str) -> tuple[str, str]:
"""Retrieves the room token via the guest API."""
headers = {
"User-Agent": "Mozilla/5.0 (Linux x86_64)",
"Content-Type": "application/json"
}
reg_req = requests.post(
f"{API_BASE}/auth/api/v1/auth/user/guest-register",
json={"displayName": display_name, "device": {"deviceName": "Linux", "deviceType": "PARTICIPANT_DEVICE_TYPE_WEB_DESKTOP"}},
headers=headers
)
reg_req.raise_for_status()
headers["Authorization"] = f"Bearer {reg_req.json()['accessToken']}"
if not room_id:
room_req = requests.post(f"{API_BASE}/api-room/api/v2/room", json={"roomType": "ROOM_TYPE_ALL_ON_SCREEN", "roomPrivacy": "ROOM_PRIVACY_FREE"}, headers=headers)
room_req.raise_for_status()
room_id = room_req.json()["roomId"]
requests.post(f"{API_BASE}/api-room/api/v1/room/{room_id}/join", json={}, headers=headers).raise_for_status()
tok_req = requests.get(f"{API_BASE}/api-room-manager/api/v1/room/{room_id}/token", params={"deviceType": "PARTICIPANT_DEVICE_TYPE_WEB_DESKTOP", "displayName": display_name}, headers=headers)
tok_req.raise_for_status()
return room_id, tok_req.json()["roomToken"]
async def run_poc() -> dict:
"""Runs the complete PoC flow."""
print("\n--- WB Stream PoC ---")
results = {"server_ok": False, "client_ok": False, "sent": 0, "recv": 0, "errors": []}
server, client = rtc.Room(), rtc.Room()
shared_room_id, _ = _get_room_token("", "OlcRTC-Server")
print("[1/3] Connecting Server & Client...")
try:
shared_room_id, server_tok = _get_room_token("", "OlcRTC-Server")
_, client_tok = _get_room_token(shared_room_id, "OlcRTC-Client")
@server.on("data_received")
def on_server_data(dp: rtc.DataPacket):
if dp.topic == "olcrtc":
asyncio.create_task(server.local_participant.publish_data(f"Echo: {dp.data.decode()}".encode(), topic="olcrtc"))
@client.on("data_received")
def on_client_data(dp: rtc.DataPacket):
results["recv"] += 1
await server.connect(WS_URL, server_tok)
results["server_ok"] = True
await client.connect(WS_URL, client_tok)
results["client_ok"] = True
print(f" :P Peers connected to room: {shared_room_id}")
except Exception as e:
results["errors"].append(str(e))
return results
print("\n[2/3] Exchanging messages...")
await asyncio.sleep(1)
for idx, msg in enumerate(TEST_MESSAGES, 1):
try:
await client.local_participant.publish_data(msg.encode(), topic="olcrtc")
results["sent"] += 1
print(f" -> Sent: {msg}")
await asyncio.sleep(0.5)
except Exception as e:
results["errors"].append(f"Sending {idx} failed: {str(e)}")
await asyncio.sleep(2)
print("\n[3/3] Cleaning up...")
await server.disconnect()
await client.disconnect()
return results
def print_results(res: dict):
print("\n--- TEST RESULTS ---")
print(f"Server: {':P' if res['server_ok'] else 'X'} / Client: {':P' if res['client_ok'] else 'X'}")
print(f"Messages: Sent {res['sent']} / Recv {res['recv']}")
if res['errors']:
for e in res['errors']: print(f" Error: {e}")
print(f"\n{':P SUCCESS' if res['sent'] and res['sent'] == res['recv'] else 'X FAILED'}\n")
if __name__ == "__main__":
try:
res = asyncio.run(run_poc())
print_results(res)
except KeyboardInterrupt:
pass