websocket实现实时直播
websocket实现实时直播
这篇文章我首发于简书,拿到这里发表不过分吧?点个赞再走呗!
作为一名web开发者,我使用websocket实现实时直播(滑鸡版)。
为什么是滑鸡版呢?因为他上不了生产,只能了解一下直播的思路,不过也挺有意思的!
思路
开发思路,我们使用websocket实现数据传输,后台就用spring boot集成了websocket,当然用netty自定义更好,我这里直接拿spring全家桶快速开发。
主播视频数据实时推送到服务端,然后由websocket推送给用户观看。最后把弹幕给实现了,这里我用Chrome浏览器+笔记本,谷歌+360极速浏览器。有些浏览器调用摄像头函数可能不一致,导致无法启动。
项目源码:https://github.com/xcocean/wszb

一、创建项目
创建一个spring boot项目wszb快速开发,maven如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
二、实现websocket服务端—画面传输
配置
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
controller
用来做页面控制
@Controller
public class WsController {
/**
* 用户可以看到画面
*/
@GetMapping("")
public String index() {
return "index";
}
/**
* 主播直播的画面
*/
@GetMapping("video")
public String video() {
return "video";
}
}
视频websocket
package com.lingkang.wszb.websocket;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
@ServerEndpoint(value = "/v")
@Component
public class VideoWebsocket {
//concurrent包的线程安全,用来存放每个客户端对应的WebSocket
private static ConcurrentHashMap<String, VideoWebsocket> webSocket = new ConcurrentHashMap<String, VideoWebsocket>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
// 表示主播
private static final String video = "v";
// 给用户一个id
private static int id = 0;
private static String thisUser = "";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
try {
String type = session.getQueryString();
if (type.equals("video")) {
// 表示主播
thisUser = video;
webSocket.put(thisUser, this);
System.out.println("有人加入,是主播");
} else {
// 表示用户
thisUser = String.valueOf(id);
webSocket.put(thisUser, this);
System.out.println("有人加入,是用户");
id = id + 1;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) throws Exception {
System.out.println("关闭连接:" + thisUser);
//需要清除当前和移除内存里的,不然还能接收信息
session.close();
webSocket.remove(thisUser);
}
/**
* 收到客户端消息后调用的方法
*/
//@OnMessage(maxMessageSize = 12)表示超出12个字节会自动关闭这个连接
@OnMessage(maxMessageSize = 56666)
public void onMessage(String message, Session session) throws IOException {
System.out.println("来自客户端的消息:" + message);
//群发消息
Iterator iter = webSocket.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
if (!entry.getKey().equals(video)) {//主播除外
webSocket.get(entry.getKey()).session.getBasicRemote().sendText(message);
}
}
}
/**
* 发生错误时调用
*/
@OnError
public void onError(Session session, Throwable error) throws Exception {
System.out.println("发生错误:" + thisUser);
session.close();
webSocket.remove(thisUser);
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户观看页面</title>
</head>
<body>
<h2 style="text-align: center;">这是用户观看页面</h2>
<img id="receiver" style="width: 500px;height: 450px;">
<script type="text/javascript" charset="utf-8">
//创建一个socket实例 ?user用来代表用户
var socket = new WebSocket("ws://localhost:8080/v?user");
//打开socket
socket.onopen = function () {
console.log("open success")
}
var image = document.getElementById('receiver');
//接收到消息的回调方法
socket.onmessage = function (data) {
image.src = data.data;
}
//连接关闭的回调方法
socket.onclose = function () {
console.log("close");
}
</script>
</body>
</html>
video.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>video</title>
</head>
<body>
<h2 style="text-align: center;">这是主播页面</h2>
<input type="button" title="开启摄像头" value="开启摄像头" onclick="getMedia()"/>
<video id="video" width="500px" height="500px" autoplay="autoplay"></video>
<canvas id="canvas" width="500px" height="500px"></canvas>
<button onclick="start()">开始直播</button>
<button onclick="stop()">停止直播</button>
<script>
//获得video摄像头区域
var video = document.getElementById("video");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
function getMedia() {
var constraints = {
video: {width: 500, height: 500},
audio: false
};
/*
这里介绍新的方法:H5新媒体接口 navigator.mediaDevices.getUserMedia()
这个方法会提示用户是否允许媒体输入,(媒体输入主要包括相机,视频采集设备,屏幕共享服务,麦克风,A/D转换器等)
返回的是一个Promise对象。
如果用户同意使用权限,则会将 MediaStream对象作为resolve()的参数传给then()
如果用户拒绝使用权限,或者请求的媒体资源不可用,则会将 PermissionDeniedError作为reject()的参数传给catch()
*/
var promise = navigator.mediaDevices.getUserMedia(constraints);
promise.then(function (MediaStream) {
video.srcObject = MediaStream;
video.play();
}).catch(function (PermissionDeniedError) {
console.log(PermissionDeniedError);
})
}
var socket = new WebSocket("ws://localhost:8080/v?video");
//打开socket
socket.onopen = function () {
console.log("open success")
}
//接收到消息的回调方法
socket.onmessage = function (event) {
console.log(event)
}
//连接关闭的回调方法
socket.onclose = function () {
console.log("close");
}
var interval
function start() {
interval = window.setInterval(function () {
ctx.drawImage(video, 0, 0, 500, 500);
socket.send(canvas.toDataURL("image/jpeg", 0.5));
}, 60);
}
function stop() {
clearInterval(interval)
}
</script>
</body>
</html>
演示:专业操作,请勿模仿

实现即时弹幕
弹幕我就懒得实现了,再new 一个websocket做弹幕链接,然后用js把接收的弹幕在显示地方移动过来就行了。
http实时语音
https://www.jianshu.com/p/7965c9faafa6
websocket实现实时直播的更多相关文章
- WebSocket+MSE——HTML5 直播技术解析
作者 | 刘博(又拍云多媒体开发工程师) 当前为了满足比较火热的移动 Web 端直播需求,一系列的 HTML5 直播技术迅速的发展起来. 常见的可用于 HTML5 的直播技术有 HLS.WebSock ...
- Asp.net+WebSocket+Emgucv实时人脸识别
上个月在网上看到一个用web实现简单AR效果的文章,然后自己一路折腾,最后折腾出来一个 Asp.net+WebSocket+Emgucv实时人脸识别的东西,网上也有不少相关资料,有用winform的也 ...
- [转]使用 HTML5 WebSocket 构建实时 Web 应用
HTML5 WebSocket 简介和实战演练 本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例 ...
- 使用 HTML5 WebSocket 构建实时 Web 应用
原文地址:http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/ HTML5 WebSocket 简介和实战演练 本文主要介绍 ...
- springboot搭建一个简单的websocket的实时推送应用
说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...
- (转)使用 HTML5 WebSocket 构建实时 Web 应用
HTML5 WebSocket 简介和实战演练 本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例 ...
- WebSocket实现实时聊天系统
WebSocket实现实时聊天系统 等闲变却故人心,却道故人心易变. 简介:前几天看了WebSocket,今天体验下它的实时聊天. 一.项目介绍 WebSocket 实时聊天系统自己一个一码的搞出来还 ...
- 使用WebSocket构建实时WEB
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3795075.html ...
- Practical Node.js (2018版) 第9章: 使用WebSocket建立实时程序,原生的WebSocket使用介绍,Socket.IO的基本使用介绍。
Real-Time Apps with WebSocket, Socket.IO, and DerbyJS 实时程序的使用变得越来越广泛,如传统的交易,游戏,社交,开发工具DevOps tools, ...
- Django实现websocket完成实时通讯,聊天室,在线客服等
一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...
随机推荐
- angular + express 实现websocket通信
最近需要实现一个功能,后端通过TCP协议连接雷达硬件的控制器,前端通过websocket连接后端,当控制器触发消息的时候,把信息通知给所以前端: 第一个思路是单独写一个后端服务用来实现websocke ...
- Spring Boot 目录遍历--表达式注入--代码执行--(CVE-2021-21234)&&(CVE-2022-22963)&&(CVE-2022-22947)&&(CVE-2022-2296)
Spring Boot 目录遍历--表达式注入--代码执行--(CVE-2021-21234)&&(CVE-2022-22963)&&(CVE-2022-22947)& ...
- Openssl Des3对压缩文件进行加密命令详解
群友提问: 致力于明天: tar -cvf - WMG_Back_"$Today"|openssl des3 -salt -k hY91gd3GJAAfghECleLwWQAPGK ...
- .NET 数据库大数据 方案(插入、更新、删除、查询 、插入或更新)
1.功能介绍 (需要版本5.0.45) 海量数据操作ORM性能瓶颈在实体转换上面,并且不能使用常规的Sql去实现 当列越多转换越慢,SqlSugar将转换性能做到极致,并且采用数据库最佳API 操作数 ...
- NFC and Contactless Technologies
NFC and Contactless Technologies NFC与无接触技术 NFC technology enables simple and safe two-way interactio ...
- 使用 OpenTelemetry 构建 .NET 应用可观测性(4):ASP.NET Core 应用中集成 OTel
目录 前言 使用 elastic 构建可观测性平台 在 ASP.NET Core 应用中集成 OTel SDK 安装依赖 基础配置 Instrumentation 配置 创建自定义 Span 和 Me ...
- client-go实战之七:准备一个工程管理后续实战的代码
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<client-go实战> ...
- Kubernetes:kube-apiserver 之 scheme(一)
0. 前言 在进入 kube-apiserver 源码分析前,有一个非常重要的概念需要了解甚至熟悉的:资源注册表(scheme). Kubernetes 中一切皆资源,管理的是资源,创建.更新.删除的 ...
- Noi-Linux 2.0 装机+使用整合
写在前面 网上的东西比较多,也比较杂乱,不是很方便,所以我整合了一些关于 Noi-Linux2.0 虚拟机装机方法+代码编辑环境+实地编程的介绍,看完至少能用起来打代码了. NOI 官网公告(JS 开 ...
- Redis主从复制部署小结
Redis主从 搭建主从架构 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离. 主从数据同步原理 全量同步 主从第一次建立连接时,会执行全量同 ...