不用采集卡在 PS4 上直播

不用采集卡在 PS4 上直播

开始之前

我在 Ubuntu 16.04 和 Raspbian Stretch 上都成功实现了劫持 PS4 自带的 twitch 推流并转推到 bilibili.

主要参考了

这里我以树莓派举例, 我的是 Raspberry 2 Model B. 主要思路是通过劫持 DNS 来欺骗 PS4 推流.

1. 安装 Raspbian Stretch 到闪存卡

如果不是使用树莓派, 这一步可以跳过.

1
2
3
wget --trust-server-names https://downloads.raspberrypi.org/raspbian_lite_latest
unzip 2018-04-18-raspbian-stretch-lite.zip
sudo dd bs=4M if=2018-04-18-raspbian-stretch-lite.img of=/dev/mmcblk0 status=progress conv=fsync

具体安装可以参考: https://www.raspberrypi.org/documentation/installation/installing-images/linux.md

安装完成后闪存卡上会出现两个分区, 在 boot 分区执行命令启用 ssh:

1
sudo touch ssh

默认账号: pi; 默认密码: raspberry

2. 安装 nginx 和 nginx-rtmp-module

  1. 下载解压源码
1
2
3
4
5
6
7
8
cd $HOME
mkdir live
cd live
wget https://nginx.org/download/nginx-1.14.0.tar.gz
tar
wget https://github.com/arut/nginx-rtmp-module/archive/v1.2.1.tar.gz
tar xzvf nginx-1.14.0.tar.gz
tar xzvf v1.2.1.tar.gz

可能还要更新系统和使用 sudo raspi-config 配置一下, 这里不再展开.

  1. 编译
1
2
3
4
5
sudo apt install libssl-dev libpcre3-dev
cd nginx-1.14.0
./configure --add-module=$HOME/live/nginx-rtmp-module-1.2.1
make
sudo make install
  1. nginx.service

创建编辑 /lib/systemd/system/nginx.service 文件(内容来自 nginx.com):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

但我们暂时不启动它.

3. 配置静态 IP

这一步是可选的, 但是有一定必要.

Raspbian 默认使用 dhcpcd, 编辑 /etc/dhcpcd.conf 添加以下内容:

1
2
3
4
interface eth0
static ip_address=192.168.1.101/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1

为 eth0 配置了 IP 为 192.168.1.101, 网关和 DNS 使用路由器地址 192.168.1.1.

4. 配置 nginx

编辑 /usr/local/nginx/conf/nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#user  nobody;
worker_processes 1;

...

# ====== modify =========

error_log /dev/null crit;

rtmp {
server {
listen 1935;
chunk_size 65536;
application app {
live on;
record off;
meta copy;
push rtmp://<转推地址>+<转推key>;
}
}
}

# ====== modify =========

http {
...

server {
...
location / {
root html;
index index.html index.htm;
}

# ====== modify =========
access_log off;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}

location /stat.xsl {
root /home/pi/nginx-rtmp-module-1.2.1;
}
# ====== modify =========

...
}

...
}

测试配置:

1
sudo /usr/local/nginx/sbin/nginx -t

到这里, 如果使用 ffmepg 推流, 理论上是可以在 http://192.168.1.101/stat 上看到流的信息.

5. DNS 劫持

介绍操作之前, 先聊聊主要思路. 主要思路无非两种, 一种是利用网关 iptables NAT(不管是在路由器上还是 Linux), 还有一种就是修改 DNS. 网关的方式配置的点比较多, 所以只介绍 DNS 的方式.

  1. 安装 dnsmasq
  2. 配置 /etc/dnsmasq.conf, 添加几个域名到我们的地址
1
2
3
address=/live-tpe.twitch.tv/192.168.1.101
address=/live.twitch.tv/192.168.1.101
address=/live-sjc.twitch.tv/192.168.1.101

关于定位具体域名, 需要用一些奇怪的方式确认, 不具体讨论.

  1. 重启 dnsmasq

6. 配置 PS

  1. 在 PS 上配置 twitch 直播
  2. 自订 PS 的网络, 在 DNS 那一步, Primary 指定 192.168.1.101, Second DNS 指定网关地址

7. 最后

  1. 在 bilibili 开启直播
  2. 复制地址和流密钥到 nginx 中, 重新加载 nginx.
  3. PS 中开始推流

8. 后续

对于不同地区可能存在不同的域名, 理想方式是让所有 live-.*.twitch.com 的域名都指向树莓派 IP, 所以我写了一个支持正则的 dns 代理代替 dnsmasq: https://github.com/vizee/dnsproxy.

还有一个更集成的方案是

dnsproxy + rtmpproxy 直接实现直播,具体查看 rtmpproxy