Greasy Fork

获取抖音弹幕

在线获取抖音直播间弹幕

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

// ==UserScript==
// @name         获取抖音弹幕
// @namespace    http://tampermonkey.net/
// @version      2024-01-02
// @description  在线获取抖音直播间弹幕
// @author       37
// @match        https://live.douyin.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
    'use strict';
    let ws;
    let observer;
    let wxUrl = 'wss://www.hzwelltodo.com/api/websocket/111/12'
    let waitMsgList = []
    let timeId ;
    function connectWebSocket() {
        ws = new WebSocket(wxUrl);
        ws.addEventListener('open', () => {
            console.log('连接成功');
            if(waitMsgList.length){//重新连接,并发送待发送数据
                console.log(waitMsgList)
                waitMsgList.forEach((item)=>{
                    ws.send(item)
                })
                waitMsgList = []
            }
            timeId = setInterval(()=>{//与服务器实时保持通信 
                ws.readyState === 1 && ws.send(JSON.stringify({"type":2,"answerText":"连接正常"}))
            },30000)
        });
        ws.addEventListener('message', event => {
            console.log('从服务器接收到消息:', event.data);
        });
        ws.addEventListener('close', (event) => {
            setTimeout(()=>{
                console.log('WebSocket 已关闭--正在重新连接');
                connectWebSocket()
            },3000)
            clearInterval(timeId)
        });
    }

    function startObserver() {
        observer = new MutationObserver(mutationsList => {
            mutationsList.forEach(mutation => {
                mutation.addedNodes.forEach(addedNode => {
                    if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.classList.contains('webcast-chatroom___enter')) {
                        const userElement = addedNode.querySelector('.u2QdU6ht');
                        const contentElement = addedNode.querySelector('.webcast-chatroom___content-with-emoji-text');
                        if (contentElement) {
                            console.log(userElement.textContent, contentElement.textContent);
                            const dataToSend = {
                                answerText: contentElement.textContent,
                                type:1
                            };
                            if(ws.readyState === 1){
                                ws.send(JSON.stringify(dataToSend))
                            }else{
                                waitMsgList.push(JSON.stringify(dataToSend))
                            } 
                        }
                    }
                });
            });
        });
        observer.observe(document.documentElement, { childList: true, subtree: true });
    }

    function stopObserver() {//在需要停止时调用 stopObserver() 来停止观察器并清理资源
        if (observer) {
            observer.disconnect();
            observer = null;
        }
    }

    connectWebSocket();
    startObserver();

    // function tN(et) { //此方法为抖音直播解析websocket加密数据函数,由于js标签跨域需要代理服务器至本地,然后遍历所有标签再注入js,比较繁琐,等有更多空闲时间再研究
    //     return (ei,en)=>tD(this, null, function*() {
    //         ei.decoder = et;
    //         let {msgs: eo, systemEmitter: eA} = ei;
    //         return ei.msgs = yield Promise.all((null != eo ? eo : []).map(ei=>tD(this, null, function*() {
    //             let {payload: en, method: eo, msg_id: ec} = ei;
    //             tM("decode msg", eo, ec),
    //             tP("decode msg", eo, ec, ei);
    //             let eu = yield tD(this, null, function*() {
    //                 try {
    //                     return en && eo ? yield et.decode(en, eo) : void 0
    //                 } catch (et) {
    //                     return eA.emit("error", "decode", et),
    //                     en
    //                 }
    //             });
    //             eu || tM("no payload can be decoded, maybe cannot find idl", eo);
    //             let eh = tk(tT({}, ei), {
    //                 payload: eu
    //             });
    //             if(eh.method == "WebcastChatMessage"){ //此处注入代码 ,eh为被解析完成的数据
    //                 console.log(eh.payload.content)        
    //             }   
    //             return tL(eo, ec, eh),
    //             eh
    //         }))),
    //         en()
    //     })
    // }

})();