// ==UserScript==
// @name 获取直播弹幕
// @namespace http://tampermonkey.net/
// @version 2.0.0
// @description 在线获取弹幕
// @author 37
// @match https://buyin.jinritemai.com/*
// @match https://zs.kwaixiaodian.com/*
// @match https://liveplatform.taobao.com/*
// @match https://live.baidu.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant none
// @license MIT
// @require http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @require https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
// ==/UserScript==
(function () {
'use strict';
let ws;
let observer;
let waitMsgList = [];
let stopWs = false;
let goodsList = []
let wxUrl = ''
let promotionsList = []
let nowHost = window.location.host
let ksBol = false
let tbWscomments = []
let tbOnceArr = []
let tbOnceArrLastMsg = ''
let timeElment = ''
function connectWebSocket() {
ws = new WebSocket(wxUrl);
ws.addEventListener('open', () => {
if (nowHost == 'zs.kwaixiaodian.com') {
ksBol = false
$('.ReactVirtualized__List').scrollTop(9999)
setTimeout(() => {
ksBol = true
}, 1000)
}
console.log('连接成功')
const submitButton = document.querySelector('#submitButton');
submitButton.textContent = `断开弹幕采集${nowHost == 'zs.kwaixiaodian.com' ? '(提示:连接弹幕后请勿手动拖动弹幕列表!)' : ''}`;
if (waitMsgList.length) {
waitMsgList.forEach((item) => {
ws.send(item);
console.log('成功发送缓存---', item);
});
waitMsgList = [];
}
});
ws.addEventListener('message', event => {
console.log('从服务器接收到消息:', JSON.parse(event.data));
JSON.parse(event.data).type == 3 && findGoods(JSON.parse(event.data).answerText[0])
});
ws.addEventListener('close', (event) => {
const submitButton = document.querySelector('#submitButton');
submitButton.textContent = '连接弹幕采集';
if (stopWs) {
stopWs = false
} else {
setTimeout(() => {
console.log('WebSocket 已关闭--正在重新连接');
connectWebSocket(wxUrl);
}, 3000);
}
});
}
function startObserver() {
observer = new MutationObserver(mutationsList => {
mutationsList.forEach(mutation => {
mutation.addedNodes.forEach(addedNode => {
var userElement = ''
var contentElement = ''
if (nowHost == 'buyin.jinritemai.com') {//抖音捕捉弹幕逻辑
if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.classList.contains('index-module__commentItem___2fLb5')) {
userElement = addedNode.querySelector('.index-module__nickname___L6O_K');
contentElement = addedNode.querySelector('.index-module__description___2W_id');
}
if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.classList.contains('index-module__newCommentShadow___3rffn')) {
console.log('监测到需要加载新弹幕')
$(".index-module__newCommentShadow___3rffn")[0].click()
}
}
if (nowHost == 'zs.kwaixiaodian.com') {//快手捕捉弹幕逻辑(快手中控有后台监测,需手动活跃到可视窗口)
if (!ksBol) return;//等待滚动条加载
try {
if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.childNodes.length && addedNode.childNodes[0].classList.contains('list-item--f1eox')) {
userElement = addedNode.querySelector('.username--naHYA');
contentElement = addedNode.querySelector('.replied-content--OFcGD');
}
} catch (error) { }
if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.classList.contains('bubble--qrbI7')) {
try {
$(".bubble--qrbI7")[0].click()
} catch (error) {
// console.log(error)
}
}
}
if (nowHost == 'liveplatform.taobao.com') {//淘宝捕捉弹幕逻辑
// console.log('------进入淘宝-----');
if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.classList.contains('tc-comment-item')) {
userElement = addedNode.querySelector('.tc-comment-item-userinfo-name ')
contentElement = addedNode.querySelector('.tc-comment-item-content span')
timeElment = addedNode.querySelector('.alpw-comment-time').textContent.trim()
tbWscomments.push({ userName: userElement.textContent, answerText: contentElement.textContent,timestamp:timeElment })
tbOnceArr = tbWscomments.filter((value, index, self) => {
return index === self.findIndex(item => item.userName === value.userName && item.answerText === value.answerText)
})
//当前时间
const currentTime = new Date();
const fiveMinutesBefore = new Date(currentTime.getTime() - 5 * 60 * 1000);
const fiveMinutesAfter = new Date(currentTime.getTime() + 5 * 60 * 1000);
tbOnceArr = tbOnceArr.filter((item) => {
const itemTimestamp = new Date().setHours(item.timestamp.substring(0, 2), item.timestamp.substring(3, 5), 0);
return itemTimestamp >= fiveMinutesBefore && itemTimestamp <= fiveMinutesAfter;
});
// console.log(tbWscomments, tbOnceArr,timeElment,'淘宝消息');
}
//如果有需要加载的提示
var element = $(".tc-comment-list-newtip")
// 判断特定条件
if (element.css("display") === "block") {
element.trigger('click')
element.click(function () {
});
}
}
if (nowHost == 'live.baidu.com') { //百度捕捉弹幕逻辑
// console.log('进入百度弹幕');
if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.classList.contains('chat-room-msg')) {
userElement = addedNode.querySelector('.msg-box-name');
contentElement = addedNode.querySelector('.msg-box-text');
}
}
//发送弹幕
if (contentElement) {
if (nowHost == 'liveplatform.taobao.com' && tbOnceArr.length !== 0) {
if ( tbOnceArr[tbOnceArr.length -1].answerText !== tbOnceArrLastMsg) {
const dataToSend = {
answerText: tbOnceArr[tbOnceArr.length - 1].answerText,
type: 1
}
if (ws && ws.readyState === 1) {
tbOnceArrLastMsg = tbOnceArr[tbOnceArr.length - 1].answerText
ws.send(JSON.stringify(dataToSend));
console.log('成功发送弹幕---', tbOnceArr[tbOnceArr.length - 1].userName, tbOnceArr[tbOnceArr.length - 1].answerText);
} else {
tbOnceArrLastMsg = tbOnceArr[tbOnceArr.length - 1].answerText
console.log('储存弹幕一条---', tbOnceArr[tbOnceArr.length - 1].userName, tbOnceArr[tbOnceArr.length - 1].answerText);
waitMsgList.push(JSON.stringify(dataToSend));
}
}
} else if(nowHost != 'liveplatform.taobao.com') {
console.log("进入别的平台");
const dataToSend = {
answerText: contentElement.textContent,
type: 1
};
if (ws && ws.readyState === 1) {
ws.send(JSON.stringify(dataToSend));
console.log('成功发送弹幕---', userElement.textContent, contentElement.textContent);
} else {
console.log('储存弹幕一条---', userElement.textContent, contentElement.textContent);
waitMsgList.push(JSON.stringify(dataToSend));
}
}
}
});
});
});
observer.observe(document.documentElement, { childList: true, subtree: true });
}
function getGoodsList() {
const match = wxUrl.match(/websocket\/([^\/]+)/);
if (match ? match[1] : null) {
$.ajax({
type: "GET",
url: "https://buyin.jinritemai.com/api/anchor/livepc/promotions",
success: function (data) {
promotionsList = data.data.promotions
goodsList = data.data.promotions.map((data, index) => {
return {
goodName: data.title,
goodNo: index + 1,
price: data.min_price / 100,
liveId: match[1],
}
})
const dataToSend = {
answerText: goodsList,
type: 4
};
ws.send(JSON.stringify(dataToSend));
alert('更新商品成功')
}
});
} else { console.log('获取liveID失败') }
}
function findGoods(item) {
$.ajax({
type: "POST",
url: "https://buyin.jinritemai.com/api/anchor/livepc/setcurrent",
data: { promotion_id: promotionsList[item.goodNo - 1].promotion_id },
success: function (data) {
document.querySelectorAll(".index__actionItem___2Z8YV")[1].click()
}
});
}
function stopObserver() {
if (observer) {
observer.disconnect();
observer = null;
}
}
function disconnectWebSocket() {
if (ws) {
ws.close();
stopObserver()
stopWs = true
console.log('WebSocket 已手动断开连接');
}
}
function createFloatingInput() {
const inputContainer = document.createElement('div');
inputContainer.style.position = 'fixed';
inputContainer.style.top = '60px';
inputContainer.style.left = '20px';
inputContainer.style.zIndex = '999999';
const inputElement = document.createElement('input');
inputElement.setAttribute('type', 'text');
inputElement.setAttribute('placeholder', '输入 WebSocket 地址');
inputElement.classList.add('input-box');
inputElement.style.padding = '8px';
inputElement.style.border = '1px solid #ccc';
inputElement.style.borderRadius = '4px';
inputElement.style.outline = 'none';
const submitButton = document.createElement('button');
submitButton.id = 'submitButton'
submitButton.textContent = '连接弹幕采集';
submitButton.style.marginLeft = '8px';
submitButton.style.padding = '8px';
submitButton.style.border = '1px solid #ccc';
submitButton.style.borderRadius = '4px';
submitButton.style.backgroundColor = '#f0f0f0';
submitButton.style.cursor = 'pointer';
const goodsButton = document.createElement('button');
goodsButton.id = 'submitButton'
goodsButton.textContent = '更新抖音商品';
goodsButton.style.marginLeft = '8px';
goodsButton.style.padding = '8px';
goodsButton.style.border = '1px solid #ccc';
goodsButton.style.borderRadius = '4px';
goodsButton.style.backgroundColor = '#f0f0f0';
goodsButton.style.cursor = 'pointer';
submitButton.addEventListener('click', () => {
const inputVal = inputElement.value.trim();
if (inputVal) {
if (ws && ws.readyState == 1) {
disconnectWebSocket();
} else {
startObserver()
wxUrl = inputVal
connectWebSocket(inputVal);
}
}
});
goodsButton.addEventListener('click', () => {
getGoodsList()
});
inputContainer.appendChild(inputElement);
inputContainer.appendChild(submitButton);
nowHost == 'buyin.jinritemai.com' && inputContainer.appendChild(goodsButton);
document.body.appendChild(inputContainer);
}
createFloatingInput();
})();