Spaces:
Runtime error
Runtime error
File size: 3,737 Bytes
c5f9050 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | # backend/cdp_streamer.py
import asyncio
import json
import websockets
from playwright.async_api import CDPSession
class CDPBrowserStreamer:
def __init__(self, page):
self.page = page
self.cdp_session = CDPSession()
self.streaming = False
async def start_streaming(self, websocket_port: int = 8080):
"""Start CDP-based streaming"""
try:
# Get CDP session from Playwright page
self.cdp_session = await self.page.context.new_cdp_session(self.page)
# Enable necessary CDP domains
await self.cdp_session.send('Runtime.enable')
await self.cdp_session.send('Page.enable')
await self.cdp_session.send('Page.startScreencast', {
'format': 'jpeg',
'quality': 80,
'maxWidth': 1280,
'maxHeight': 800,
'everyNthFrame': 1 # Stream every frame for real-time
})
# Start WebSocket server for streaming
await websockets.serve(self.handle_client, "localhost", websocket_port)
print(f"π₯ CDP Streaming started on port {websocket_port}")
except Exception as e:
print(f"β Failed to start CDP streaming: {e}")
async def handle_client(self, websocket, path):
"""Handle WebSocket clients for streaming"""
print("π Client connected to CDP stream")
try:
# Listen for screencast frames
self.cdp_session.on('Page.screencastFrame', lambda params:
asyncio.create_task(self.send_frame(websocket, params)))
# Keep connection alive and handle client messages
async for message in websocket:
data = json.loads(message)
if data['type'] == 'mouse':
await self.handle_mouse_event(data)
elif data['type'] == 'keyboard':
await self.handle_keyboard_event(data)
except websockets.exceptions.ConnectionClosed:
print("π Client disconnected from CDP stream")
async def send_frame(self, websocket, params):
"""Send screencast frame to client"""
try:
frame_data = {
'type': 'frame',
'data': params['data'], # Base64 encoded JPEG
'metadata': {
'sessionId': params['sessionId'],
'timestamp': params.get('timestamp')
}
}
await websocket.send(json.dumps(frame_data))
# Acknowledge frame
await self.cdp_session.send('Page.screencastFrameAck', {
'sessionId': params['sessionId']
})
except Exception as e:
print(f"β Error sending frame: {e}")
async def handle_mouse_event(self, data):
"""Handle mouse events from client"""
await self.cdp_session.send('Input.dispatchMouseEvent', {
'type': data['eventType'], # 'mousePressed', 'mouseReleased', 'mouseMoved'
'x': data['x'],
'y': data['y'],
'button': data.get('button', 'left'),
'clickCount': data.get('clickCount', 1)
})
async def handle_keyboard_event(self, data):
"""Handle keyboard events from client"""
await self.cdp_session.send('Input.dispatchKeyEvent', {
'type': data['eventType'], # 'keyDown', 'keyUp', 'char'
'text': data.get('text', ''),
'key': data.get('key', ''),
'code': data.get('code', '')
})
|