抖音直播伴侣捕捉RTMP直播推流码的方法与实现

​ 对象最近在抖音播pubg给朋友看,于是有了这个需求,听她朋友们讲这类捕捉推流码然后到obs推流的软件一年是六十块钱。我寻思这玩意不就简单用中间人抓个包的事情吗。

​ 在github上看了发现也有几个项目介绍是写捕捉流量的。但是我发现基本都用不了。于是决定自己上手操作。我在犹豫要不要放出代码,前面都是探索过程,由于两周前完成的,所以现在的记录都是一个回忆的过程,同时写博客是在mac,而代码以及调试环境都在windows,所以图会不放或者少放。

0x00 准备

​ 需要准备的环境:Proxifier Standard Edition V4,Python,MitmProxy

​ 我选择的开发语言是python

1
2
pip install mitmproxy
pip install requests

​ 安装好mitmproxy以及requests,前者创建一个中间人代理服务器,后者用来给抖音发送一个终止直播包。我比较推荐使用se版本的proxifier,因为pe版本会在特定情况下导致浏览器崩溃,而且se跟pe的捕捉流量的方式也不一样,se应该是会创建虚拟网卡所以更加好用。

​ 使用proxifier创建好一个proxyserver,https协议,127.0.0.1:8080,实际情况以自己的环境为准,这里我只提我的环境。我全都是默认,因为我需要考虑到易用性。

​ 代理上mitmproxy之后,访问https://mitm.it/来下载证书,根据对应系统按照官方文档进行配置。

​ 编写一个main.py

1
2
3
4
def request(flow:http.HTTPFlow):
# 你的捕捉请求包代码
def response(flow:http.HTTPFlow):
# 你的捕获响应包代码

起初我是将所有请求包都通过并且输出,然后配合proxifier观察有没有哪些url是有比较明显的交互的。

​ 执行命令

1
mitmdump -s main.py

​ 前期调试阶段不要增加-q参数,因为需要研究这些流量。

0x01 调试

​ 我在调试阶段发现了一个域名log-snssdk.zijieapi.com,根据子域名包含的log以及实际的请求包来看,应该是记录当前直播状态的存储服务器,我在本地多次进行开播结束直播,在proxifier看到这个url频繁出现,也频繁交互。于是我在代码中加入了

1
2
3
4
log_hosts = ["log-snssdk.zijieapi.com"]
def request(flow:http.HTTPFlow):
if flow.request.pretty_host in log_hosts:
print(flow.request.text())

在重新运行mitmdump之后,进行开启直播,果不其然捕捉到了开播的状态,以及推流状态还有rtmp码。

通过这个域名的包是json数据,其中有一个key是event_key,这个地方其实就是关键。

他其中有三种状态,一个是connect_start,一个是push_stream,一个是connect_end。看到这里大多数朋友应该已经懂了。我起初以为connect_start与push_stream的push_url是一样的。直到我在obs尝试直播的时候才发现不对。

在发送connect_start这个包之后,由于直播的风控问题,一般都会延迟推流,也就是说开始直播的五秒后才进行。所以核心是push_stream这个状态,这个状态才代表推流真正开始。

0x02 使用obs接管流量

​ 当直播伴侣开启直播的阶段,此时推流数据由直播伴侣推送到直播平台,可以在push_stream出来的时候,kill掉直播伴侣这个进程。随后解析包含push_stream这个包中的push_url,这个包由推流地址以及推流码组成,以third作为分割,即可分割出推流地址和推流码。使用obs进行配置即可进行顶掉直播伴侣然后使用obs推流。

例如:rtmp://push.rtmp.xxx.com/third/stream-xxxxxxxxx?expire=xxxxx&sign=xxxxx&volcSecret=xxxxx&volcTime=xxxxx

​ 这样就能分割出:

服务器:rtmp://push.rtmp.xxx.com/third

推流码:stream-xxxxxxxxx?expire=xxxxx&sign=xxxxx&volcSecret=xxxxx&volcTime=xxxxx

​ 此时已经可以推流

0x03 思考

​ 我在抓这个包的时候,其实我发现了一个很搞笑的问题,这个包里存在一个from的key,value是obs。是不是直播伴侣其实推流用的还是obs的协议,还是说基于obs进行的二开?这个我不清楚

​ 这个方案抖音并非不知道,在我上述提到connect_end这个状态中,会向log服务器发送一个直播总时间等等的直播状态,同时我这个方案是没有写如何结束直播的,那就是说在极端的情况下需要每次都打开直播伴侣,结束直播。

​ 说实话这种方案抖音肯定也会有考虑怎么解决,无非就是判断是不是真人在直播等等,而且会不定时有一个状态码发送到服务器,以此来证明是通过直播伴侣来直播,总之有多个方案来判断用户有无违规行为。本身我们直播的账号也是满足抖音开播要求的(1000粉丝还有啥要求忘了),这个方案本身只是使用了更好的工具来进行推流,尽管有一定的风险,但我认为还是可以使用的。用户应该有自己的考虑。

0x04 项目地址

https://github.com/0chencc/DouyinLiveFlowCatch

本项目遵循GPLv3,请勿用作商用。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!