B站直播间弹幕广播

B站直播间弹幕转发,需要用户已登录(不可用)。若有滥用等问题概不负责,诶嘿。顺便关注一下小东人鱼和noworld吧~

目前为 2022-01-03 提交的版本。查看 最新版本

// ==UserScript==
// @name         B站直播间弹幕广播
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  B站直播间弹幕转发,需要用户已登录(不可用)。若有滥用等问题概不负责,诶嘿。顺便关注一下小东人鱼和noworld吧~
// @author       太陽闇の力
// @match        https://live.bilibili.com/*
// @grant        none
// @require https://gf.qytechs.cn/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://gf.qytechs.cn/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.cssText = 'width:218px;position:fixed;bottom:5px;right:60px;z-index:999;box-sizing:border-box;';

		// 工具名称
		const topTool = window.document.createElement('div');
		topTool.innerText = '弹幕转发';
        topTool.style.cssText = 'text-align:center;line-height:20px;width:100%;color:rgb(210,143,166);font-size:14px;';

		// 最小化按钮
		const collapseButton = window.document.createElement('button');
		collapseButton.innerText = unfold[isunfold];
        collapseButton.style.cssText = 'float:right;width:40px;height:20px;border:none;cursor:pointer;background-color:#1890ff;border-radius:1px;color:#ffffff;';

		// 主窗口
		const mainWindow = window.document.createElement('div');
        mainWindow.style.cssText = 'width:100%;background-color:rgba(220, 192, 221, .5);padding:10px;box-sizing:border-box;';
        if(isunfold==0){
           mainWindow.style.display = "none";
        }

		// 直播间号输入框
		const textArea = window.document.createElement('textarea');
        textArea.placeholder = '转发的直播间号,换行分隔'
        textArea.style.cssText = 'width:100%;height:60px;resize:none;outline:none;background-color:rgba(255,255,255,.5);';

		// 按钮区容器
		const buttonArea = window.document.createElement('div');
        buttonArea.style.cssText = 'width:100%;height:30px;box-sizing:border-box;display:flex;';

		// 开始按钮
		const goButton = window.document.createElement('button');
		goButton.innerText = '开始';
        goButton.style.cssText = 'width:max-content;height:28px;padding:0 5px;margin-left:5px;';

       //用户UID
        const uidBox = window.document.createElement('input');
        uidBox.placeholder = "输入用户uid";
        uidBox.style.cssText = 'width:70px;height:28px;padding:0 5px;margin-left:5px;';

       //发送间隔
        const interBox = window.document.createElement('input');
        interBox.value = 1;
        interBox.placeholder = "间隔(秒";
        interBox.style.cssText = 'width:40px;height:28px;padding:0 5px;margin-left: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.innerText = intext;
            div.style.cssText = 'box-sizing:border-box;width:200px;height:40px;position:fixed;bottom:40px;left:50px;z-index:999;background-color:rgba(255, 255, 0,.2);border-radius:5px;color:#FF0000;font-size:medium;line-height:40px;text-align: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);
     }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址