
Project Design Purpose : 该项目旨在创建一个轻量级、可扩展的摄像头模拟服务程序,通过 Flask Web 界面,在 HTTP(s) 上公开一个 Motion-JPEG (MJPEG) 视频流,用于网络靶场、红/蓝对抗演习以及研究,在这些场景中,需要逼真的摄像头端点,但又无需物理硬件。

模拟视频流可以从五种不同类型的源生成:
- 本地物理摄像头(嵌入式网络摄像头或 USB 摄像头)。
- 外部实时流(RTSP/HTTP 源)。
- 静态或旋转图像数据集(从目录加载的图像)。
- 操作系统屏幕录制(完整或部分屏幕截图)。
- 应用程序窗口捕获(仅限 Windows;捕获正在运行的应用程序窗口)。
该模拟器有意模仿 Axis IP cameras 的 Web UI 和行为,因此它也可以部署为可信的摄像头蜜罐,或作为测试和集成的直接替代品。
# Author: Yuancheng Liu
# Created: 2025/10/15
# version: v_0.0.5
# Copyright: Copyright (c) 2025 LiuYuancheng
# License: GNU General Public License V3
Introduction
IoT/IP 摄像头是现代 IT/OT 系统中的关键传感器之一,用于监视、安全监控和操作可见性。在数字孪生和模拟环境(其中 MU、PLC、RTU 甚至像火车或跑道灯这样的物理世界实体都在软件中建模)中,通常缺少逼真的摄像头端点。Python Virtual Motion-JPEG Camera Simulator 旨在通过生成可信的 MJPEG 摄像头流来填补这一空白,这些流可以集成到数字孪生、网络靶场、监控仪表板以及欺骗/蜜罐部署中。
该项目提供了一个轻量级、便携式的模拟器,可以在 VM 或容器中运行,并通过 HTTP(s) 公开带有 Axis 风格 Web UI 的 MJPEG 流。系统工作流程图如下所示:

Figure-01: System Workflow Diagram, version v_0.0.3 (2025)
视频流可以由实时设备、预先录制的数据集或主机上的捕获生成,因此模拟器可以呈现上下文相关的视频——例如,当数字孪生指示飞机正在最后进近时,在模拟跑道摄像头上显示着陆的飞机。
Architecture Overview
该系统包含三个主要组件,如下面的架构图所示:

Figure-02: System Architecture Diagram, version v_0.0.3 (2025)
-
Virtual Camera Client Library : 将各种视频/图像源转换为具有可配置 FPS 和分辨率的 Motion-JPEG (MJPEG) 流。支持的源:本地网络摄像头/USB 摄像头、RTSP/HTTP 流、图像数据集、桌面屏幕截图(完整/部分)和应用程序窗口捕获(仅限 Windows)。
-
Flask Camera Server : 一个模仿 Axis 风格摄像头页面的管理 Web 应用程序。它公开摄像头配置、流端点、用户控件和日志——使模拟器既可以用作逼真的测试摄像头,也可以用作令人信服的蜜罐 UI。
-
Multi-Camera View Monitor Dashboard : 一个仪表板程序,将多个虚拟摄像头源聚合到一个多帧视图中,用于在指挥中心进行监控或投影。
System Design
本节介绍系统三个主要组件的详细设计和内部结构,这些组件在 Introduction[Architecture Overview] 章节中介绍。
Design of Virtual Camera Client Library
Virtual Camera Client Library 负责将各种视频源转换为可以提供给浏览器或其他应用程序的连续 MJPEG 流。该模块的核心是基类 camClient,它定义了由五个主要步骤组成的流式传输管道:

