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实现实时直播的更多相关文章

  1. WebSocket+MSE——HTML5 直播技术解析

    作者 | 刘博(又拍云多媒体开发工程师) 当前为了满足比较火热的移动 Web 端直播需求,一系列的 HTML5 直播技术迅速的发展起来. 常见的可用于 HTML5 的直播技术有 HLS.WebSock ...

  2. Asp.net+WebSocket+Emgucv实时人脸识别

    上个月在网上看到一个用web实现简单AR效果的文章,然后自己一路折腾,最后折腾出来一个 Asp.net+WebSocket+Emgucv实时人脸识别的东西,网上也有不少相关资料,有用winform的也 ...

  3. [转]使用 HTML5 WebSocket 构建实时 Web 应用

    HTML5 WebSocket 简介和实战演练 本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例 ...

  4. 使用 HTML5 WebSocket 构建实时 Web 应用

    原文地址:http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/ HTML5 WebSocket 简介和实战演练 本文主要介绍 ...

  5. springboot搭建一个简单的websocket的实时推送应用

    说一下实用springboot搭建一个简单的websocket 的实时推送应用 websocket是什么 WebSocket是一种在单个TCP连接上进行全双工通信的协议 我们以前用的http协议只能单 ...

  6. (转)使用 HTML5 WebSocket 构建实时 Web 应用

    HTML5 WebSocket 简介和实战演练 本文主要介绍了 HTML5 WebSocket 的原理以及它给实时 Web 开发带来的革命性的创新,并通过一个 WebSocket 服务器和客户端的案例 ...

  7. WebSocket实现实时聊天系统

    WebSocket实现实时聊天系统 等闲变却故人心,却道故人心易变. 简介:前几天看了WebSocket,今天体验下它的实时聊天. 一.项目介绍 WebSocket 实时聊天系统自己一个一码的搞出来还 ...

  8. 使用WebSocket构建实时WEB

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3795075.html ...

  9. Practical Node.js (2018版) 第9章: 使用WebSocket建立实时程序,原生的WebSocket使用介绍,Socket.IO的基本使用介绍。

    Real-Time Apps with WebSocket, Socket.IO, and DerbyJS 实时程序的使用变得越来越广泛,如传统的交易,游戏,社交,开发工具DevOps tools, ...

  10. Django实现websocket完成实时通讯,聊天室,在线客服等

    一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...

随机推荐

  1. 文心一言 VS 讯飞星火 VS chatgpt (98)-- 算法导论9.3 4题

    四.用go语言,对一个包含n个元素的集合,假设一个算法只使用比较来确定第i小的元素,证明:无需额外的比较操作,它也能找到第 i-1 小的元素和第 n-i大的元素. 文心一言: 在这个问题中,我们要使用 ...

  2. 微服务使用openfeign调用单点的会话失效问题

    项目Springcloud,认证中心方式实现SSO使用开源框架Sa-Token 本身的单独访问每个客户端服务的单点就没有问题.然后单点通过Fegin调用就不好使了! 主要使用的Sa-Token的微服务 ...

  3. 前端三件套系例之BootStrap—— BootStrap组件、BootStrap插件

    文章目录 1 BootStrap组件 1 Glyphicons 字体图标 2 下拉菜单 2.1 基本使用 2.2 对齐 2.3 标题 2.4 分割线 2.5 禁用的菜单项 3 按钮组 3.1 基本使用 ...

  4. QQ机器人整理合集

    QQ机器人有什么用呢? QQ机器人可以实现包括自动回复.定时推送.发送图片QQ机器人,营销圈用的比较多,可以开发各种自动功能等等.用其制作的QQ机器人程序 机器人框架+插件 小栗子机器人 官网:htt ...

  5. Python学习 —— 初步认知

    写在前面 Python是一种流行的高级编程语言,具有简单易学.代码可读性高.应用广泛等优势.它是一种解释型语言,可以直接在终端或集成开发环境(IDE)中运行,而无需事先编译. Python的安装 Py ...

  6. math库常用函数+产生随机数总结

    math库常用函数+产生随机数总结 1.对x开平方 double sqrt(x)://返回值为double类型,输入的x类型随意,只要是数的类型 2.求常数e的x次方 double exp(x);// ...

  7. JS个人总结(2)

    1.null被认为是一个空的对象引用..如果定义的变量准备将来用保存对象,最好将该变量初始化null.即 var x=null;这样只有检查null值就可以知道这个变量是否已经保存了一个对象.. 2. ...

  8. 带着问题去分析:Spring Bean 生命周期

    1: Bean在Spring容器中是如何存储和定义的 Bean在Spring中的定义是_org.springframework.beans.factory.config.BeanDefinition_ ...

  9. P8368 [LNOI2022] 串 题解

    题目链接 题目分析 题目要求我们构造一个最长的 \(T\) 序列,我们首先从每个 \(T_i\) 入手,思考如何安排才能合法. 容易观察到对于每个 \(T_i\),合法的 \(T_{i-1}\) 有两 ...

  10. Web服务器及Web应用服务器

    1. 如果仅需要展示html页面,而不要其他功能,apache:(nginx也是类似功能:它本身仅提供html静态页面的功能,不能支持jsp.java servlet.asp等功能,但通过同其他应用服 ...