- 创建详细的README文档,介绍项目功能、架构、使用方法等 - 新增.pyc文件和目录,用于缓存编译后的Python代码 - 添加.lingma规则文件,用于代码格式检查 - 删除ALVR串流处理器代码,准备替换为OpenXR输入处理器 - 新增OpenXR输入处理器代码,处理VR控制器输入
257 lines
8.3 KiB
Python
257 lines
8.3 KiB
Python
"""
|
||
OpenXR串流处理器
|
||
|
||
负责与VR设备通信和视频流传输
|
||
支持有线连接的低延迟串流
|
||
"""
|
||
|
||
import socket
|
||
import struct
|
||
import threading
|
||
import json
|
||
import time
|
||
import subprocess
|
||
import psutil
|
||
from direct.showbase.DirectObject import DirectObject
|
||
from panda3d.core import Texture, PNMImage
|
||
|
||
|
||
class OpenXRStreamer(DirectObject):
|
||
"""OpenXR串流处理器"""
|
||
|
||
def __init__(self, world, openxr_manager):
|
||
super().__init__()
|
||
self.world = world
|
||
self.openxr_manager = openxr_manager
|
||
|
||
# 串流服务器配置
|
||
self.server_ip = "127.0.0.1"
|
||
self.server_port = 9943
|
||
self.streaming_port = 9944
|
||
|
||
# 有线连接设置
|
||
self.connection_mode = "wired" # wired, wireless
|
||
self.wired_port = 9945 # 有线连接端口
|
||
|
||
# 连接状态
|
||
self.connected = False
|
||
self.streaming = False
|
||
self.server_socket = None
|
||
self.streaming_socket = None
|
||
|
||
# 流媒体配置
|
||
self.stream_width = 2880 # 推荐分辨率
|
||
self.stream_height = 1700
|
||
self.stream_fps = 72
|
||
self.bitrate = 150 # Mbps
|
||
self.codec = "h264"
|
||
|
||
# 线程管理
|
||
self.connection_thread = None
|
||
self.streaming_thread = None
|
||
self.running = False
|
||
|
||
# 性能统计
|
||
self.frame_count = 0
|
||
self.last_fps_time = time.time()
|
||
self.current_fps = 0
|
||
self.latency = 0
|
||
|
||
print("✓ OpenXR串流处理器初始化完成")
|
||
|
||
def initialize(self):
|
||
"""初始化OpenXR串流"""
|
||
try:
|
||
# 检查串流服务器是否运行
|
||
if not self._check_streaming_server():
|
||
print("串流服务器未运行,尝试启动...")
|
||
if not self._start_streaming_server():
|
||
print("无法启动串流服务器")
|
||
return False
|
||
|
||
# 连接到串流服务器
|
||
if not self._connect_to_server():
|
||
print("无法连接到串流服务器")
|
||
return False
|
||
|
||
# 配置流媒体设置
|
||
self._configure_streaming()
|
||
|
||
# 启动串流线程
|
||
self._start_streaming_threads()
|
||
|
||
print("✓ OpenXR串流初始化成功")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"OpenXR串流初始化错误: {str(e)}")
|
||
return False
|
||
|
||
def _check_streaming_server(self):
|
||
"""检查串流服务器是否运行"""
|
||
try:
|
||
# TODO: 实际检查串流服务器状态
|
||
# 这里暂时返回False以便在开发阶段使用模拟模式
|
||
return False
|
||
except:
|
||
return False
|
||
|
||
def _start_streaming_server(self):
|
||
"""启动串流服务器"""
|
||
try:
|
||
# TODO: 实际启动串流服务器
|
||
print("ℹ 串流服务器启动占位符")
|
||
return False
|
||
except Exception as e:
|
||
print(f"串流服务器启动失败: {str(e)}")
|
||
return False
|
||
|
||
def _connect_to_server(self):
|
||
"""连接到串流服务器"""
|
||
try:
|
||
# TODO: 实际连接到串流服务器
|
||
print("ℹ 串流服务器连接占位符")
|
||
return False
|
||
except Exception as e:
|
||
print(f"串流服务器连接失败: {str(e)}")
|
||
return False
|
||
|
||
def _configure_streaming(self):
|
||
"""配置流媒体设置"""
|
||
# 根据OpenXR管理器设置配置串流参数
|
||
if self.openxr_manager:
|
||
render_size = self.openxr_manager.get_openxr_info()['render_size']
|
||
self.stream_width = render_size[0]
|
||
self.stream_height = render_size[1]
|
||
|
||
print(f"ℹ 串流配置: {self.stream_width}x{self.stream_height}@{self.stream_fps}fps")
|
||
|
||
def _start_streaming_threads(self):
|
||
"""启动串流线程"""
|
||
self.running = True
|
||
|
||
# 启动连接线程
|
||
self.connection_thread = threading.Thread(target=self._connection_handler, daemon=True)
|
||
self.connection_thread.start()
|
||
|
||
# 启动串流线程
|
||
self.streaming_thread = threading.Thread(target=self._streaming_handler, daemon=True)
|
||
self.streaming_thread.start()
|
||
|
||
def _connection_handler(self):
|
||
"""连接处理线程"""
|
||
while self.running:
|
||
try:
|
||
# TODO: 实现连接处理逻辑
|
||
time.sleep(1)
|
||
except Exception as e:
|
||
print(f"连接处理错误: {str(e)}")
|
||
|
||
def _streaming_handler(self):
|
||
"""串流处理线程"""
|
||
while self.running:
|
||
try:
|
||
if self.streaming:
|
||
self._send_video_frames()
|
||
time.sleep(1.0 / self.stream_fps)
|
||
except Exception as e:
|
||
print(f"串流处理错误: {str(e)}")
|
||
|
||
def _send_video_frames(self):
|
||
"""发送视频帧"""
|
||
try:
|
||
# 获取左右眼纹理
|
||
if self.openxr_manager and hasattr(self.openxr_manager, 'eye_textures'):
|
||
left_texture = self.openxr_manager.eye_textures.get('left')
|
||
right_texture = self.openxr_manager.eye_textures.get('right')
|
||
|
||
if left_texture and right_texture:
|
||
# TODO: 实现视频编码和发送逻辑
|
||
self.frame_count += 1
|
||
|
||
# 更新FPS统计
|
||
current_time = time.time()
|
||
if current_time - self.last_fps_time >= 1.0:
|
||
self.current_fps = self.frame_count
|
||
self.frame_count = 0
|
||
self.last_fps_time = current_time
|
||
# print(f"串流FPS: {self.current_fps}")
|
||
|
||
except Exception as e:
|
||
print(f"视频帧发送错误: {str(e)}")
|
||
|
||
def start_streaming(self):
|
||
"""开始OpenXR串流"""
|
||
if not self.connected:
|
||
print("串流服务器未连接")
|
||
return False
|
||
|
||
self.streaming = True
|
||
print("✓ OpenXR串流已开始")
|
||
return True
|
||
|
||
def stop_streaming(self):
|
||
"""停止OpenXR串流"""
|
||
self.streaming = False
|
||
print("✓ OpenXR串流已停止")
|
||
|
||
def get_streaming_status(self):
|
||
"""获取串流状态"""
|
||
return {
|
||
"connected": self.connected,
|
||
"streaming": self.streaming,
|
||
"fps": self.current_fps,
|
||
"latency": self.latency,
|
||
"resolution": f"{self.stream_width}x{self.stream_height}",
|
||
"bitrate": self.bitrate,
|
||
"codec": self.codec
|
||
}
|
||
|
||
def set_stream_quality(self, width, height, fps, bitrate):
|
||
"""设置串流质量"""
|
||
self.stream_width = width
|
||
self.stream_height = height
|
||
self.stream_fps = fps
|
||
self.bitrate = bitrate
|
||
|
||
print(f"✓ 串流质量已设置: {width}x{height}@{fps}fps, {bitrate}Mbps")
|
||
return True
|
||
|
||
def send_haptic_feedback(self, controller_id, duration, intensity):
|
||
"""发送触觉反馈"""
|
||
try:
|
||
# TODO: 实现触觉反馈发送逻辑
|
||
print(f"ℹ 触觉反馈发送占位符: 控制器{controller_id}, 持续时间{duration}s, 强度{intensity}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"触觉反馈发送失败: {str(e)}")
|
||
return False
|
||
|
||
def shutdown(self):
|
||
"""关闭串流"""
|
||
self.running = False
|
||
self.stop_streaming()
|
||
|
||
# 等待线程结束
|
||
if self.connection_thread and self.connection_thread.is_alive():
|
||
self.connection_thread.join(timeout=2)
|
||
|
||
if self.streaming_thread and self.streaming_thread.is_alive():
|
||
self.streaming_thread.join(timeout=2)
|
||
|
||
# 关闭套接字
|
||
if self.server_socket:
|
||
self.server_socket.close()
|
||
|
||
if self.streaming_socket:
|
||
self.streaming_socket.close()
|
||
|
||
print("✓ OpenXR串流已关闭")
|
||
|
||
def is_connected(self):
|
||
"""检查是否连接"""
|
||
return self.connected
|
||
|
||
def is_streaming(self):
|
||
"""检查是否正在串流"""
|
||
return self.streaming |