EG/core/openxr_streamer.py
Rowland 72819341ef docs(README): 添加项目README文档
- 创建详细的README文档,介绍项目功能、架构、使用方法等
- 新增.pyc文件和目录,用于缓存编译后的Python代码
- 添加.lingma规则文件,用于代码格式检查
- 删除ALVR串流处理器代码,准备替换为OpenXR输入处理器
- 新增OpenXR输入处理器代码,处理VR控制器输入
2025-07-29 17:46:08 +08:00

257 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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