Python开发多媒体管理软件实现方法

软件开发环境
python 3.7.3
pycharm Community 2020
PYQT5 
教师端控制界面

Server

  • 下拉列表显示全部已经连接的客户端ip地址
  • 对选中的设备进行查看设备信息,重启电脑,关闭电脑,锁屏等操作。
  • 具备广播功能,可以自定义教师广播的文本内容
  • 监控的所有学生端屏幕,可以点击查看大图
  • 系统信息显示栏,可以显示教师端的IP地址和端口号;显示学生端设备信息,可以显示对学生端电脑作出的重启、关闭、锁屏等
学生端软件界面

学生端软件界面
学生端软件包括如下内容:

  • 连接教师端,需要输入教师端的网址和端口号
  • 操作面板提示做的各项操作内容和老师的广播内容
  • 可以向教师端传输文件,传输文件大小不超过1Mb
  • 举手签到操作,点击举手后教师端可以即时看到举手信息
软件技术规格:

1、软件包括学生端和教师端,采用局域网通信。
2、教师端能够连接至少2台学生端。
3、学生端能够向教师端发送文件。
4、学生端能够进行签到举手操作。
5、教师端能够向学生端设备广播信息,信息内容可自定义。
6、教师端可以对学生端屏幕进行查看。
7、教师端可以对学生端计算机进行重启操作。
8、教师端可以对学生端计算机进行关闭操作。
9、教师端可以对学生端计算机进行锁屏操作。
10、教师端能够接收学生端上传的文件。 - 状态栏自动接收
11、教师端能够查看学生端计算机的状态如CPU占用。 - 状态栏显示
12、教师端能偶查看学生端的签到举手操作。 -状态栏显示

需求详细分析:
控制学生端,发送信息,发送文件,发送监控视频,都要基于数据传输。因此首先选定教师端和学生端的通信协议为TCP/IP。基于此通信协议后,教师端需要接收:客户端的信息,举手信息,设备状态,文件;需要发送:自定义广播内容,重启、关机、锁屏等命令。相对于教师端的接收和操作,每个学生端就应具备相应的发送和接收功能。
教师端对学生端屏幕监控功能。学生端需要具备静默运行的屏幕截取功能,并发送到服务端。服务端能够接收到全部已经连接的学生端截屏,并显示在屏幕上。

软件架构
应用架构

根据以上的需求分析,软件的架构框图如下图所示。
服务端软件架构
软件在界面的支撑下,需要实现TCP服务端和监控端的功能。TCP服务器具备相应的接收和发送功能。教师端的监控功能持续接收学生端的屏幕截图。

服务端框图详细设计
在软件架构的指导下,我们将软件分为以上多条线实现,包括了Server开启,接收Client的信息,并能够发送信息;接收屏幕截图。所有逻辑运行的线路,用多线程方式运行,逻辑线程同界面线程分离,避免界面假死,提高界面的友好度。

数据传输的原理

TCP传输的原理可以参照网络相关资料。如下是TCP进行传输的三次握手过程说明。

TCP三次握手的过程如下:
客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。

屏幕截图的原理

python进行屏幕截图,采用pyautogui对屏幕进行截取,并使用HTTPServer来发送屏幕截图。
pyautogui是对屏幕、鼠标、键盘进行控制的python库,调用screenshot()将返回Image对象,该screenshot()功能大约需要100毫秒。
如果你不需要截取整个屏幕,还有一个可选的region参数。你可以把截取区域的左上角XY坐标值和宽度、高度传入截取。其文档位于https://pyautogui.readthedocs.io/en/latest/

http server就是web server,或者说网页服务器,网站服务器。常用的web server有iis,apache等。iis是internet information server的简称,是windows上主要的web服务器。

界面开发基础

PYQT5开发的方法。采用QtDesigner来简单设计一个界面,并保存为一个文件名为ui的文件。
如下提供了一个python调用ui文件并显示出界面的方法。

class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        loadUi("ui_source_server/server_panel.ui", self)  # 加载面板文件,使用qt designer开发

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.setStyleSheet(qss_style)
    window.show()
    sys.exit(app.exec_())

如果希望对软件界面进行美化,那么就在main中加入qss文件。qss是类似于CSS的文件,下文将做出解释。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    with open('style_source_server/app_style.qss', encoding='utf-8') as f:
        qss_style = f.read()
    window.setStyleSheet(qss_style)
    window.show()
    sys.exit(app.exec_())
实现路径

1、界面初步实现
教师端的初步实现
学生端的初步实现

2、屏幕录制
采用PyAutoGUI.screenshot()完成屏幕截图。
HTTPServer提供截图页面。

