SyncTV 多人同步观影平台部署实战与多人语音中转

作者:阿白叔 发布时间: 2025-12-11 阅读量:21 评论数:0

SyncTV 介绍

2e0c00a6fba886cb7021c48403dce24e-5csq.png

上图是Sync TV 的界面截图。按照官方的介绍说法,支持以下功能:

  • 同步观看

    • 视频同步

    • 直播同步

  • 影院模式

    • 聊天

    • 弹幕

  • 代理

    • 视频代理

    • 直播代理

    • 代理缓存

  • 视频解析

    • Alist

    • Bilibili

    • Emby

  • 直播解析

    • 哔哩哔哩

  • WebRTC

Sync TV Docker部署

我使用的环境是1panel,因此我用此面板进行演示,其他的工具也是类似的。

我这边主要演示使用docker-compose 进行部署。

version: '3.3'
services:
  synctv:
    image: 'synctvorg/synctv:latest'
    container_name: synctv
    restart: unless-stopped
    ports:
      - '8080:8080/tcp'
      - '8080:8080/udp'
    volumes:
      - /opt/synctv:/root/.synctv
    environment:
      - PUID=0
      - PGID=0
      - UMASK=022
      - TZ=Asia/Shanghai

建议将外部的暴露端口修改一下,改成别的,比如我用的是8210。后面再进行反向代理。

将上面的文件创建好,命名为“docker-compose.yml”

或者 使用 1Panel 直接把上面的复制过去。

部署成功可以输入服务器IP:端口号访问测试。

到这一步已经基本可以使用了。RTMP创建直播流推流我没测试成功,不过也比较吃带宽,我索性就不用了。

全网教程我看了很多,基本上到这一步或者再加一步反向代理就结束了,而我这边还有更完善的教程。

P2P 设置

SyncTV 当有多个用户观看同一个视频时,服务器需要承受很大的网络压力。这时,P2P就可以派上用场了。

如果你想要在看影片的时候能够P2P链接的话,需要配置一下。

SyncTV 借助 CDNBye 提供的 P2P 服务,可以轻易实现视频的 P2P 传输。

只需要在 CDNBye 面板 注册一个账号,如果你的域名备案过那么可以使用国内的区域,否则使用国外的区域,比如 hk ,然后添加你的域名即可。

swarmcloud-ojpo.png

然后前往 SyncTV 的 管理后台 页面中的 系统设置,修改 Swarm Cloud 区域 为对应的区域,比如 hk 即可。

zone-d5yu.png

区域选择

  • 广州:cn

  • 香港:hk

  • 美国:us

  • 欧洲: eu

反向代理设置

依次填写。

代理地址是127.0.0.1:端口

端口就是你上面开放的端口,没改就是8080.

到这步,就能通过域名正常访问到了。

补充一点!

官方的教程中说使用反向代理是需要往server字段添加下面的内容的:

client_max_body_size 20m;
proxy_cache off;
proxy_buffering off;
proxy_http_version 1.1;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header REMOTE-HOST $remote_addr;

location = /api/room/ws {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "";
    proxy_set_header Range $http_range;
}

语音功能中转配置

不过依旧有个问题,就是语音他本质还是靠P2P去转发的,使用我这边还可以添加turn服务器进行中转。

我试图从修改config.yaml来开启webrtc的中转,翻了一下官方的文档,似乎是不支持的,他默认是通过Google的stun服务器去打通进行链接。

我后来想的方案是通过前端去劫持websocket的数据,实践证明是可行的。

接下来讲实践步骤。

部署Coturn中转服务器

下面的方案二选一哈!!!

  1. 用docker,直接用docker的方案:

docker run -d \

  --name=coturn \

  --network=host \

  --restart=always \

  coturn/coturn \

  -n \

  --log-file=stdout \

  --listening-port=3478 \

  --min-port=49160 \

  --max-port=49200 \

  --external-ip=你的公网IP \

  --user=synctv:synctvpassword \

  --realm=synctv.local \

  --lt-cred-mech

  1. 或者也可以像上面面板那样子使用docker-compose

填入下面的配置

version: '3'

