网络监控摄像头实时直播与录像回放系统,基于 .NET 8 + Blazor 构建,支持用户认证与权限管理。
- 直播预览:通过 WebRTC 技术实时预览 RTSP 网络摄像头,支持 TCP/UDP 传输;自动将
localhost/127.0.0.1替换为本机局域网 IP,避免 NAT 后客户端无法连接 - 录像回放:播放指定目录下的录制文件(MP4 视频 / AAC 音频)
- 时间筛选:录像列表支持按今天、最近 1/3/6/12 小时、最近 3 天等条件筛选
- 分页浏览:录像列表自动分页,每页 20 条,支持首页/末页/上一页/下一页跳转
- 存储监控:首页实时显示录像总大小、磁盘剩余空间及分区总容量
- 文件下载:录像列表页支持直接下载任意录制文件
- 用户认证:基于 Cookie 的登录/登出,登录后跳转回原页面(
returnUrl支持) - 权限分级:管理员可访问
/admin/users进行用户管理;普通用户可自助修改密码 - 用户管理:管理员可创建新用户(默认普通用户角色)、修改任意用户密码、删除任意用户;所有用户均可修改自己的密码
- 响应式布局:用户管理页与录像列表页均提供桌面表格视图与移动卡片视图自适应切换
- 跨平台:支持 Windows 和 Linux 双平台部署
| 层级 | 技术 |
|---|---|
| 前端框架 | Blazor Server + Blazor WebAssembly(混合模式) |
| UI 组件 | Bootstrap 5 + Bootstrap Icons 1.13.1 |
| 实时通信 | WebRTC(通过 webrtc-streamer)+ 本地 JS 模块 |
| 后端框架 | ASP.NET Core 8 |
| 语言 | C# 12(.NET 8) |
| 数据持久化 | SQLite(本地 webcamserver.db) |
| 身份认证 | ASP.NET Core Cookie Authentication |
WebcamServer/
├── AuthenticationEndpoints.cs # 登录 / 登出 HTTP 端点(/login-submit、/logout)
├── Program.cs # 应用启动、DI、中间件管道、数据库初始化
├── Components/
│ ├── Layout/ # MainLayout(含导航栏与认证状态)、EmptyLayout(登录页)
│ └── Pages/ # Home / LivePreview / Recordings / Player / UserManagement / Login / About
├── Services/
│ ├── RecordingService.cs # 录像扫描、分页、存储统计(Singleton)
│ ├── RecordingsStateService.cs # 跨页面共享分页/筛选状态(Scoped)
│ ├── AuthService.cs # 用户创建、校验、CRUD
│ └── CustomAuthenticationStateProvider.cs # 自定义 Blazor 认证状态提供器
├── Data/AppDbContext.cs # EF Core DbContext
├── Models/User.cs # 用户实体 + UserRoles 常量
├── Options/ # LiveStreamOptions / RecordingsOptions / AdminUserOptions
└── wwwroot/
├── favicon.png
└── js/webrtcstreamer.js # WebRTC-streamer 客户端封装(JS 模块)
-
.NET 8 SDK
Download .NET 8 -
WebRTC Streamer(用于直播预览)
需要在直播服务器上运行webrtc-streamer,负责将 RTSP 流转换为 WebRTC 流:# 参考 https://github.com/mpromonet/webrtc-streamer 的发布说明
编辑 WebcamServer/appsettings.json,包含以下三个配置节:
{
"LiveStream": {
"RtspUrl": "rtsp://10.0.228.102:8554/live",
"WebRtcStreamerUrl": "http://10.0.228.102:8000",
"Options": "rtptransport=tcp&timeout=60"
},
"Recordings": {
"Path": "C:\\record"
},
"AdminUser": {
"Username": "admin",
"Password": "admin123"
},
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:5000"
}
}
}
}| 配置项 | 说明 |
|---|---|
RtspUrl |
摄像头的 RTSP 地址 |
WebRtcStreamerUrl |
webrtc-streamer 服务的 HTTP 地址 |
Options |
RTSP 连接参数,如传输协议(tcp/udp)、超时时间等 |
URL 中的
localhost与127.0.0.1会在运行时被自动替换为服务器本机局域网 IP,便于跨主机访问。
| 配置项 | 说明 | 默认值 |
|---|---|---|
Path |
录像文件所在目录 | 当前进程工作目录 |
| 配置项 | 说明 |
|---|---|
Username |
初始管理员用户名 |
Password |
初始管理员密码 |
首次启动时,若数据库中不存在同名用户,系统会自动以本节配置创建管理员账户。
建议在生产环境中修改默认密码,或通过环境变量AdminUser__Username/AdminUser__Password覆盖。
cd WebcamServer
dotnet run启动后访问 http://<服务器IP>:5000,使用配置的管理员账户登录。
# Windows dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true # Linux (arm64) dotnet publish -c Release -r linux-arm64 --self-contained -p:PublishSingleFile=true
| 路径 | 页面 | 权限 |
|---|---|---|
/ |
首页(系统概览、存储信息) | 已登录 |
/login |
登录页(独立布局,无导航栏) | 公开 |
/logout |
登出端点(清除 Cookie 并跳转) | 任意 |
/live |
直播预览(WebRTC) | 已登录 |
/recordings |
录像列表(支持筛选/分页/移动端卡片视图) | 已登录 |
/player/{文件名} |
录像播放(video / audio) | 已登录 |
/admin/users |
用户管理(列表 + 修改密码 / 删除 / 自助改密) | 已登录(仅管理员可管理用户) |
/access-denied |
权限不足提示页 | 已登录 |
/about |
关于页面 | 公开 |
- 认证方式:基于 ASP.NET Core Cookie Authentication,Cookie 名为
WebcamServer.Auth,默认有效期 7 天,启用滑动过期。 - 登录流程:
- 用户访问受保护页面 →
MainLayout检测未登录,重定向至/login?returnUrl=/{原路径}。 - 用户提交登录表单 → 跳转至
/login-submit?username=...&password=...&returnUrl=...(HTTP 端点,可正常签发 Cookie)。 - 服务端校验通过后调用
SignInAsync,按returnUrl跳转回原页面(默认/)。
- 用户访问受保护页面 →
- 角色:
Admin:可访问/admin/users,管理所有用户。User:普通用户,只能修改自己的密码。
- 登出:访问
/logout端点清除 Cookie 并跳转回登录页。
系统使用正则表达式解析文件名中的录制时间等信息:
record_<YYYYMMDD>_<HHmmss>_<毫秒>_[序号].<mp4|aac>
示例:record_20260515_143022_128.mp4
- 支持 MP4(视频)和 AAC(音频)两种格式
- 序号段为可选
- 所有符合命名规范的文件会自动出现在录像列表中
- 文件通过
/recordings/{文件名}静态路径直接提供,无需额外文件服务器
- 用户数据保存在应用根目录下的
webcamserver.db(SQLite)。 - 密码以哈希形式存储(
User.PasswordHash),不保存明文。 Program.cs在启动时调用Database.EnsureCreated()自动建表,并通过AdminUser配置节确保管理员账户存在。
- 混合渲染模式:页面默认使用
@rendermode InteractiveServer,服务端实时交互确保录像列表、用户管理等数据操作的即时性。 - Blazor WASM 支持:
WebcamServer.Client作为 WebAssembly 客户端组件独立运行。 - 静态文件服务:
Program.cs中配置了/recordings虚拟路径,映射到Recordings:Path指定的实际录像目录,并通过自定义FileExtensionContentTypeProvider显式注册.mp4/.aac的 MIME 类型。 - 跨主机访问:直播页 JS 模块启动时会自动把
LiveStream配置里的localhost/127.0.0.1替换为服务器本机非环回 IPv4。