Step 1: Frame Capture from Source
-
每个子类实现
camClient接口函数getOneFrame()以从其分配的视频源检索一个 OpenCV (cv2) 图像帧。此函数确保所有源类型之间的一致帧对象。
Step 2: Image JPEG Encoding
-
每个捕获的帧都被压缩成 JPEG 格式,以减少带宽并实现高效的流式传输:
-
_, buffer = cv2.imencode('.jpg', frame)
Step 3: Return HTTP Streaming
-
Flask 生成器不断地将每个编码的 JPEG 帧产生到 HTTP 响应流:
-
yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n')
Step 4: Multipart MJPEG Response
-
HTTP 响应使用 MIME 类型
multipart/x-mixed-replace发送,允许浏览器将其解释为连续的 JPEG 图像流: -
mimetype='multipart/x-mixed-replace; boundary=frame'
Step 5: Browser Renders Live Stream
-
在浏览器的
元素中,按顺序编码每个传入的 JPEG 帧并显示它们——在视觉上创建一个视频: -
Class Structure and Source Inheritance
camClient 基类由几个专门的子类扩展,这些子类处理不同的输入源:

Figure-04: Class Structure Diagram, version v_0.0.3 (2025)
每个子类管理其自己的捕获逻辑,同时为 Flask 服务器和仪表板维护统一的流式传输接口。
Design of Flask Camera Server
Flask Camera Server 是一个 Web 主机,提供用户界面、视频直播视图、配置选项和用于视频流的 API 端点。它还支持安全访问控制以及与网络靶场或数字孪生环境中的物理世界模拟数据的链接。Flask 服务器的运行流程/结构如下所示:

Figure-04: Flask Server Workflow Diagram, version v_0.0.3 (2025)
四个模块的功能详细信息包括:
-
Video Source Manager Module : 包装器模块导入并与
Virtual Camera Client Library集成,以管理来自多个视频源的帧捕获。 -
User and Access Management Module : 处理身份验证和授权,链接到凭据数据库以管理用户登录和 MJPEG 获取 API 访问权限。
-
Data Manager Module : 数据管理器模块与网络靶场的物理世界模拟器交互,以将操作状态(例如,飞机位置、火车移动)映射到适当的摄像头视频显示馈送帧。
-
Flash Web Service Module : 主 Web 服务模块打开一个可配置的端口来处理所有 http/https 请求。
基于 Flask 的 Web 服务器为用户提供四个主要页面,如下所示:
[1] Camera Home Page
当用户访问摄像头模拟器 IP 地址时的默认登录页面,提示用户使用有效的凭据登录,然后才能访问摄像头系统:

Figure-05: IP Camera Home Page Screenshot, version v_0.0.3 (2025)
[2] Camera Video Live View Page
用户使用正确的凭据登录后,他们可以访问显示当前实时 MJPEG 流的页面。用户可以从页面实时调整帧分辨率和 FPS:

Figure-06: Camera Video Live View Page Screenshot, version v_0.0.3 (2025)
[3] User Configuration Page
允许不同类型的用户管理和更改访问凭据。当前版本提供 2 种类型的用户:
-
Normal users 只能查看直播流并更改自己的密码。
-
Admin users 可以添加/删除用户、重置/检查密码以及管理 MJPEG API 令牌。

Figure-07: User Configuration Page Screenshot, version v_0.0.3 (2025)
[4] Access Token Configuration Page
用于为外部应用程序生成和管理 MJPEG API 访问令牌。对于其他使用 motion-JPEG API 获取帧的程序,调用 API URL 时需要有效的访问令牌。只有管理员用户才能访问 API 令牌配置页面,如下所示:

Figure-08: Access Token Configuration Page Screenshot, version v_0.0.3 (2025)
有 2 种类型的 API 访问令牌:
-
Fixed Token : 固定令牌在摄像头本地数据库中预先配置,并且没有使用限制。如果我们重新启动摄像头模拟器程序,固定令牌不会丢失。
-
Temporary Token : 临时令牌保存在摄像头的内存中,每次管理员按下“Generate a random token”按钮时,摄像头模拟器都会生成一个 16 个字符的临时令牌。管理员还可以设置临时令牌的有效期。当摄像头模拟器重新启动时,所有临时令牌都将丢失。
用户访问规则和可用功能如下表所示:
| Function\User | Admin User | Normal User |
|---|---|---|
| Access the user management page | ✅ | ❌ |
| Change own password | ✅ | ✅ |
| Change and check other user's password | ✅ | ❌ |
| Add and remove normal user | ✅ | ❌ |
| Create new admin user | ✅ | ❌ |
| Remove exist admin user | ❌ | ❌ |
| Access the motion-JPEG token management page | ✅ | ❌ |
| View the fixed and temporary API token | ✅ | ❌ |
| Generate, modify and delete the temporary API token | ✅ | ❌ |
Design of Multi-Camera View Monitor Dashboard
Multi-Camera View Monitor Dashboard 将多个虚拟摄像头流聚合到一个统一的监控界面中。它通过 HTTP API 调用获取 MJPEG 视频源,并在可配置的多视图布局中显示它们。摄像头模拟器和仪表板的网络拓扑和配置如下所示:

