您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
B站直播间弹幕转发,需要用户已登录。若有滥用等问题概不负责,诶嘿。顺便关注一下小东人鱼和noworld吧~
当前为
// ==UserScript== // @name B站直播间弹幕广播 // @namespace http://tampermonkey.net/ // @version 0.1 // @description B站直播间弹幕转发,需要用户已登录。若有滥用等问题概不负责,诶嘿。顺便关注一下小东人鱼和noworld吧~ // @author 太陽闇の力 // @include /https?:\/\/live\.bilibili\.com\/(blanc\/)?\d+\??.*/ // @grant none // @require https://greasyfork.org/scripts/417560-bliveproxy/code/bliveproxy.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js // 命令分析参考自 https://segmentfault.com/a/1190000017328813 //界面参考自小东人鱼午安社五更耗纸 https://github.com/gokoururi-git/gachihelper/ // 弹幕api使用参考自 https://greasyfork.org/zh-CN/scripts/434726 // @license MIT // ==/UserScript== // 当前直播间号 const proomid = /(?!https:\/\/live.bilibili.com\/)\d+/.exec(window.location.href)[0]; (function() { //-----------配置区---------- //0默认收起,1默认展开 let isunfold = 0; // 转发对象的UID,也即转发谁的弹幕 let uid = 353039514; // 要转发的直播间号,也即发到哪儿 let rooms = ` 9806022 2077803 431458 145657 `.replace(/ /g, '').trim().split('\n'); // 设置弹幕的发送间隔(秒),默认1秒,指转发到直播间A,然后再转发到直播间B,中间的时间间隔 //如果设置太小,会因发送频率过快而被B站吞掉弹幕,将自动重发并且自动设置发送间隔为1秒(如果本来是1秒,将设置成1.5秒) let inter = 1; //-----------UI区---------- let unfold = ["展开","收起"]; // 总容器 const container = window.document.createElement('div'); container.style.width = '218px'; container.style.position = 'fixed'; container.style.bottom = '5px'; container.style.right = '60px'; container.style.zIndex = '999'; container.style.boxSizing = 'border-box'; // 工具名称 const topTool = window.document.createElement('div'); topTool.innerText = '弹幕转发'; topTool.style.textAlign = 'center'; topTool.style.lineHeight = '20px'; topTool.style.height = '20px'; topTool.style.width = '100%'; topTool.style.color = 'rgb(210,143,166)'; topTool.style.fontSize = '14px'; // 最小化按钮 const collapseButton = window.document.createElement('button'); collapseButton.innerText = unfold[isunfold]; collapseButton.style.float = 'right'; collapseButton.style.width = '40px'; collapseButton.style.height = '20px'; collapseButton.style.border = 'none'; collapseButton.style.cursor = 'pointer'; collapseButton.style.backgroundColor = '#1890ff'; collapseButton.style.borderRadius = '0'; collapseButton.style.color = '#ffffff'; // 主窗口 const mainWindow = window.document.createElement('div'); if(isunfold==0){ mainWindow.style.display = "none"; } mainWindow.style.width = '100%'; mainWindow.style.backgroundColor = 'rgba(220, 192, 221, .5)'; mainWindow.style.padding = '10px'; mainWindow.style.boxSizing = 'border-box'; // 直播间号输入框 const textArea = window.document.createElement('textarea'); textArea.placeholder = '转发的直播间号,换行分隔' textArea.style.boxSizing = 'border-box'; textArea.style.width = '100%'; textArea.style.height = '60px'; textArea.style.resize = 'none'; textArea.style.outline = 'none'; textArea.style.background = 'rgba(255,255,255,.5)'; // 按钮区容器 const buttonArea = window.document.createElement('div'); buttonArea.style.width = '100%'; buttonArea.style.boxSizing = 'border-box'; buttonArea.style.height = '30px'; buttonArea.style.display = 'flex'; // 开始按钮 const goButton = window.document.createElement('button'); goButton.innerText = '开始'; goButton.style.width = 'max-content'; goButton.style.height = '28px'; goButton.style.padding = '0 5px'; goButton.style.marginLeft = '5px'; //用户UID const uidBox = window.document.createElement('input'); uidBox.placeholder = "输入用户uid"; uidBox.style.width = "70px"; uidBox.style.height = '28px'; uidBox.style.padding = '0 5px'; uidBox.style.marginLeft = '5px'; //发送间隔 const interBox = window.document.createElement('input'); interBox.value = 1; interBox.placeholder = "间隔(秒"; interBox.style.width = "40px"; interBox.style.height = '28px'; interBox.style.padding = '0 5px'; interBox.style.marginLeft = '5px'; // 组装 topTool.appendChild(collapseButton); container.appendChild(topTool); mainWindow.appendChild(textArea); buttonArea.appendChild(uidBox); buttonArea.appendChild(interBox); buttonArea.appendChild(goButton); mainWindow.appendChild(buttonArea); container.appendChild(mainWindow); window.document.body.appendChild(container); // 显示逻辑控制 collapseButton.addEventListener('click', () => { if (collapseButton.innerText === '收起') { mainWindow.style.display = 'none'; collapseButton.innerText = '展开'; return; } if (collapseButton.innerText === '展开') { mainWindow.style.display = 'block'; collapseButton.innerText = '收起'; return; } }, false); function setOpacity(ele, opacity) { if (ele.style.opacity != undefined) { ///兼容FF和GG和新版本IE ele.style.opacity = opacity / 100; } else { ///兼容老版本ie ele.style.filter = "alpha(opacity=" + opacity + ")"; } } function fadeout(ele, opacity, speed) { if (ele) { var v = ele.style.filter.replace("alpha(opacity=", "").replace(")", "") || ele.style.opacity || 100; v < 1 && (v = v * 100); var count = speed / 1000; var avg = (100 - opacity) / count; var timer = null; timer = setInterval(function() { if (v - avg > opacity) { v -= avg; setOpacity(ele, v); } else { clearInterval(timer); } }, 500); } } function showmessage(intext) { const div = window.document.createElement('div'); div.style.boxSizing = 'border-box'; div.style.width = '200px'; div.style.height = "40px" div.style.position = 'fixed'; div.style.bottom = '40px'; div.style.left = '50px'; div.style.zIndex = '999'; div.style.boxSizing = 'border-box'; div.style.backgroundColor = 'rgba(255, 255, 0,.2)'; div.style.borderRadius = "5px"; div.style.color = "#FF0000"; div.innerText = intext; div.fontSize = "medium"; div.style.lineHeight = "40px"; div.style.textAlign = "center"; window.document.body.appendChild(div); fadeout(div, 1, 2000); if (inter == 1) { inter = 1.5; } else { inter = 1; } setTimeout((ele) => { ele.remove(); }, 2000, div); } //-----------逻辑区区---------- // 主要逻辑为检测弹幕,转发弹幕 function hdl(command) { let info = command.info if (info[2][0] != uid) { return; } let apiClient = axios.create({ baseURL: 'https://api.live.bilibili.com', withCredentials: true }) async function PostRequest(msg, roomid) { let cookie = document.cookie; let rnd = parseInt(+new Date() / 1000); let ObjectCookie = objectCookies(cookie) let data = new FormData() data.append('bubble', 0) data.append('color', 16777215) data.append('fontsize', 25) data.append('mode', 1) data.append('rnd', rnd) data.append('msg', msg) data.append('roomid', roomid) data.append('csrf', ObjectCookie.bili_jct) data.append('csrf_token', ObjectCookie.bili_jct) let ajaxObj = (await apiClient.post('/msg/send', data, { cookie: cookie })).data return ajaxObj; } function objectCookies(cookie) { var cookies = cookie.split(';'); var result = {}; for (var i = 0; i < cookies.length; i++) { var keyvaluepair = cookies[i].split('='); result[keyvaluepair[0].trim()] = keyvaluepair[1]; } return result; } let depth = 0; function send(msg, roomid) { let resp = PostRequest(msg, roomid); resp.then(res => { if (res.msg == "您发送弹幕的频率过快") { depth += 1; showmessage(res.msg + ",正在重发"); setTimeout(send, 1000 * inter * rooms.length + depth, msg, roomid); if (depth == 20) { alert("弹幕转发:请刷新网页以确认网络是否处于正常状态"); } } }) }; for (let i = 0; i < rooms.length; i++) { setTimeout(send, 1000 * inter * (i + 1), info[1], rooms[i]); } } try{ goButton.addEventListener('click', () => { if (goButton.innerText == '暂停') { bliveproxy.removeCommandHandler('DANMU_MSG', hdl) goButton.innerText = '开始'; return; } uid = uidBox.value; if(uid==''){ showmessage("您未输入uid"); return; } rooms=textArea.value; if(rooms==''){ showmessage("您未输入直播间号"); return; } rooms = textArea.value.replace(/ /g, '').trim().split('\n'); if (rooms.indexOf(proomid) > -1) { showmessage("不能转发到所在直播间"); return; } bliveproxy.addCommandHandler('DANMU_MSG', hdl) goButton.innerText = '暂停'; }, false); }catch (e) { alert('弹幕转发:发生未知错误\n' + e); } })();