美化push_screen.py界面,增加状态栏显示配置和连接信息

This commit is contained in:
2026-03-19 09:41:43 +08:00
parent b470b4cf4a
commit 4d7ae06eb3

View File

@@ -2,10 +2,14 @@ import subprocess
import psutil
import os
import sys
import socket
import time
from loguru import logger
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QMessageBox, QVBoxLayout, QWidget
from PySide6.QtCore import QProcess, Qt
from PySide6.QtWidgets import (QApplication, QMainWindow, QPushButton, QMessageBox,
QVBoxLayout, QWidget, QLabel, QGroupBox, QGridLayout,
QStatusBar, QProgressBar, QFrame)
from PySide6.QtCore import QTimer, Qt, QThread, Signal
from PySide6.QtGui import QFont, QPalette, QColor
logger.add(sys.stderr, format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}", level="INFO")
@@ -14,57 +18,192 @@ MEDIAMTX_PATH = r"D:\ScreenCast\mediamtx\mediamtx.exe"
FFMPEG_PATH = r"D:\ScreenCast\ffmpeg\bin\ffmpeg.exe"
STREAM_PATH = "screen"
def check_mediamtx_running():
logger.info("检查MediaMTX进程是否运行")
for proc in psutil.process_iter(['name']):
if proc.info['name'] == 'mediamtx.exe':
logger.info("MediaMTX进程已运行")
class ConnectionChecker(QThread):
status_update = Signal(dict)
def run(self):
while True:
status = {
"mediamtx": self.check_mediamtx(),
"ffmpeg": self.check_ffmpeg(),
"server": self.check_server(),
"server_port": self.check_port(SERVER_IP, 8554),
}
self.status_update.emit(status)
time.sleep(3)
def check_mediamtx(self):
for proc in psutil.process_iter(['name']):
if proc.info['name'] == 'mediamtx.exe':
return True
return False
def check_ffmpeg(self):
return os.path.exists(FFMPEG_PATH)
def check_server(self):
try:
socket.create_connection((SERVER_IP, 8554), timeout=2)
return True
logger.info("MediaMTX进程未运行")
return False
except:
return False
def start_mediamtx():
if not check_mediamtx_running():
logger.info("启动MediaMTX服务")
subprocess.Popen([MEDIAMTX_PATH], cwd=r"D:\ScreenCast\mediamtx", creationflags=subprocess.CREATE_NEW_CONSOLE)
time.sleep(3)
logger.info("MediaMTX服务已启动")
def push_full_screen(window):
logger.info("开始全屏投屏")
start_mediamtx()
cmd = [
FFMPEG_PATH,
"-f", "gdigrab", "-framerate", "30", "-i", "desktop",
"-c:v", "libx264", "-preset", "ultrafast", "-tune", "zerolatency",
"-f", "rtsp", f"rtsp://{SERVER_IP}:8554/{STREAM_PATH}"
]
logger.info(f"执行FFmpeg命令: {' '.join(cmd)}")
process = QProcess()
process.startDetached(FFMPEG_PATH, cmd[1:])
logger.info("FFmpeg推流已启动")
QMessageBox.information(window, "提示", f"全屏投屏已启动!接收端可打开浏览器访问:\nhttp://{SERVER_IP}:8889/webrtc.html?src=screen")
def check_port(self, ip, port):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)
result = sock.connect_ex((ip, port))
sock.close()
return result == 0
except:
return False
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("投屏源控制")
self.setFixedSize(400, 200)
self.setFixedSize(500, 350)
self.status_bar = QStatusBar()
self.setStatusBar(self.status_bar)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
main_layout = QVBoxLayout(central_widget)
self.btn_push = QPushButton("一键全屏投屏")
title_label = QLabel("会议投屏系统 - 主播端")
title_font = QFont("Microsoft YaHei", 14, QFont.Bold)
title_label.setFont(title_font)
title_label.setAlignment(Qt.AlignCenter)
main_layout.addWidget(title_label)
config_group = QGroupBox("本地配置")
config_layout = QGridLayout()
self.mediamtx_label = QLabel("MediaMTX: 未检测")
self.ffmpeg_label = QLabel("FFmpeg: 未检测")
self.server_label = QLabel("服务器连接: 未检测")
self.port_label = QLabel("RTSP端口: 未检测")
self.mediamtx_indicator = QLabel("")
self.mediamtx_indicator.setFixedWidth(20)
self.ffmpeg_indicator = QLabel("")
self.ffmpeg_indicator.setFixedWidth(20)
self.server_indicator = QLabel("")
self.server_indicator.setFixedWidth(20)
self.port_indicator = QLabel("")
self.port_indicator.setFixedWidth(20)
config_layout.addWidget(self.mediamtx_indicator, 0, 0)
config_layout.addWidget(self.mediamtx_label, 0, 1)
config_layout.addWidget(self.ffmpeg_indicator, 1, 0)
config_layout.addWidget(self.ffmpeg_label, 1, 1)
config_layout.addWidget(self.server_indicator, 2, 0)
config_layout.addWidget(self.server_label, 2, 1)
config_layout.addWidget(self.port_indicator, 3, 0)
config_layout.addWidget(self.port_label, 3, 1)
config_group.setLayout(config_layout)
main_layout.addWidget(config_group)
info_group = QGroupBox("流信息")
info_layout = QGridLayout()
info_layout.addWidget(QLabel("服务器IP:"), 0, 0)
info_layout.addWidget(QLabel(SERVER_IP), 0, 1)
info_layout.addWidget(QLabel("推流地址:"), 1, 0)
info_layout.addWidget(QLabel(f"rtsp://{SERVER_IP}:8554/{STREAM_PATH}"), 1, 1)
info_layout.addWidget(QLabel("访问地址:"), 2, 0)
info_layout.addWidget(QLabel(f"http://{SERVER_IP}:8889/webrtc.html?src=screen"), 2, 1)
info_group.setLayout(info_layout)
main_layout.addWidget(info_group)
self.btn_push = QPushButton("🎬 开始全屏投屏")
self.btn_push.setFixedHeight(50)
self.btn_push.clicked.connect(lambda: push_full_screen(self))
layout.addWidget(self.btn_push)
self.btn_push.setFont(QFont("Microsoft YaHei", 11))
self.btn_push.clicked.connect(self.push_full_screen)
main_layout.addWidget(self.btn_push)
self.log_label = QLabel("日志: 等待启动...")
self.log_label.setWordWrap(True)
self.log_label.setFrameShape(QFrame.Shape.StyledPanel)
self.log_label.setFixedHeight(40)
main_layout.addWidget(self.log_label)
self.checker = ConnectionChecker()
self.checker.status_update.connect(self.update_status)
self.checker.start()
logger.info("投屏源控制界面已初始化")
def update_status(self, status):
if status["mediamtx"]:
self.mediamtx_indicator.setStyleSheet("color: green; font-size: 16px;")
self.mediamtx_label.setText(f"MediaMTX: ✓ 运行中")
else:
self.mediamtx_indicator.setStyleSheet("color: red; font-size: 16px;")
self.mediamtx_label.setText(f"MediaMTX: ✗ 未运行")
if status["ffmpeg"]:
self.ffmpeg_indicator.setStyleSheet("color: green; font-size: 16px;")
self.ffmpeg_label.setText(f"FFmpeg: ✓ 已安装")
else:
self.ffmpeg_indicator.setStyleSheet("color: red; font-size: 16px;")
self.ffmpeg_label.setText(f"FFmpeg: ✗ 未找到")
if status["server"]:
self.server_indicator.setStyleSheet("color: green; font-size: 16px;")
self.server_label.setText(f"服务器连接: ✓ 可连接")
else:
self.server_indicator.setStyleSheet("color: orange; font-size: 16px;")
self.server_label.setText(f"服务器连接: ✗ 连接失败")
if status["server_port"]:
self.port_indicator.setStyleSheet("color: green; font-size: 16px;")
self.port_label.setText(f"RTSP端口: ✓ 端口开放")
else:
self.port_indicator.setStyleSheet("color: orange; font-size: 16px;")
self.port_label.setText(f"RTSP端口: ✗ 端口关闭")
def start_mediamtx(self):
if not self.checker.check_mediamtx():
logger.info("启动MediaMTX服务")
subprocess.Popen([MEDIAMTX_PATH], cwd=r"D:\ScreenCast\mediamtx", creationflags=subprocess.CREATE_NEW_CONSOLE)
time.sleep(3)
logger.info("MediaMTX服务已启动")
self.log_label.setText("日志: MediaMTX服务已启动")
else:
logger.info("MediaMTX已在运行")
self.log_label.setText("日志: MediaMTX已在运行")
def push_full_screen(self):
logger.info("开始全屏投屏")
self.start_mediamtx()
if not os.path.exists(FFMPEG_PATH):
logger.error("FFmpeg未安装")
QMessageBox.warning(self, "错误", "FFmpeg未安装请检查配置")
return
cmd = [
FFMPEG_PATH,
"-f", "gdigrab", "-framerate", "30", "-i", "desktop",
"-c:v", "libx264", "-preset", "ultrafast", "-tune", "zerolatency",
"-f", "rtsp", f"rtsp://{SERVER_IP}:8554/{STREAM_PATH}"
]
logger.info(f"执行FFmpeg命令: {' '.join(cmd)}")
subprocess.Popen(cmd, creationflags=subprocess.CREATE_NEW_CONSOLE)
logger.info("FFmpeg推流已启动")
self.log_label.setText("日志: FFmpeg推流已启动正在向服务器推送...")
QMessageBox.information(self, "提示", f"全屏投屏已启动!\n\n接收端可打开浏览器访问:\nhttp://{SERVER_IP}:8889/webrtc.html?src=screen")
def closeEvent(self, event):
self.checker.terminate()
event.accept()
if __name__ == "__main__":
logger.info("应用程序启动")
app = QApplication(sys.argv)
app.setStyle("Fusion")
window = MainWindow()
window.show()
sys.exit(app.exec())