V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
liyang5945
V2EX  ›  分享创造

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

  •  
  •   liyang5945 · 2020-09-21 08:53:26 +08:00 · 3020 次点击
    这是一个创建于 442 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

    功能介绍&特性:

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

    演示 demo:

    web 版同步效果

    wI60je.gif

    客户端与 web 版同步效果

    wofbYd.gif

    原理:

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

    项目所用到的

    如何使用:

    本项目的核心是 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
    • 第三方视频地址

    wfntdU.png

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

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

    wfnYZT.png

    使用场景 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⭐⭐⭐

    24 条回复    2021-09-24 08:30:58 +08:00
    libracloud
        1
    libracloud  
       2020-09-21 09:29:40 +08:00
    整挺好,
    Tigerw
        2
    Tigerw  
       2020-09-21 09:49:08 +08:00
    适合和女友一起看某片
    Acoffice
        3
    Acoffice  
       2020-09-21 09:54:21 +08:00
    支持!
    其实站内之前有个[t/706555]( https://www.v2ex.com/t/706555)
    justin2018
        4
    justin2018  
       2020-09-21 13:17:48 +08:00
    不错 可以不用自己搭建服务器了 😁
    go
        5
    go  
       2020-09-21 13:27:31 +08:00
    太长不看
    只问问 "和一个异地的人一起看电影" 这个需求实现没
    liyang5945
        6
    liyang5945  
    OP
       2020-09-21 13:30:07 +08:00
    @go #5 当然是实现了啊
    kuaner
        7
    kuaner  
       2020-09-21 13:38:07 +08:00
    用 ws 来同步,播放,暂停,跳转这些操作嘛?
    zrp1994
        8
    zrp1994  
       2020-09-21 13:39:55 +08:00 via Android
    为什么不用 webrtc 呢?串流服务器都不用

    https://getmetastream.com/
    liyang5945
        9
    liyang5945  
    OP
       2020-09-21 13:45:51 +08:00
    @zrp1994 #8 直接传输画面或视频流之类的的对网络上传带宽要求都比较高,我现在住的一个垃圾公寓,上传带宽只有 1Mbs,所以使用了 websocket
    jackrebel
        10
    jackrebel  
       2020-09-21 13:46:00 +08:00
    异地恋的福音。
    idealhs
        11
    idealhs  
       2020-09-21 14:16:33 +08:00
    疫情提升了一波这种需求啊,这种的话之前有浏览器插件的,我目前在 FF 上用的 SyncWatch 还不错,只不过只支持在线视频。
    fangcan
        12
    fangcan  
       2020-09-21 15:55:34 +08:00
    建议加个随机匹配另外一只单身狗一起看的功能
    lucifer69
        13
    lucifer69  
       2020-09-21 16:19:52 +08:00
    异地一起看视频,可以一起边看边讨论了
    wpblank
        14
    wpblank  
       2020-09-21 16:33:21 +08:00 via iPhone
    带聊天再发展发展就成弹幕应用了,话说任意用户点暂停是不是所有同步暂停。
    liyang5945
        15
    liyang5945  
    OP
       2020-09-21 16:40:44 +08:00
    @wpblank #14 是的
    Taurus12C
        16
    Taurus12C  
       2020-09-22 14:31:16 +08:00
    我也做过一个,小程序、app 、web 三端得,不过我用的解决方案是流服务器,nginx-rtmp+OBS+vue+workerman(这里主要实现弹幕聊天)
    bianqurenfm
        17
    bianqurenfm  
       2020-09-23 18:31:31 +08:00
    模拟在线影院,预约看同一场电影的人在房间里实时弹幕?
    liyang5945
        18
    liyang5945  
    OP
       2020-09-23 18:37:07 +08:00
    @bianqurenfm #17 差不多吧,不过我这个没有弹幕功能,可以用其他的工具开着语音边看边聊
    bianqurenfm
        19
    bianqurenfm  
       2020-09-23 18:41:32 +08:00
    @liyang5945 目前看很多视频网站弹幕的人都以为弹幕是实时的,其实弹幕不是实时的,视频也不是同步的,也许你做这个会颠覆一种新模式?
    codehz
        20
    codehz  
       2020-09-25 16:11:40 +08:00
    @liyang5945 #9 webrtc 可以用 datachannel 来传输二进制数据
    (意义就是可以在局域网中直接使用而不需要任何服务器)
    (广域网则可以无缝衔接到用 STUN 服务器)
    maple52ck
        21
    maple52ck  
       78 天前
    感谢分享技术, 有幸拜读学习。
    小白刚开始接触,目前有遇到两个问题直接卡主不知道如何是好,还望赐教。

    布置 Web 端时到“浏览器打开 192.168.3.58/client/”无法进入,前面步骤均已完成,GoEasy appkey 也以填入,环境都模拟了您的,包括端口改为 8088,内网 IP 设为 192.168.3.58 ,WEB 访问 192.168.3.58:8088 是 nginx 的“Welcome”页面,就是进不去 Client,不得要领。
    想尝试改 SPlayer 源码,第一步安装 goeasy 就卡主了不知道怎么弄😓。。。第一次接触源码~~~
    可以的话我留下邮箱希望可以跟您再多学习!~
    [email protected]
    感恩!
    liyang5945
        22
    liyang5945  
    OP
       76 天前   ❤️ 1
    @maple52ck #21 你这问题太小白了,无力吐槽,你能打开 nginx 显示 welcome,就把 client 放到 nginx 的 html 目录下面,所以你的地址应该是这样:192.168.3.58:8088/client
    maple52ck
        23
    maple52ck  
       76 天前
    @liyang5945 嗯嗯!确实是刚接触,照您说的把 Client 放到 html 目录已经解决问题了,因为上面说的是根目录,所以一直不得要领,现在已经搞定第一种方法啦!感谢!
    然后我再尝试 SPlayer 这个,到打包 build 那步了,但是提示“ValidationError: Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
    - configuration.devtool should match pattern "^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$".
    BREAKING CHANGE since webpack 5: The devtool option is more strict.”
    我目前查找到的原因是说 Webpack V5 相较于 V4 有更严格的要求,所以 devtool 的赋值不能为空好像,但是我还没有找到应该改哪里哪个文件的赋值,正在研究哈哈~~
    最后再次感谢大大分享!这是目前我遇到最厉害的同步观影了!我也是同样对体验有要求的哪类人,所以超级适合我!感恩!~
    liyang5945
        24
    liyang5945  
    OP
       74 天前
    @maple52ck #23 加我 qq 吧,我博客里能找到 qq 号
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3870 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 17ms · UTC 09:00 · PVG 17:00 · LAX 01:00 · JFK 04:00
    ♥ Do have faith in what you're doing.