sync-player:使用 websocket 实现同步播放视频(可用于异地同步观影、观剧,支持本地文件,支持外挂字幕) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
liyang5945
V2EX    分享创造

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

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

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

    • 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]( 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
    异地恋的福音。
        11
    idealhs  
       2020-09-21 14:16:33 +08:00
    疫情提升了一波这种需求啊,这种的话之前有浏览器插件的,我目前在 FF 上用的 SyncWatch 还不错,只不过只支持在线视频。
    idealhs
    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  
       2021-09-20 16:28:05 +08:00
    感谢分享技术, 有幸拜读学习。
    小白刚开始接触,目前有遇到两个问题直接卡主不知道如何是好,还望赐教。

    布置 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
       2021-09-21 19:45:42 +08:00   1
    @maple52ck #21 你这问题太小白了,无力吐槽,你能打开 nginx 显示 welcome,就把 client 放到 nginx 的 html 目录下面,所以你的地址应该是这样:192.168.3.58:8088/client
    maple52ck
        23
    maple52ck  
       2021-09-22 16:43:01 +08:00
    @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
       2021-09-24 08:30:58 +08:00
    @maple52ck #23 加我 qq 吧,我博客里能找到 qq 号
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5252 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 08:09 PVG 16:09 LAX 00:09 JFK 03:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86