saermart / DouyinLiveWebFetcher

抖音直播间网页版的弹幕数据抓取(2024最新版本)
GNU Affero General Public License v3.0
526 stars 158 forks source link

收取礼物包问题(已解决,附源码供参考) #35

Open KanyShigure opened 3 months ago

KanyShigure commented 3 months ago

1.收取的礼物通讯包会是两个一样的先后发送,导致同一个礼物接收两次,需要一个静态列表检测礼物包是否收过 2.在观众多次点击送礼物连击的时候,会重复接收礼物包导致数量偏多,和上一个问题类似,但收到的不是同一个包,包id不一样

TerryYoung518 commented 2 months ago

我来提供我的思路吧,首先感谢repo作者的开源贡献。

  1. 对于 sendType 不等于4的情况(一般为1),说明送的是普通礼物,可以直接取 groupCount 作为当前送礼行为的礼物数量。
  2. 对于 sendType 等于4的情况,说明送的是连击礼物,这个时候需要分类讨论:
    • repeatEnd 等于0,则礼物消息是连击送礼阶段实时产生的消息,comboCount 的数值是 本次连击的累计礼物数量

      为什么是累计数量呢?经过观察发现不一定每次连击都会产生消息,比如 comboCount 的数值可能是:1、2、3、5、6这样跳跃增长的,也就是说中途可能会少那么一两次记录,减少了消息量,节省了网络资源,但连击礼物总数是不会错的。

    • repeatEnd 等于1,则礼物消息是连击送礼结束后的汇总消息,comboCount 的数值就是本次连击礼物总数。

注意,以上 普通礼物连击礼物 是我自己定义的名称。

因此,对于连击礼物(sendType 等于4),如果只关心礼物总量,那么只需要考虑repeatEnd为1的那一个消息就可以了。如果关心消息的实时性,可以维护一个记录连击礼物行为和累计礼物数量的表,计算每次的 comboCount 差值,从而获得近似数量准确的实时礼物消息。

值得注意的是,涉及礼物数量的有 groupCount repeatCount comboCount totalCount似乎 groupCountcomboCount至少一个数值必为 1,而repeatCounttotalCount的数值均等于groupCountcomboCount的最大值(或是乘积)。

如果有错误,欢迎指出。

wangyucong commented 1 week ago

我来提供我的思路吧,首先感谢repo作者的开源贡献。

  1. 对于 sendType 不等于4的情况(一般为1),说明送的是普通礼物,可以直接取 groupCount 作为当前送礼行为的礼物数量。
  2. 对于 sendType 等于4的情况,说明送的是连击礼物,这个时候需要分类讨论:

    • repeatEnd 等于0,则礼物消息是连击送礼阶段实时产生的消息,comboCount 的数值是 本次连击的累计礼物数量

      为什么是累计数量呢?经过观察发现不一定每次连击都会产生消息,比如 comboCount 的数值可能是:1、2、3、5、6这样跳跃增长的,也就是说中途可能会少那么一两次记录,减少了消息量,节省了网络资源,但连击礼物总数是不会错的。

    • repeatEnd 等于1,则礼物消息是连击送礼结束后的汇总消息,comboCount 的数值就是本次连击礼物总数。

注意,以上 普通礼物连击礼物 是我自己定义的名称。

因此,对于连击礼物(sendType 等于4),如果只关心礼物总量,那么只需要考虑repeatEnd为1的那一个消息就可以了。如果关心消息的实时性,可以维护一个记录连击礼物行为和累计礼物数量的表,计算每次的 comboCount 差值,从而获得近似数量准确的实时礼物消息。

值得注意的是,涉及礼物数量的有 groupCount repeatCount comboCount totalCount似乎 groupCountcomboCount至少一个数值必为 1,而repeatCounttotalCount的数值均等于groupCountcomboCount的最大值(或是乘积)。

如果有错误,欢迎指出。

刚刚发现,sendType为4 的时候,同一个连击礼物周期内,不管repeatEnd为0还是1,groupId是相同的,似乎可以利用这个来做数据更新,这样即能确保礼物的实时性,又能确保总量不出错。

sendType=0 这种是瞬发礼物,比如一次送66 88个这种 sendType=5 这种是粉丝灯牌礼物

TerryYoung518 commented 6 days ago

刚刚发现,sendType为4 的时候,同一个连击礼物周期内,不管repeatEnd为0还是1,groupId是相同的,似乎可以利用这个来做数据更新,这样即能确保礼物的实时性,又能确保总量不出错。

sendType=0 这种是瞬发礼物,比如一次送66 88个这种 sendType=5 这种是粉丝灯牌礼物

@wangyucong 不错的发现,我采用的是${groupId}_${userId}_${giftId}作为某一系列 连击礼物 的唯一key。

KanyShigure commented 6 days ago

早已解决,忘了关issue了,礼物收包中有个值代表该信息包为连击信息,实际的算法应 总量=连击量*连击次数+单击次数 或 总量=提前量+增量 (其中连击数 连击次数 单击次数 为数据包内明文信息) 直接将收到的数据包以json格式print出来就可以找到连击数 连击次数 单击次数,然后根据算法提取就可以了(我是直接转为json对象然后读,觉得string split太麻烦了)

KanyShigure commented 6 days ago

image 处理源码,由于wss对象我已提前魔改过,此处仅供参考,