services:
  coturn:
    image: coturn/coturn
    container_name: coturn
    restart: always
    # 🔥 核心:必须使用 Host 模式
    # 这样 Coturn 才能直接管理服务器的 UDP 端口,性能最高且不出错
    network_mode: host
    
    command:
      - -n                            # 不使用配置文件,全靠命令行参数
      - --log-file=stdout             # 日志输出到 Docker 控制台
      - --min-port=49160              # 语音数据端口起点
      - --max-port=49200              # 语音数据端口终点
      - --listening-port=3478         # 信令握手端口
      - --fingerprint                 # WebRTC 校验机制
      - --lt-cred-mech                # 启用长期凭证机制 (WebRTC 必须)
      
      # 👇 这里填你的公网 IP (必须和 Nginx 注入脚本里的一致)
      - --external-ip=
      
      # 👇 域名 (可以随便填,或者填你的 IP)
      - --realm=
      
      # 👇 账号密码 (必须和 Nginx 注入脚本里的一致)
      # 格式是 用户名:密码
      - --user=synctv:synctvpassword

后续有个nginx的脚本注入,用于劫持,账号密码不建议动,非要动你得懂得后面怎么改!

安装好后我们测试一下连通性!

点击网址 Coturn STUN/TURN 服务器测试

选择“TURN测试”,挨个输入你的参数:

截图的不是我的,网站自带的,成功配置下面就是类似截图的样子。

对了,上面使用docker配置好别忘记放行端口:

3478 tcp/udp
49160-49200 udp

放行上述的端口!

测试成功后我们就可以进行下一步了!

Nginx前端反代劫持!

如果能做到这一步,应该说明你是有一定基础的!所以我教程就简单点了!!!

这一步的原理就是通过前端把你的websocket的数据劫持给给代理服务器,只需要修改nginx的配置文件即可。

我使用的是1panel 的网站服务,也是支持nginx语法的!

点开后往指定的位置添加内容:

server {
    listen 443 ssl http2;
    server_name wto.abaishu.fun;
    
    # ... SSL 和日志配置 ...

    # 1. 优化 WebSocket (单独处理,不注入脚本)
    location = /api/room/ws {
        proxy_pass http://127.0.0.1:8210;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }

    # 2. 网页主入口 (注入脚本)
    location / {
        proxy_pass http://127.0.0.1:8210;
        
        # 基础 Header
        proxy_set_header Host $host;
        proxy_set_header Range $http_range;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "";

        # 🔥 核心:禁用压缩,否则无法替换内容
        proxy_set_header Accept-Encoding ""; 

        # 🔥 核心:注入 JS 脚本
        sub_filter_once on;
        sub_filter_types text/html;
        sub_filter '</head>' '
        <script>
        (function() {
            // Base64 解码配置 (c3luY3R2 -> synctv)
            const MY_TURN_CONFIG = {
                urls: "turn:你的公网IP:3478",
                username: atob("c3luY3R2"), 
                credential: atob("c3luY3R2cGFzc3dvcmQ=")
            };

            console.log("%c🔥 SyncTV 劫持补丁(安全版)已加载", "color: #00aa00; font-weight: bold;");

            const OriginalRTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection;
            if (!OriginalRTCPeerConnection) return;

            // 劫持构造函数
            window.RTCPeerConnection = function(config) {
                if (!config) config = {};
                // 强行覆盖为我们的 TURN
                config.iceServers = [MY_TURN_CONFIG];
                console.log("🔒 已注入混淆后的 TURN 凭证");
                return new OriginalRTCPeerConnection(config);
            };
            window.RTCPeerConnection.prototype = OriginalRTCPeerConnection.prototype;
        })();
        </script>
        </head>';
    }
}

请留意到脚本的配置,有个地方是需要修改公网ip的,并且为了你的配置信息不明文裸奔,我额外添加了base64的编码

如果你改了账号和密码,需要在对应的地方修改你账号密码base64编码后的内容!

配置完后保存进行测试

测试现象

点开你的网站,点击F12,开启控制台,如果发现出现了劫持补丁,说明成功加载了。

恭喜你,你的SyncTV语音功能已经能无视复杂的网络NAT环境正常使用了!!!

评论