# 开箱即用 -简化版 WebRTC 直播项目(Spring Boot + WebSocket) **Repository Path**: lanyuan/WebRTC ## Basic Information - **Project Name**: 开箱即用 -简化版 WebRTC 直播项目(Spring Boot + WebSocket) - **Description**: 这是一个[开箱即用]简化版直播系统,以 WebRTC 作为音视频传输通道,以 WebSocket 作为信令(Signaling)与聊天消息的广播通道, 直播端(主播):/broadcaster.html 观看端(观众):/viewer.html 用最少的工程复杂度,快速跑通「采集摄像头 → WebRTC 推流 → 多端观看 → 聊天互动」的完整链路,方便二次开发与部署。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-04-16 - **Last Updated**: 2026-04-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 简化版 WebRTC 直播项目(Spring Boot + WebSocket)
WebRTC
## 1. 项目简介 这是一个**简化版直播系统**,以 **WebRTC** 作为音视频传输通道,以 **WebSocket** 作为信令(Signaling)与聊天消息的广播通道,前端页面为纯静态 HTML(无需构建前端工程)。 - **直播端(主播)**:`/broadcaster.html` - **观看端(观众)**:`/viewer.html` - **后端服务**:Spring Boot 3.x,提供静态资源与 WebSocket 端点 `/ws/live` 本项目目标是:用最少的工程复杂度,快速跑通「采集摄像头 → WebRTC 推流 → 多端观看 → 聊天互动」的完整链路,方便二次开发与部署。 --- ## 2. 功能特性 ### 2.1 直播(WebRTC) - **主播采集**:浏览器 `getUserMedia()` 获取摄像头/麦克风 - **实时传输**:WebRTC `RTCPeerConnection` 点对点推送音视频 - **多观众支持**:主播为每个观众维护独立 `RTCPeerConnection` ### 2.2 信令与聊天室(WebSocket) - **信令通道**:WebSocket `/ws/live` 转发 `offer/answer/ice` - **聊天室**:观众发送 `chat`,服务端广播给所有连接(观众与主播均可见) - **无登录用户编号**:观众端自动生成并持久化 `用户XXXX`,聊天显示为 `XX用户: 内容` ### 2.3 可靠性增强 - **断线自动重连**:主播端/观众端 WebSocket 断开后指数退避自动重连 - **服务端重启恢复**:主播重新上线后会自动对当前在线观众重新发起协商,观众无需手动刷新/重开 ### 2.4 设备能力 - **摄像头源切换**:直播端支持在内置/外接摄像头间切换,直播中使用 `replaceTrack()` 无缝切换画面 - **WeCam/手机摄像头**:支持动态接入(设备热插拔自动刷新 + 手动“刷新设备”) --- ## 2.5 页面截图 > 说明:截图文件在仓库根目录,Gitee 会直接渲染预览。 ### 2.5.1 观看端(用户端) ![用户端页面截图](用户端.png) ### 2.5.2 直播端(主播端) ![直播端页面截图](直播端.png) --- ## 3. 技术栈 - **后端**:Java 17、Spring Boot 3.2.x - **实时能力**: - WebRTC:音视频传输 - WebSocket:信令与聊天 - **前端**:原生 HTML/CSS/JavaScript(无框架) --- ## 3.1 开发工具与开发环境 ### 3.1.1 推荐开发工具 - **IDE**:IntelliJ IDEA / VS Code - **API/网络调试**:Chrome DevTools(Network / Console / WebRTC Internals) - **构建工具**:Maven - **反向代理/HTTPS**(生产推荐):Nginx + Let’s Encrypt ### 3.1.2 开发环境要求 - **操作系统**:Windows / macOS / Linux 均可 - **JDK**:17+ - **Maven**:3.8+ - **浏览器**:Chrome / Edge(建议使用较新版本) --- ## 4. 目录结构 ```text . ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── com/example/livestreaming │ │ │ ├── LiveStreamingApplication.java │ │ │ ├── config │ │ │ │ ├── WebSocketConfig.java │ │ │ │ └── WebSocketContainerConfig.java │ │ │ └── handler │ │ │ └── LiveStreamHandler.java │ │ └── resources │ │ ├── application.properties │ │ └── static │ │ ├── broadcaster.html │ │ └── viewer.html │ └── test └── log.md ``` --- ## 4.1 业务流程图(主播开播 / 观众观看 / 聊天) > 说明:这是“用户视角”的业务流程,强调页面交互与关键事件。 ```mermaid flowchart TD A[主播打开 /broadcaster.html] --> B[WebSocket 连接 /ws/live] B --> C[注册角色 role=broadcaster] C --> D[点击“开始直播”】【获取摄像头/麦克风权限】] D --> E[采集 localStream 并预览本地画面] V1[观众打开 /viewer.html] --> V2[WebSocket 连接 /ws/live] V2 --> V3[注册角色 role=viewer] V3 --> V4[服务端下发 viewer-id] V3 --> V5[服务端通知主播 viewer-joined] V5 --> O1[主播为该 viewer 创建 RTCPeerConnection] O1 --> O2[主播 createOffer + setLocalDescription] O2 --> O3[通过 WebSocket 转发 offer 给 viewer] O3 --> A1[viewer setRemoteDescription] A1 --> A2[viewer createAnswer + setLocalDescription] A2 --> A3[通过 WebSocket 转发 answer 给 broadcaster] A3 --> O4[主播 setRemoteDescription] O1 --> I1[双方交换 ICE candidate(WebSocket 转发)] I1 --> M1[WebRTC 建链成功] M1 --> P1[观众端 video 播放 remoteStream] V1 --> C1[观众发送聊天:用户XXXX: 内容] C1 --> C2[WebSocket 广播 chat 给所有会话] C2 --> C3[观众端显示消息] C2 --> C4[主播端画面左下角滚动显示消息] R1[服务端重启/网络抖动] --> R2[WS 断开] R2 --> R3[主播/观众指数退避自动重连] R3 --> R4[重新注册角色] R4 --> R5[主播重新对在线观众触发协商] R5 --> M1 ``` --- ## 4.2 直播数据流程图(媒体流 vs 信令/聊天) > 说明:这是“数据视角”的流程图,强调**媒体流走 WebRTC**,**控制/聊天走 WebSocket**。 ```mermaid flowchart LR subgraph BrowserA["主播浏览器 /broadcaster.html"] A1["getUserMedia 获取音视频"] A2["RTCPeerConnection(多 viewer)"] A3["WebSocket /ws/live"] end subgraph Server["Spring Boot 服务"] S1["静态资源 /static"] S2["WebSocket Handler /ws/live
(信令路由 + 聊天广播)"] end subgraph BrowserV["观众浏览器 /viewer.html"] V1["RTCPeerConnection"] V2["video.srcObject = remoteStream"] V3["WebSocket /ws/live"] end %% 静态资源 Server -->|"HTTP(S) 提供"| BrowserA Server -->|"HTTP(S) 提供"| BrowserV %% 信令/聊天(WebSocket) BrowserA <--> |"signal: offer/answer/ice"| S2 BrowserV <--> |"signal: offer/answer/ice"| S2 BrowserV --> |"chat: 用户XXXX"| S2 S2 --> |"chat broadcast"| BrowserA S2 --> |"chat broadcast"| BrowserV %% 媒体流(WebRTC,点对点) A1 --> A2 A2 -.->|"SRTP 音视频媒体流"| V1 V1 --> V2 ``` --- ## 5. 快速开始(本地) ### 5.1 环境要求 - JDK:**17+** - Maven:**3.8+** - 浏览器:推荐 **Chrome / Edge**(WebRTC 支持更完整) ### 5.2 启动后端 项目默认端口在 `src/main/resources/application.properties`: ```properties server.port=17867 ``` 启动: ```bash mvn spring-boot:run ``` 或: ```bash mvn -q test java -jar target/*.jar ``` ### 5.3 打开页面 - 直播端:`http://localhost:17867/broadcaster.html` - 观看端:`http://localhost:17867/viewer.html` > 注意:**摄像头/麦克风权限**在非 localhost 的 HTTP 页面通常会被浏览器禁止(见下文 HTTPS 部署说明)。 --- ## 6. 部署到服务器(必须看:HTTPS / 域名 / IP) ### 6.1 为什么必须 HTTPS? 浏览器对摄像头/麦克风有强制安全策略: - ✅ `https://你的域名/...`:允许 - ✅ `http://localhost/...`:允许(本地开发特例) - ❌ `http://服务器IP/...` 或 `http://你的域名/...`:通常禁止 `getUserMedia()` 因此:**要在服务器上真实使用摄像头采集,必须配置 HTTPS。** ### 6.2 推荐方案:Nginx 终止 HTTPS + 反向代理 Spring Boot > 最推荐,证书可信、浏览器策略最友好、也最符合生产部署习惯。 #### 6.2.1 Nginx 配置示例 将 Spring Boot 服务跑在 `127.0.0.1:17867`,由 Nginx 对外提供 HTTPS。 ```nginx server { listen 80; server_name your.domain.com; location /.well-known/acme-challenge/ { root /var/www/html; } location / { return 301 https://$host$request_uri; } } server { listen 443 ssl http2; server_name your.domain.com; ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem; # 静态页 + HTTP location / { proxy_pass http://127.0.0.1:17867; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # WebSocket(信令/聊天) location /ws/live { proxy_pass http://127.0.0.1:17867/ws/live; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } } ``` #### 6.2.2 证书申请(Let’s Encrypt) ```bash sudo apt update sudo apt install -y nginx certbot python3-certbot-nginx sudo certbot --nginx -d your.domain.com ``` #### 6.2.3 部署后访问 - 直播端:`https://your.domain.com/broadcaster.html` - 观看端:`https://your.domain.com/viewer.html` > 页面内 WebSocket 地址会根据页面协议自动选择 `ws/wss`,HTTPS 下会自动使用 `wss://.../ws/live`。 ### 6.3 只有 IP 的场景 如果没有域名,只能用 IP:浏览器依然要求 HTTPS。你需要: - 使用**包含 IP SAN** 的证书(自签或内网 CA) - 并在访问端系统/浏览器中**信任该证书/CA** 否则即使能打开页面,也可能因为“不安全”而被浏览器拒绝摄像头权限。 --- ## 7. 运行流程(架构说明) ### 7.1 WebSocket 信令协议(简化) WebSocket 端点:`/ws/live` 主要消息类型: - **注册角色** - `{"type":"role","role":"broadcaster"}` - `{"type":"role","role":"viewer"}` - **服务端下发 viewerId** - `{"type":"viewer-id","viewerId":""}` - **观众加入通知(给主播)** - `{"type":"viewer-joined","viewerId":""}` - **信令转发** - `{"type":"signal","target":"broadcaster","viewerId":"...","sdp":{...}}` - `{"type":"signal","target":"broadcaster","viewerId":"...","candidate":{...}}` - `{"type":"signal","target":"","viewerId":"","sdp":{...}}` - `{"type":"signal","target":"","viewerId":"","candidate":{...}}` - **聊天** - `{"type":"chat","user":"用户1234","message":"hello"}` ### 7.2 WebRTC 媒体流 - 主播:`localStream.getTracks()` → `pc.addTrack(track, localStream)` - 观众:`pc.ontrack` → 将远端 track 加入 `remoteStream` → `video.srcObject = remoteStream` --- ## 8. 常见问题(FAQ / 排障) ### 8.1 摄像头报错:必须 HTTPS 或 localhost 现象:`Error accessing camera: getUserMedia 需要 HTTPS 或 localhost...` 原因:浏览器策略限制。 解决: - 生产:按第 6 章配置 HTTPS(推荐 Nginx 终止 TLS) - 本地:使用 `http://localhost:17867/...` ### 8.2 服务端重启后观众无画面 本项目已做自动恢复: - 客户端 WebSocket 断线自动重连 - 主播重新上线会对在线观众重新协商 如果仍异常,建议打开浏览器控制台观察: - 观众端 `pc state connected` 是否出现 - 直播端是否能看到 `viewer-joined` ### 8.3 观众端黑屏但 pc 已 connected 浏览器自动播放策略可能拦截。项目已在观众端视频设置 `muted/playsinline` 并在 `ontrack` 主动 `play()`。 ### 8.4 外接/手机摄像头不出现 请在直播端: - 点击“**刷新设备**” - 或重新授予摄像头权限后再尝试 --- ## 9. 适用范围与限制说明 这是一个“教学/原型级”的简化项目,已尽量补齐核心链路,但仍有一些现实限制: - 未引入 TURN 服务,复杂网络(对称 NAT)下可能需要额外部署 TURN 才能稳定连通 - 未做鉴权/房间/多主播管理(目前默认一个主播、多观众) - 聊天为广播模型,未做敏感词/风控/持久化 --- ## 11. 后续功能计划(Roadmap) > 说明:这是一个“对齐抖音/快手等平台能力”的可落地迭代列表,建议按阶段推进(先把“稳定可用”做扎实,再做“互动/运营/商业化/平台化”)。 ### 11.1 阶段一:直播间能力补齐(MVP+) - **房间/多直播间**:支持 `roomId`,同一服务承载多个直播间(避免全局广播混流) - **观众列表与在线人数**:实时在线人数、加入/离开提示、观众列表(可分页) - **直播间状态机**:未开播/直播中/暂停/结束;观众端展示统一状态与占位图 - **清晰度与码率档位**:360p/540p/720p/1080p 档位切换;主播端码率自适应/手动锁定 - **弱网自适应**:丢包/抖动/RTT 监测 → 降码率/降分辨率;观众端弱网提示 - **自动重连完善**:断线重连、重协商、状态提示;支持“仅重连信令/仅重连媒体”策略 - **跨浏览器兼容**:Chrome/Edge/Safari 的差异处理与兼容清单 ### 11.2 阶段二:互动玩法对齐(平台互动) - **弹幕/评论滚动**:评论与弹幕不同样式/轨道;开关与频率控制 - **点赞/飘心**:观众端高频点赞,主播端/观众端动画展示(限流防刷) - **礼物系统(基础版)**:礼物面板、礼物连击、榜单(贡献榜/周榜) - **禁言/拉黑/踢人**:主播端管理能力;支持时长禁言与解禁 - **关注/收藏**:观众关注主播、收藏直播间(需要账户体系) - **聊天室增强**:@提及、表情包、消息撤回、置顶公告、消息审核 ### 11.3 阶段三:连麦 / PK / 多人互动(直播核心玩法) - **多主播/连麦**:支持多人推流与连麦互动(WebRTC Mesh / SFU 方向) - **PK(双人对战)**:两路直播画面合成布局、PK 倒计时、礼物计分 - **合流与布局**:画中画、分屏、宫格;主播端可拖拽布局 - **观众连麦申请**:举手申请、主播同意/拒绝、连麦排队 - **音频优化**:回声消除、噪声抑制、自动增益(AEC/NS/AGC)开关与参数 ### 11.4 阶段四:内容安全与合规(平台必备) - **鉴权与防刷**:Token、签名、限流、黑名单、IP/设备指纹(基础版) - **敏感词/垃圾信息过滤**:词库、正则、频率控制、风控策略 - **举报与审核流**:观众举报、后台审核、封禁与记录 - **水印**:主播/房间号/时间戳水印(防盗录/溯源) - **权限控制**:房间密码/付费房/白名单房(需账户与支付) ### 11.5 阶段五:稳定性/可观测性/运维(工程化) - **TURN 支持**:集成可配置 TURN(Coturn),提高对称 NAT/企业网络下的连通率 - **SFU 化演进**:引入 SFU(Janus/mediasoup/ion-sfu 等)以支持大规模观众 - **录制/回放**:服务端录制(SFU 录制/FFmpeg)与回放页面;支持分段与索引 - **监控与告警**:连接数、失败率、重连率、WebRTC 关键指标(RTT/丢包/抖动) - **日志与链路追踪**:结构化日志、traceId、WebSocket/信令关键事件落盘 - **灰度发布**:版本号、兼容策略、回滚方案 - **Docker / Compose 一键部署**:Spring Boot + Nginx + Coturn + 可选 SFU ### 11.6 阶段六:平台化与商业化(对齐大平台) - **账户体系**:手机号/邮箱/三方登录;昵称/头像/等级体系 - **主播体系**:认证、开播权限、封禁与申诉流程 - **推荐与增长**:直播间列表、热门榜、推荐流(基础算法/规则) - **数据看板**:在线峰值、停留时长、互动转化、礼物收入、复访率 - **支付与分成**:充值、礼物币、订单、对账、提现、分成策略 - **管理后台**:用户/房间/主播/礼物/风控/数据全量管理 --- ## 12. 讨论社群 QQ群: 1036383470 点击链接加入群聊 **【WebRTC 直播】**:[`https://qm.qq.com/q/uBdnQ3ifBI`](https://qm.qq.com/q/uBdnQ3ifBI) > 群二维码/群截图(可选):请将图片放到仓库根目录并命名为 `qqqun.jpg` QQ群 --- ## 13. 💰 打赏赞助 如果这个项目对你有帮助,欢迎打赏支持,我会持续完善项目与文档。 > 请将赞助二维码图片放在仓库根目录:`wxpay.png` wxpay --- ## 14. 🤝 贡献指南 我们欢迎所有形式的贡献!无论您是代码开发者、文档编写者,还是问题反馈者,您的贡献都将帮助 WebRTC 变得更好。以下是几种主要的贡献方式: ### 14.1 💻 代码贡献 - Fork 项目到您的 GitHub/Gitee 账号 - 创建特性分支(`git checkout -b feature/AmazingFeature`) - 提交更改(`git commit -m 'Add some AmazingFeature'`) - 推送到分支(`git push origin feature/AmazingFeature`) - 提交 Pull Request ### 14.2 📚 文档贡献 - 完善现有文档内容 - 补充使用示例和最佳实践 - 提供多语言翻译 - 修正文档错误 ### 14.3 🌟 其他贡献方式 - 报告并修复 Bug - 提出功能改进建议 - 参与社区讨论,帮助其他开发者 - 分享使用经验和案例 ### 14.4 💡 期望 欢迎提出更好的意见,帮助完善 WebRTC。 --- ## 10. License 本项目采用 **MIT License** 开源,允许自由使用、修改与分发,但不提供任何担保。详见仓库根目录 `LICENSE` 文件。