sync-player:使用 websocket 实现同步播放视频(可用于异地同步观影、观剧,支持本地文件,支持外挂字幕)

liyang5945:前段时间我有这样一个需求,想和一个异地的人一起看电影,先后在网上找了一些方案,不过那几个案都有一些缺点

  • coplay 一个浏览器插件,只能播放各大视频网站的视频,视频资源有限,我想要看的视频没有,比如一些经典电影和美剧之类

  • 微光 APP 还是上面的问题,而且只有手机端

  • 向日葵等远程桌面 受限于网络问题,卡顿很严重,体验不好

作为一个对用户体验有追求的切图仔,我是一个下载党,看电影必须下载到本地看,基本不看视频网站上的玩意

那么有没有能实现同步播放本地文件的方案呢,答案是肯定的,经过我的一些摸索和研究,我实现了本地文件的同步播放,同时支持 PC 和手机端,而且还支持外挂字幕等高级功能,如何实现请往下看。

功能介绍&特性:

一个可以同步看视频的播放器,可用于异地同步观影、观剧,支持多人同时观看。
本项目有两个版本,web 版运行在浏览器上,可跨平台,不限操作系统、设备,功能简单适用于要求不高的用户。还有基于 SPlayer(射手影音)DIY 的客户端版本(windows 、MAC),播放 4K 高清文件、外挂字幕,统统没问题。

演示 demo:

web 版同步效果

sync-player:使用 websocket 实现同步播放视频(可用于异地同步观影、观剧,支持本地文件,支持外挂字幕)

客户端与 web 版同步效果

sync-player:使用 websocket 实现同步播放视频(可用于异地同步观影、观剧,支持本地文件,支持外挂字幕)

原理:

基于 websocket 实现,与一些用 websocket 实现的聊天室类似,只不过这个聊天室里的消息换成了播放暂停的动作和时间信息,客户端收到消息后执行相应的动作:播放、暂停、快进,以达到同时播放的效果。

项目所用到的

  • node.js
  • socket.io
  • HTML5 video API
  • vue.js

如何使用:

本项目的核心是 websocket,所以至少需要一台服务器提供 websocket 服务,websocket 服务可以自己部署,可以使用第三方平台 GoEasy 提供的 websocket 服务(可免费使用两个月)。

1 、自己部署:websocket 服务器可以是一台具有公网 IP 的云服务器,也可以是一台具有公网 IP 的普通 PC,没有公网 IP 也可以。你也可以使用 zerotier 或其他 VPN 工具将两台设备组成一个大局域网,让它们能互相通信。websocket 服务器操作系统不限,只要有 node.js 环境。

websocket 服务端部署方法:安装 node.js 环境,将 server 目录移动到服务器上,进入 server 目录,执行以下命令

安装项目依赖包


# 安装项目依赖包

npm install 

# 启动 websocket 服务

node index.js

2 、使用 GoEasy 的 websocket 服务

注册 GoEasy 开发者账号并创建一个应用,获得 appkey,复制到本项目相应位置即可。

GoEasy 官网: https://www.goeasy.io

无论是使用哪种 websocket 服务都可以,本项目写了两套代码,只需将不用的那套注释掉即可(默认 GoEasy)。

除了 websocket 服务器之外,还需要两个 http 服务端,一个是 web 服务端(提供 html 、css 、js 等文件的访问),一个是视频服务端(提供视频文件访问)。

你可以将 web 服务部端署到以下位置:

  • 具有公网 IP 的服务器
  • github-pages 或国内的码云提供的静态 web 服务
  • localhost(本地服务器),同一个局域网内的设备访问该服务器内网 IP

视频文件只需一个视频地址就行,也有以下几种选择:

  • 具有公网 IP 的服务器
  • localhost(本地服务器),同一个局域网内的设备访问该服务器内网 IP
  • 第三方视频地址

sync-player:使用 websocket 实现同步播放视频(可用于异地同步观影、观剧,支持本地文件,支持外挂字幕)

使用场景 1:云服务器带宽足够大(至少要大于播放视频的码率),云服务器既可以作为 websocket 服务端,也可以作为 http 服务端。上图中所有设备都访问云服务器的 ip 或域名。