from http.server import BaseHTTPRequestHandler, HTTPServer
import PyAutoGUI
import socket
PORT = 8008
# 获取学生机局域网地址
IP = socket.gethostbyname(socket.gethostname())
#windows
class myHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        img = PyAutoGUI.screenshot() #屏幕截图
        if img:
            self.send_response(200) #HTTP 状态码
            self.send_header('Content-Type', 'image/png')
            self.end_headers()
            img.save(self.wfile, 'PNG') # 写入HTTP 响应流文件


def main():
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #判断当前端口是否已经打开
        result = sock.connect_ex((IP, PORT))
        portopen = result == 0
        sock.close()
        if not portopen:
            #启动web服务器,用自定义的响应处理类
            server = HTTPServer((IP, PORT), myHandler)
            server.serve_forever() # 服务器持续监听
    except:
        pass

if __name__ == '__main__':
    main()

如果单独运行屏幕截取的程序后,在浏览器中打开localhost:8008,就能立刻看到截取的屏幕图像了。如果手动刷新页面,截取的屏幕图像也随之刷新。

  1. 连接上后端的数据
    教师的服务端程序可以连接上学生端的屏幕图像,再设置轮询以后就可以显示截屏了。该种方法实现的屏幕监控具有弊端,在总结部分有解释。
    界面上显示后端的
eval('self.video_' + str(i + 1)).setPixmap(video)

在pyqt5中使用setPixmap将图片显示到label中。

4.软件界面和逻辑的分离
python中如果采用PYQT5开发界面,强烈推荐使用多线程来开发界面和逻辑分离的部分。如下中self.check_thread来开启多线程程序,程序的回调信号为pyqtSignal。回调信号的参数类型可以是python自带的常规函数类型,如int,string,list等,如果是其他更复杂的类型,可以存放到list类型中进行传递。
多线程的函数返回值触发回调函数,如下self.server_callback。回调函数的参数value即回调信号的参数。

        self.check_thread = Server([])  # 多线程去获取
        self.check_thread.signal.connect(self.server_callback)
        self.check_thread.start()  # 启动线程
class Server(QThread):
    signal = pyqtSignal(list)  # 括号里填写信号传递的参数

    def __init__(self, args_list):
        super().__init__()
        self.args_data = args_list

    def __del__(self):
        self.wait()

    def run(self):
        while True:
            client_socket, client_address = socket_server.accept()
            if client_address not in conn_list:
                conn_list.append(client_address)
                conn_dt[client_address] = client_socket
            self.signal.emit([client_socket, client_address])  # 发射信号
    def server_callback(self, value):
        """
        Sever 回调函数功能
        :param value:
        :return:
        """

5.子窗口的实现
点击每个学生端的查看按钮,可以对学生端的屏幕进行详细查看。
父窗口连接子窗口。

self.child = Child(students[client_num - 1])  # 创建子窗口实例
self.child.exec()

传入一个参数,参数信息为当前查看的学生信息。

class Child(QDialog):
    """
    查看客户端详情页。
    """
    def __init__(self, label, parent=None):
        super().__init__(parent)
        self.student = label
        self.initUI()

    def initUI(self):
        loadUi("ui_source_server/child_panel.ui", self)
        self.setWindowTitle("多媒体管理软件 -樱桃智库")  # 设置窗口标题
        self.pushButton_quit.clicked.connect(self.quit)  # 点击ok,隐士存在该方法

        self.timer = QTimer(self)  # 初始化一个定时器
        if self.student:
            self.timer.timeout.connect(self.get_client_screen)  # 每次计时到时间时发出信号
            self.timer.start(600)  # 设置计时间隔并启动;单位毫秒
        else:
            pass

    def get_client_screen(self):
        self._thread = AutoPollScreen([self.student])  # 多线程去获取
        self._thread.signal.connect(self.screen_callback)
        self._thread.start()  # 启动线程

    def screen_callback(self, videos):
        video = videos[0].scaled(1200, 800)
        self.label.setPixmap(video)

    def quit(self):  # 点击ok是发送内置信号
        self.timer.stop()
        self.close()
开发完毕

最后的界面
其实可以更进一步地对界面的美化进行提高,但想想也没必要了!
套娃的屏幕监控

异常捕获

1、屏幕截图慢。
教师控制端采用轮询的方式连接学生端的http服务器,会导致屏幕监控出现卡顿或者帧数较慢的情况出现。针对此问题的解决办法可以借鉴腾讯会议的屏幕分享功能。

2、学生端关闭程序,教师端会卡死。
这个问题主要是因为TCP的连接造成的,TCP连接成功后应该主动断开连接,否则会抛出异常。但是存在的难点是,如果学生端非正常退出,也没有办法将退出信号提前发送给教师端。

参考资料

Python开发多媒体管理软件实现方法

项目地址

https://github.com/Jarrettluo/multimedia_management_software

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值