如何科学地直播 PS4
当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »
劫持 twitch 推流,无需采集卡就能直播 PS4 画面,于是又省下了买采集卡的钱(。
Head Pic: #arknights 白面鸮 - UM3c的插画 - pixiv
如何科学的直播 PS4
不用采集卡直播还有一种最简单的方法是使用 PS4 遥控操作(PS4 Remote Play),直接直播在电脑上串流的 PS4 画面,但这有几点缺点
- 手柄需要一直连到电脑上,且声音只能通过电脑或手柄播放
- Slim 机型(比如我这种穷人甚至买的二手 Slim)只支持 720p 串流,虽然用来直播是可以的,但是自己玩的话体验极差
那么问题就在于如何找到一种独立的“投屏”方法,在不影响游戏体验的情况下得到 PS4 画面
好在 PS4 其实是自带直播推流功能的,支持 twitch 和 youtube,那么我们只要劫持推流就可以拿来推到自己想要的直播平台上了
当然了,这种方法肯定是没有采集卡效果好的,而且 Slim 的推流最高也只支持 720p 60fps
0. 前置准备
想要完成上述操作,我们需要
- 一台 openwrt 路由器或自建的软路由
- 一个位于内网的 linux,可以是 WSL 或者虚拟机,如果你是软路由的话也可以尝试直接利用
我个人最推荐 WSL,它最为方便,WSL 大法好 - nginx + nginx-rtmp-module
后续示例均为使用 WSL 与 openwrt 路由器
1. 编译带 nginx-rtmp-module 的 nginx
Require | Website |
---|---|
nginx | https://nginx.org/en/download.html |
nginx-rtmp-module | https://github.com/arut/nginx-rtmp-module |
此处假设我们将 nginx 装到/opt
下,我编译的是写这篇文章的时候最新的 stable version nginx-1.16.1
# 安装依赖
apt-get install -y build-essential libpcre3 libpcre3-dev libssl-dev zlib1g-dev git
# 获取 nginx 源码
cd /opt
wget https://nginx.org/download/nginx-1.16.1.tar.gz
tar zxvf nginx-1.16.1.tar.gz
cd nginx-1.16.1
# 获取 nginx-rtmp-module
git clone https://github.com/arut/nginx-rtmp-module.git --depth=1
# configure
./configure --prefix=/opt/nginx --add-module=./nginx-rtmp-module/ --with-http_ssl_module
然后稍等一下,不急着make
使用gcc -dumpversion
命令查看一下自己的 gcc 版本,特别是如果你用的是 WSL,预装的 gcc 应该是 8,版本是 7 及以上的必须改 makefile 来忽略 nginx 源码中 switch-case 没加 break 造成的 implicit fallthrough error
编辑objs/Makefile
,在下面所示的这行上加个-Wno-implicit-fallthrough
# 把
CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g
# 改为
CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -Wno-implicit-fallthrough
好,接下来就可以继续了
make && make install
2. 配置 nginx
# 当前目录 /opt/nginx-1.16.1
cp nginx-rtmp-module/stat.xsl /opt/nginx/html
chown -R www:www /opt/nginx/html
接着修改/opt/nginx/conf/nginx.conf
,首先将最前面#user nobody;
修改为user www;
在 http 配置块前加上 rtmp 配置
rtmp {
server {
listen 1935;
application app {
live on;
}
}
}
在 http 的 server 配置块中加入 rtmp 状态页面配置,location /
直接修改原有即可
location / {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /opt/nginx/html;
}
最好将 http 的 server 中的 listen 也改一下,因为我们编译的这个 nginx 只是拿来做推流劫持的,不会用来做别的事,所以不需要占用 80 端口,改成其他的可以避免以后做什么事需要用 80 端口导致冲突
在此处我改为10080
,见下方完整配置
于是最终你的配置文件应该像这样(我删掉了自带注释)
user www;
worker_processes 1;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
application app {
live on;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
# 改一下监听端口
listen 10080;
server_name localhost;
location / {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /opt/nginx/html;
}
}
}
接着测试一下配置文件,没错误就可以启动 nginx 了
# 测试配置
/opt/nginx/sbin/nginx -t
# 启动
/opt/nginx/sbin/nginx
3. 劫持 twitch 推流
接下来只要劫持 live.twitch.tv 到 nginx 就行
需要注意的是,不能使用 hosts 方式,这对新版本的 PS4 系统无效,我试了下确实如此,所以我们使用 iptables 做 DNAT
首先用dig
或者nslookup
查看一下我们当前网络的 live.twitch.tv 被解析到哪里
# 以 dig 为例,没有的话需要安装
apt-get install -y dnsutils
dig live.twitch.tv
# ; <<>> DiG 9.11.5-P4-5.1-Debian <<>> live.twitch.tv
# ;; global options: +cmd
# ;; Got answer:
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36451
# ;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
#
# ;; QUESTION SECTION:
# ;live.twitch.tv. IN A
#
# ;; ANSWER SECTION:
# live.twitch.tv. 600 IN CNAME live.video.twitch.tv.
# live.video.twitch.tv. 600 IN CNAME live-beta.video.twitch.tv.
# live-beta.video.twitch.tv. 600 IN CNAME live-hkg.twitch.tv.
# live-hkg.twitch.tv. 600 IN A 45.113.128.181
# live-hkg.twitch.tv. 600 IN A 45.113.128.147
# live-hkg.twitch.tv. 600 IN A 45.113.128.110
#
# ;; Query time: 312 msec
# ;; SERVER: 192.168.123.1#53(192.168.123.1)
# ;; WHEN: Fri Sep 13 15:14:30 CST 2019
# ;; MSG SIZE rcvd: 321
我们可以看到记录有 3 个 IP,都在45.113.128.0/24
中,所以我们就 DNAT 这个网段的 1935 端口到 nginx 所在设备的 1935 端口就行
在 openwrt 路由器或软路由上执行
iptables -t nat -I PREROUTING -d 45.113.128.0/24 -p tcp --dport 1935 -j DNAT --to-destination 192.168.123.2:1935
我在 WSL 上运行 nginx,所以需要转发到我 PC 上,192.168.123.2
是我 PC 的内网 IP,建议在路由器上配置给相应设备分配静态 IP
注意:如果你使用 WSL 或虚拟机,请关闭 Winddows 防火墙,或创建规则放行 1935 端口;若使用内网中的 linux 机器也应当检查防火墙确保端口开放
4. 开启 PS4 直播推流
按下 share 键打开菜单,有个“播放游玩过程”,选 twitch 然后按说明绑定账号,设置推流分辨率之类的
开始推流之后访问 rtmp stat 页面,例如我自己这种部署方式就是 http://127.0.0.1:10080 ,然后应该就能看到 live streams 下方出现了一条记录
如果 app 写的是[EMPTY]
的话那么 rtmp 地址就是rtmp://127.0.0.1:1935/app/
否则应该是rtmp://127.0.0.1:1935/app/xxx
然后我们拿一个支持 rtmp 的播放器测试一下,顺利的话就应该能看到 PS4 的画面了(好耶
5. 推流到直播平台
有两种方式,看自己需求选择
(1) 直接推流
这种方式相当于原封不动地推流到其他直播平台,好处是不用再开推流软件,但我自己试的时候不知为何推流画质十分惨烈
修改 nginx 配置,在 rtmp 配置块中的live on;
下面添加一行push rtmp://[直播推流带key的完整地址];
即可
例如这是推流到B站的示例
push rtmp://js.live-send.acg.tv/live-js/?streamname=[name]&key=[key];
修改完配置只要/opt/nginx/sbin/nginx -s reload
即可重载配置
(2) 使用 obs 再推流
大部分情况下你可能想用 obs 做些处理再推流,这很简单,只要添加“媒体源”,去掉“本地文件”勾选,在“输入”中贴上 rtmp 地址即可
6. 自启动
nginx 方面
普通 linux 上自启动 nginx 应该不用我多说,改/etc/rc.local
若使用 WSL,你可以在 PC 上创建一个 vbs 脚本,例如nginx-rtmp.vbs
,内容如下
Set ws = CreateObject("Wscript.Shell")
ws.run "wsl /opt/nginx/sbin/nginx", vbhide
然后把这个脚本扔到 Windows 的启动目录C:\Users\[用户名]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
即可
使用 vbs 的原因是 vbhide 可以让命令执行的时候不会有一个 cmd 窗一瞬出现影响观感
iptables 方面
这一方面情况比较复杂,只是路由器启动时加 iptables 规则的话,可以简单的写在路由器启动脚本里就行
但有些时候,例如启动 ss,可能会清空你的 nat 表,这时候需要重新添加,总之就看你自己实际情况将命令也放在 ss 启动脚本里什么的
一劳永逸的简便的方法是写个守护脚本,我就不贴脚本了,因为我自己都还懒得去写(
后记
这个方法最大的缺点是,无法与加速器同时使用
目前市面上的加速器基本都是在 PC 上起一个 TAP Adapter 然后让 PS4 连,这样所有的流量都会走加速器出去,iptables 无法劫持
不过有些加速器也有提供路由器插件,我没有实际用过因为没有“支持”插件的路由器,说不定这种情况下有方法可以实现同时使用
另外,如果路由器上用的是 DNSMasq,配合 ipset 应该可以实现自动将 live.twitch.tv 的 IP 加到 ipset 中,然后 iptables 规则就可以直接使用 ipset,而不用自己手写网段了