Skip to content

Commit 0ac38c1

Browse files
not working external phone management
1 parent 28117e4 commit 0ac38c1

File tree

8 files changed

+1039
-1
lines changed

8 files changed

+1039
-1
lines changed

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,19 @@ package-lock.json
6464
*.db
6565
*.sqlite
6666
*.sqlite3
67+
68+
# Generated certificates and SSL files
69+
certs/
70+
*.pem
71+
*.key
72+
*.crt
73+
*.cert
74+
75+
# Test files and temporary scripts
76+
test_*.py
77+
test_*.html
78+
test-*.html
79+
80+
# Generated documentation
81+
HTTPS_SETUP.md
82+
PHONE_CAMERA_SETUP.md

app/main.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
from fastapi.staticfiles import StaticFiles
33
from fastapi.responses import FileResponse
44
from fastapi.middleware.cors import CORSMiddleware
5+
import socketio
56
import os
67
import logging
78
import glob
89
import asyncio
910
from typing import List, Dict, Any
1011
import threading
1112
import queue
13+
import time
1214
from pathlib import Path
1315
from . import config
16+
from .webrtc_signaling import get_socketio_app
1417

1518
# Import our custom recording functionality
1619
from .recording import (
@@ -76,6 +79,12 @@
7679
allow_headers=["*"], # Allows all headers
7780
)
7881

82+
# Get Socket.IO app for WebRTC signaling
83+
sio = get_socketio_app()
84+
85+
# Create Socket.IO ASGI app
86+
socket_app = socketio.ASGIApp(sio, app)
87+
7988
# Create static directory if it doesn't exist
8089
os.makedirs("app/static", exist_ok=True)
8190

@@ -665,6 +674,143 @@ def get_robot_config(robot_type: str, available_configs: str = ""):
665674
return {"status": "error", "message": str(e)}
666675

667676

677+
# ============================================================================
678+
# WEBRTC STREAM MANAGEMENT ENDPOINTS
679+
# ============================================================================
680+
681+
@app.get("/webrtc/streams")
682+
def get_active_streams():
683+
"""Get list of all active WebRTC streams"""
684+
try:
685+
from .webrtc_signaling import active_streams, stream_buffers
686+
687+
streams = []
688+
for stream_id, stream_data in active_streams.items():
689+
stream_copy = stream_data.copy()
690+
stream_copy['buffer_size'] = len(stream_buffers.get(stream_id, []))
691+
streams.append(stream_copy)
692+
693+
return {"success": True, "streams": streams}
694+
except Exception as e:
695+
logger.error(f"Error getting active streams: {str(e)}")
696+
return {"success": False, "error": str(e)}
697+
698+
@app.get("/webrtc/streams/{stream_id}")
699+
def get_stream_info(stream_id: str):
700+
"""Get detailed information about a specific stream"""
701+
try:
702+
from .webrtc_signaling import active_streams, stream_buffers
703+
704+
if stream_id not in active_streams:
705+
return {"success": False, "error": "Stream not found"}
706+
707+
stream_info = active_streams[stream_id].copy()
708+
stream_info['buffer_size'] = len(stream_buffers.get(stream_id, []))
709+
710+
# Add buffer statistics
711+
if stream_id in stream_buffers and stream_buffers[stream_id]:
712+
buffer = stream_buffers[stream_id]
713+
stream_info['buffer_stats'] = {
714+
'oldest_frame': buffer[0]['timestamp'] if buffer else None,
715+
'newest_frame': buffer[-1]['timestamp'] if buffer else None,
716+
'total_frames': len(buffer)
717+
}
718+
719+
return {"success": True, "stream": stream_info}
720+
except Exception as e:
721+
logger.error(f"Error getting stream info for {stream_id}: {str(e)}")
722+
return {"success": False, "error": str(e)}
723+
724+
@app.get("/webrtc/sessions")
725+
def get_active_sessions():
726+
"""Get list of all active WebRTC sessions"""
727+
try:
728+
from .webrtc_signaling import active_sessions
729+
730+
sessions = []
731+
for webrtc_id, session_data in active_sessions.items():
732+
session_copy = session_data.copy()
733+
# Remove sensitive client IDs from public endpoint
734+
session_copy.pop('desktop_client', None)
735+
session_copy.pop('phone_client', None)
736+
sessions.append(session_copy)
737+
738+
return {"success": True, "sessions": sessions}
739+
except Exception as e:
740+
logger.error(f"Error getting active sessions: {str(e)}")
741+
return {"success": False, "error": str(e)}
742+
743+
@app.post("/webrtc/test-stream")
744+
def create_test_stream():
745+
"""Create a test stream for development/testing purposes"""
746+
try:
747+
import uuid
748+
from datetime import datetime
749+
from .webrtc_signaling import active_streams, stream_buffers
750+
751+
# Generate test stream
752+
stream_id = str(uuid.uuid4())
753+
test_webrtc_id = f"test_{int(time.time())}"
754+
755+
# Create test stream entry
756+
active_streams[stream_id] = {
757+
'stream_id': stream_id,
758+
'webrtc_id': test_webrtc_id,
759+
'created_at': datetime.now().isoformat(),
760+
'status': 'test_active',
761+
'metadata': {
762+
'width': 640,
763+
'height': 480,
764+
'fps': 30,
765+
'codec': 'h264',
766+
'test': True
767+
}
768+
}
769+
770+
# Initialize with test frame data
771+
stream_buffers[stream_id] = [
772+
{
773+
'timestamp': time.time(),
774+
'data': 'test_frame_data_placeholder',
775+
'sequence': 0
776+
}
777+
]
778+
779+
logger.info(f"Created test stream: {stream_id}")
780+
781+
return {
782+
"success": True,
783+
"stream_id": stream_id,
784+
"webrtc_id": test_webrtc_id,
785+
"message": "Test stream created successfully"
786+
}
787+
788+
except Exception as e:
789+
logger.error(f"Error creating test stream: {str(e)}")
790+
return {"success": False, "error": str(e)}
791+
792+
@app.delete("/webrtc/streams/{stream_id}")
793+
def delete_stream(stream_id: str):
794+
"""Delete a specific stream and its buffer"""
795+
try:
796+
from .webrtc_signaling import active_streams, stream_buffers
797+
798+
if stream_id not in active_streams:
799+
return {"success": False, "error": "Stream not found"}
800+
801+
# Remove stream and buffer
802+
del active_streams[stream_id]
803+
if stream_id in stream_buffers:
804+
del stream_buffers[stream_id]
805+
806+
logger.info(f"Deleted stream: {stream_id}")
807+
return {"success": True, "message": "Stream deleted successfully"}
808+
809+
except Exception as e:
810+
logger.error(f"Error deleting stream {stream_id}: {str(e)}")
811+
return {"success": False, "error": str(e)}
812+
813+
668814
@app.on_event("shutdown")
669815
async def shutdown_event():
670816
"""Clean up resources when FastAPI shuts down"""
@@ -680,3 +826,7 @@ async def shutdown_event():
680826
if manager:
681827
manager.stop_broadcast_thread()
682828
logger.info("✅ Cleanup completed")
829+
830+
# Create a combined app that serves both FastAPI and Socket.IO
831+
# The socket_app already wraps the FastAPI app, so we use it as the main app
832+
main_app = socket_app

0 commit comments

Comments
 (0)