使用场景 2:云服务器的带宽很小,这时候它只能作为 websocket 服务端,这时可以用上图中的 PC1 和 PC2 作为 http 服务端,PC1 和 PHONE1 在一个内网访问 PC1 的内网 IP,PC2 和 PHONE2 在一个内网访问 PC2 的内网 IP,PC3 可作为自己的 http 服务端,PHONE3 若是有提供视频文件的服务端,也可以使用。

sync-player:使用 websocket 实现同步播放视频(可用于异地同步观影、观剧,支持本地文件,支持外挂字幕)

使用场景 3:需要使用 zerotier 或其他 VPN 工具将异地设备组成一个大局域网,其中任意一台 PC 均可作为 websocket 服务端和 http 服务端(需要上传带宽足够大)。上图中各设备都访问那台 PC 的内网 ip 即可。

最简单的使用方法,下载 nginx 开启一个本地服务器,下载本项目 client 文件夹放到到 nginx 根目录里,视频文件也放到里面。注册 goeasy 开发者账号并创建一个应用,获得 appkey,并填入到 appkey 到代码(script/main.js)相应位置。然后浏览器打开 192.168.3.58/client/,填入你的视频地址192.168.3.58/movie/xxx.mp4或网络视频地址,对方也这样操作一番,即可实现同步播放视频,不过这种方法只能白嫖两个月。

web 版本的功能比较简单,而且受限于网络问题,快进之类的操作需要缓冲一段时间。如果你不满足 web 版功能,对用户体验有更高的要求,如支持更多文件格式、播放高清本地视频文件、外挂字幕等,我也找到了另一种方式来满足你的需求。

那就是 DIY 一个开源的播放器的源码:SPlayer(射手影音)。

射手影音官网: https://splayer.org

源码地址: https://github.com/chiflix/splayerx

在以electron + 播放器为关键字一番搜索之后,我找到了这个基于 electron 实现的开源播放器,并下载了源码来研究。

经过一番研究之后,我找到了控制视频播放、暂停、快进的代码位置,并将控制同步的代码移植了进去,从而也实现了同步功能,并且与 web 版兼容。

具体方法请看:修改教程

本项目部分图标样式来源于此项目: coplay

本项目 github 地址:点击前往 ,欢迎⭐⭐⭐STAR⭐⭐⭐

如何让 websocket 连接走代理?

ob:请教下,目前有一台 centos 服务器,装了 ss 客户端,配置好 http_proxy 和 https_proxy,所有的 http 请求,目前可以访问被墙网站,现在的问题是,怎么让 websocket 也通过代理来请求被墙的服务地址?把 all_proxy 都设置上了,也是不管用。搜了很多资料没找到解决办法,特来请求帮助,谢谢。liumingha…

使用 websocket 发送数据给前端过段时间后后端程序卡死

swqslwl:后端程序启动后 120 秒左右就卡死了,无论推送速度是快还是慢,总是会卡死。没有任何报错信息。 后端用的是 go,gin 框架中开了 2 个协程,1 个用来接受数据,1 个用来入库和用 websocket 发给前端。 接受数据和数据库写入都没问题。应该就是 websocket 推给前端时的问题。也检查了协程数,都是正常的。 var upgra…

关于 Sync.Mutex 的竞争问题

Chaox:var mu sync.Mutex func produce(ch chan<- int){ for i:=0;i<10;i++{ mu.Lock() ch<-i fmt.Println("produce:"+strconv.Itoa(i)) mu.Unlock() } } func consumer(ch <- chan…

golang 使用 websocket 发送数据给前端,总是会有丢包的情况发生

swqslwl:报错有时是 write:broken pipe. 有时是 An established connection was aborted by the software in your host machine. 有时不报错,wrieshark 抓包发现包全部发出去了,但前端就是会丢包。 上个帖子犯了个低级错误用了共享内存变量,现在改为用 cha…

[求助] React WebSocket Stomp 后端返回不能实时显示

qwertty01:单独调用 addLog 是可以实时显示的 但是调用 connect 和 sendMessage 时,不能实时显示必须点击一下才能显示出来 能不能用 useEffect ? export const WebSocketPage = () => { const [log, setLog] = useState([]) const [st…