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

软件开发环境

python 3.7.3
pycharm Community 2020

教师端控制界面

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

学生端软件界面

学生端软件界面

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

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

软件技术规格:

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

需求详细分析

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

软件架构

应用架构

根据以上的需求分析,软件的架构框图如下图所示。


服务端软件架构

软件在界面的支撑下,需要实现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连接成功后应该主动断开连接,否则会抛出异常。但是存在的难点是,如果学生端非正常退出,也没有办法将退出信号提前发送给教师端。

参考资料

暂无。

项目地址

https://github.com/Jarrettluo/multimedia_management_software

以上项目作为联系项目,距离真正商用还有很远的距离。仅提供毕业设计或软件开发的参考项目。如果对其他的实现方法感兴趣,我们可以从开源地址联系我,我们共同探讨!

欢迎点赞、转发、分享!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,825评论 6 546
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,814评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,980评论 0 384
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 64,064评论 1 319
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,779评论 6 414
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,109评论 1 330
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,099评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,287评论 0 291
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,799评论 1 338
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,515评论 3 361
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,750评论 1 375
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,221评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,933评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,327评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,667评论 1 296
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,492评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,703评论 2 380

推荐阅读更多精彩内容