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. slate源码解析(三)- 定位

    接口定义 能够对于文字.段落乃至任何元素的精准定位 并做出增删改查,都是在开发一款富文本编辑器时一项最基本也是最重要的功能之一.让我们先来看看Slate中对于如何在文档树中定位元素是怎么定义的[源码] ...

  2. Ubuntu 22.04上安装docker方法及oracle 11g方法

    1.切换到管理员登录 ubt2204@ubt2204-Virtual-Machine:~/database$ su Password: 2.执行安装docker命令 root@ubt2204-Virt ...

  3. MySQL5.7版本单节点大数据量迁移到PXC8.0版本集群全记录-2

    本文主要记录57版本升级80版本的过程,供参考. ■ 57版本升级80版本注意事项 默认字符集由latin1变为utf8mb4 MyISAM系统表全部换成InnoDB表 sql_mode参数默认值变化 ...

  4. gitlab ci 用 cypress/playwright 做测试并展示结果至 mr

    前言 看了一下官方的教程好像都没有讲怎么将测试结果展示出来,只是给出测试的 ci 脚本,但根据 gitlab 官方的文档是有测试报告的展示的,所以这里给出一个基于 junit 测试报告的展示. 前期准 ...

  5. Python - 中文文本进行余弦相似度比较

    今天,在看论文的时候,突然想到了一件事情,爱是相对的,是双方的事情.那么"你爱我"和"你爱我"的相似度是多少呢?采用余弦相似度的方式来进行相似度比较.首先&qu ...

  6. docker 仓库-Harbor

    docker 仓库之分布式 Harbor: Harbor 是一个用于存储和分发docker镜像的企业级Registry服务器,由于Vmware 开源,其通过添加一些企业必须的功能特性,例如安全.标识和 ...

  7. 在不知带头节点地址的情况下删除和插入一个p指针指向的节点总结

    在不知带头节点地址的情况下删除和插入一个p指针指向的节点总结 (p指向的不是第一个,也不是最后一个)A->B->C *p->B 插入(在p结点之前插入q) 解析: 直接往p前插入q, ...

  8. CSP 2022 游寄

    Day -2147483648 官网有了通知,但选手注册不知为何坏掉了: 先开坑: Day -大概两个月 注册了,但老师还没给我审核呜呜呜 第一轮 早上 早上起床就直接来机房了,不用跑操欸嘿. 上午 ...

  9. EhCache使用详细介绍

    http://hi.baidu.com/yjl_zzh/item/18e6518397cdd1d9d1f8cdfb 2.EhCache的使用注意点    当用Hibernate的方式修改表数据(sav ...

  10. “技能兴鲁”职业技能大赛-网络安全赛项-学生组初赛 Crypto WP

    babyRSA 查看代码 from gmpy2 import * from Crypto.Util.number import * flag = 'flag{I\'m not gonna tell y ...