Figure-09: Monitor Dashboard Network Diagram, version v_0.0.3 (2025)
显示仪表板功能包括:
-
支持同时监控多个 MJPEG 源。
-
可配置的网格布局(例如,2x2、3x3)用于自定义显示设置。
-
可调整的流 FPS 和分辨率,用于性能调整。
-
允许多个仪表板订阅同一个摄像头流
Dashboard's Camera Access Configuration File
每个摄像头源都在 JSON 配置文件中定义。以下是将新摄像头添加到仪表板的示例:
"Desktop1": {
"name": "Desktop screenshot 1 virtual Camera",
"url": "http://127.0.0.1:5000/cgi-bin/mjpg/",
"token": "motionJPEG",
"size": [
640,
480
]
},
该仪表板支持灵活的布局配置、可调整的 FPS,并且可以在单个窗口或多个显示器上显示多个摄像头流。
System Configuration and Usage
Development Environment : Python 3.7.4+
Project file list and module function description
Virtual Camera Client Library
| Program File | Execution Env | Description |
|---|---|---|
src/lib/virtualCamera.py |
python 3 | Virtual camera lib module |
src/lib/virtualCameraTest.py + templates |
python 3 + HTML | Virtual camera lib test case module |
Flask Camera Server
| Program File | Execution Env | Description |
|---|---|---|
src/VirtualCam/static/* |
CSS, JS,Image | All the web CSS, JavaScript and image |
src/VirtualCam/templates/* |
HTML | All the html pages of the web. |
src/VirtualCam/Config_templat.txt |
The configuration template file for user to build own config file. | |
src/VirtualCam/users_template.json |
JSON | The user credential data base file template. |
src/VirtualCam/webCamGlobal.py |
python 3 | Global parameter module. |
src/VirtualCam/webCamDataMgr.py |
python 3 | Optional module to linked to the cyber range physical world simulation module. |
src/VirtualCam/webCamAuth.py |
python 3 | Flask user authorization module. |
src/VirtualCam/webCamApp.py |
python 3 | Main Flask web host execution module. |
Multi-Camera View Monitor Dashboard
| Program File | Execution Env | Description |
|---|---|---|
src/MultiCamViewDashboard/camDashboardConfig_template.txt |
Dashboard configuration template file. | |
src/MultiCamViewDashboard/camDashboardDataMgr.py |
python 3 | Sub-thread module to fetch MJPEG image from all cameras |
src/MultiCamViewDashboard/camDashboardGlobal.py |
python 3 | Global parameter module. |
src/MultiCamViewDashboard/camDashboardPanel.py |
python 3 | Dashboard display panel module. |
src/MultiCamViewDashboard/cameraConfig_template.json |
JSON | Camera access configuration file template. |
src/MultiCamViewDashboard/camDashboardRun.py |
python 3 | Dashboard main execution module. |
System Pre-Setup
Before configure the system, install the additional lib/software in the below table:
| Lib Module | Version | Installation | Lib link |
|---|---|---|---|
| Flask | 1.1.2 | pip install Flask |
https://flask.palletsprojects.com/en/stable/ |
| Flask_Login | 0.6.2 | pip install Flask-Login |
https://pypi.org/project/Flask-Login/ |
| numpy | 1.21.6 | pip install numpy |
https://pypi.org/project/numpy/ |
| opencv_python | 4.5.1.48 | pip install opencv-python |
https://pypi.org/project/opencv-python/ |
| PyAutoGUI | 0.9.53 | pip install PyAutoGUI |
https://pyautogui.readthedocs.io/en/latest/ |
| pywin32 | 305 | pip install pywin32 |
https://pypi.org/project/pywin32/ |
| requests | 2.28.1 | pip install requests |
https://pypi.org/project/requests/ |
| win32gui | 221.6 | pip install win32gui |
https://pypi.org/project/win32gui/ |
| wxPython | 4.1.0 | pip install wxPython |
https://pypi.org/project/wxPython/ |
虚拟摄像头的使用
工作文件夹 : src/VirtualCam
步骤 1:设置 Web 配置文件。
将配置文件模板 Config_template.txt 重命名为 Config.txt,并按照如下所示设置参数:
# This is the config file template for the module
# Setup the parameter with below format (every line follows : format, the
# key can not be changed):
#-----------------------------------------------------------------------------
# Camera mode flag,
CAM_MD:2
#-----------------------------------------------------------------------------
# Camera Admin user config and user record file.
USERS_RCD:users.json
#-----------------------------------------------------------------------------
# Define physical world simulator IP
RW_IP:127.0.0.1
# Define physical world simulator connection port
RW_PORT:3001
RW_REFRESH_TIME:1
# Physical world reconnection time
RW_RECONN_TIME:10
#-----------------------------------------------------------------------------
# Camera video source parameter:
# Simulated camera report to RW ID:
CAM_ID:RW_CAM_REAL
# Physical camera ID
CAM_IDX:0
CAM_FPS:6
# Simulated camera data set parameters:
CAM_DATA_DIR:takeoff
CAM_DATA_PREFIX:takeoff-
CAM_DATA_START_IDX:6
CAM_DATA_END_IDX:53
#-----------------------------------------------------------------------------
# Init the Flask app parameters
FLASK_SER_PORT:5000
FLASK_DEBUG_MD:False
FLASK_MULTI_TH:True
FLASK_FIXED_TOKEN:motionJPEG
步骤 2:设置视频源
在配置文件中设置摄像头模式标志参数:
-
CAM_MD:1- 来自真实摄像头 -
CAM_MD:2- 来自图像数据集 -
CAM_MD:3- 来自桌面屏幕录制 -
CAM_MD:4- 来自 Windows 应用程序。
在 webCamApp.py 中,配置视频源,如下所示:
if gv.gCamMode == 0:
gv.iCamMgr = cam.camClientReal(gv.gCamSrc, fps=gv.gCamFps)
elif gv.gCamMode == 1:
gv.iCamMgr = cam.camClientSimu(gv.gCamDir, gv.gCamFilePrefix, fps=gv.gCamFps)
gv.iCamMgr.setShowTimestamp(True)
gv.iCamMgr.setTestMode(56)
elif gv.gCamMode == 2:
gv.iCamMgr = cam.camClientScreen(fps=gv.gCamFps)
else:
windowName = "templates - File Explorer"
#windowName = "2D Airport CAT-II Runway Light System Simulation"
#windowName = "Microsoft Edge"
gv.iCamMgr = cam.camClientWinApp(windowName)
要查找整个应用程序窗口名称,请将鼠标移动到 Windows 任务栏,然后单击顶部弹出的小窗口以显示窗口名称,如下所示:

从 Windows 应用程序捕获时,该应用程序不能最小化。
步骤 3:设置用户授权文件
将 users_template.json 重命名为 users.json,并添加用户名和密码,如下所示:
"admin": {
"username": "admin",
"password": "admin",
"usertype": "admin"
},
步骤 4:运行虚拟摄像头程序
运行 Flask Web 主机并打开 URL:http://
python webCamApp.py
要使用 GET 请求调用 motion JPEG API,请从令牌页面复制固定或临时令牌,如下所示:

然后使用 http GET 请求 URL http:// 获取虚拟摄像头的单帧,如下所示:
response = requests.get(http://:/cgi-bin/mjpg/, timeout=1)
摄像头视图仪表板的使用
步骤 1:设置仪表板配置文件。
将配置文件模板 camDashboardConfig_template.txt 重命名为 camDashboardConfig.txt,并按照如下所示设置参数:
# This is the config file template for the module
# Setup the parameter with below format (every line follows : format, the
# key can not be changed):
#-----------------------------------------------------------------------------
# Test mode:
# - True: run the UI with out connect to the cameras.
# - False: connect to the cameras and fetch the vide stream.
#TEST_MD:True
TEST_MD:False
#-----------------------------------------------------------------------------
# Define all the HMI UI config parameters
# define UI title name
UI_TITLE: Multi-Camera View Monitor Dashboard
# Define update clock interval
CLK_INT:0.5
#-----------------------------------------------------------------------------
# camera connection configuration file.
CAM_CONFIG_FILE:cameraConfig.json
步骤 2:设置摄像头连接配置文件
将配置文件模板 cameraConfig_template.json 重命名为 cameraConfig.txt,从相关摄像头的令牌页面复制访问令牌(固定/临时),并将要访问的摄像头添加到文件中,如下所示:
"Desktop1": {
"name": "Desktop screenshot 1 virtual Camera",
"url": "http://127.0.0.1:5000/cgi-bin/mjpg/",
"token": "motionJPEG",
"size": [
640,
480
]
},
步骤 3:运行仪表板
确保所有虚拟摄像头都在运行,并使用 cmd 运行仪表板:
python camDashboardRun
然后,仪表板将如下所示:

未配置或未连接的摄像头将显示“no video”。
程序典型用例
该系统设计用于构建 OT 网络靶场并支持网络演习,可能的用例包括:
-
为蓝队/红队演习和网络靶场提供仪表化的摄像头端点。
-
部署可信的摄像头蜜罐,以捕获攻击者行为并构建数据集。
-
将摄像头馈送集成到数字孪生场景中(例如,显示基于模拟操作的与状态相关的视频)。
-
在没有物理摄像头的情况下测试和验证监控客户端、分析管道和仪表板。
-
聚合来自虚拟机和主机应用程序的各种视频源,用于演示、QA 或 ML 数据集生成。
我们还将展示两个用例,说明如何使用该项目来模拟航空跑道网络靶场中的 4 个不同的摄像头,并在网络演习中监控铁路网络靶场 HMI。
用例:作为网络靶场监控系统
该系统用于 航空跑道灯光管理系统网络靶场,以模拟塔台操作员的监控摄像头监控系统,以显示如下所示的四个摄像头。这四个摄像头包括:
-
机场跑道着陆区监控摄像头
-
机场跑道起飞区监控摄像头
-
塔台操作室监控摄像头
-
网络靶场物理世界模拟器视图显示摄像头

Figure-10: Cyber Range Surveillance System Dashboard, version v_0.0.3 (2025)
用例:作为网络演习主投影屏幕
该系统用于监控陆基铁路 IT-OT 系统网络安全网络靶场系统中在不同 VM 上运行的所有 UI 程序,并在大型电视上投影,如下所示。 4 个受监控的程序包括:
-
铁路网络靶场物理世界模拟器
-
总部铁路轨道信号系统监控 HMI
-
总部铁路列车监控和控制系统 HMI
-
总部铁路管理 HMI

Figure-11: Cyber Exercise Main Projection Screen, version v_0.0.3 (2025)
GitHub 链接:
https://github.com/LiuYuancheng/Python_Virtual_MotionJPEG_Camera
感谢您花时间查看文章详细信息,如果您有任何问题和建议或发现任何程序错误,请随时给我留言。如果您能提出一些意见并分享任何改进建议,我们将不胜感激,以便我们能够更好地完成工作~
上次编辑者:LiuYuancheng ([email protected]),于 2025 年 3 月 11 日,如果您有任何问题,请随时给我留言。
No comment for this article.