b站低质弹幕过滤 测试版 bilibili 哔哩哔哩

低质弹幕屏蔽测试版,屏蔽无意义的弹幕如“哈哈哈哈”,刷屏弹幕如“完结撒花”。随便写的脚本,虽然搞过nlp,但都是语义建模,很少接触表达建模,而且js也不循序太高的复杂度,所以目前用的是简单测词频法,后续还会慢慢优化。

// ==UserScript==
// @name         b站低质弹幕过滤 测试版 bilibili 哔哩哔哩
// @namespace    http://tampermonkey.net/
// @version      0.0.3
// @description  低质弹幕屏蔽测试版,屏蔽无意义的弹幕如“哈哈哈哈”,刷屏弹幕如“完结撒花”。随便写的脚本,虽然搞过nlp,但都是语义建模,很少接触表达建模,而且js也不循序太高的复杂度,所以目前用的是简单测词频法,后续还会慢慢优化。
// @author       You
// @match        https://www.bilibili.com/video/*
// @grant        none
// ==/UserScript==

function GET(url,fun=function(x){console.log(x.responseText)}){
    const xhr = new XMLHttpRequest()
    xhr.open('get',url)
    xhr.send()
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4 && xhr.status == 200){
            fun(xhr)
        }
    }
}
(function() {
    'use strict';
    const cid = window.__INITIAL_STATE__.videoData.cid
    console.log('video cid',cid)
    const danmuURL = 'https://api.bilibili.com/x/v1/dm/list.so?oid='+cid
    console.log('danmu url:',danmuURL)
    const k = 5  //屏蔽强度 1~10,10最强
    GET(danmuURL,function(xhr){
        const xml = xhr.responseXML
        xml.getElementsByTagName('d')
        const danmuList = []
        for(let d of xml.getElementsByTagName('d')){
            const danmu = d.textContent.replace(/[~!@#$(),.?''""!(),。?“”‘’;:;: +-=\\、·…]/g,'').toLowerCase()
            if(!!danmu){
                danmuList.push(danmu+'#')
            }
        }
        console.log(danmuList)
        const char_dict = {}
        const word_dict = {}
        let total_char = 0
        for(let danmu of danmuList){
            for(let i=0;i<danmu.length-1;i++){
                const cc = danmu[i]
                const nc = danmu[i+1]
                if(!(cc in char_dict)){
                    char_dict[cc] = 0
                }
                if(!(cc in word_dict)){
                    word_dict[cc] = {'total':0}
                }
                if(!(nc in word_dict[cc])){
                    word_dict[cc][nc] = 0
                }
                char_dict[cc] += 1
                word_dict[cc][nc] += 1
                word_dict[cc]['total'] += 1
                total_char += 1
            }
        }
        for(let c in char_dict){
            char_dict[c] = char_dict[c]/total_char
        }
        console.log('char dict',char_dict)
        for(let cc in word_dict){
            let total_nc = word_dict[cc].total
            for(let nc in word_dict[cc]){
                word_dict[cc][nc] = char_dict[cc]*word_dict[cc][nc] / total_nc
            }
        }
        let danmuFreqList = []
        for(let danmu of danmuList){
            let freq = 0
            for(let i = 0;i < danmu.length -1;i++){
                freq += word_dict[danmu[i]][danmu[i+1]]
            }
            freq /= danmu.length-1
            danmuFreqList.push([danmu,freq])
        }
        danmuFreqList = danmuFreqList.sort(function(a,b){
            return b[1] - a[1]
        })
        const size = parseInt(danmuList.length * k / 10)
        const removed_danmu = new Set()
        for(let i =0;i<size;i++){
            removed_danmu.add(danmuFreqList[i][0].substring(0,danmuFreqList[i][0].length-1))
        }
        console.log('danmu  freq list',danmuFreqList)
        console.log('removed danmu list',removed_danmu)
        function addOBS(){
            const container = document.getElementsByClassName('bilibili-player-video-danmaku')[0]
            if(container){
                const init_danmu = container.getElementsByClassName('b-danmaku')
                for(let danmu of init_danmu){
                    if(removed_danmu.has(danmu.innerText.replace(/[~!@#$(),.?''""!(),。?“”‘’;:;: +-=\\、·…]/g,'').toLowerCase())){
                        console.log('屏蔽',danmu.innerText)
                        danmu.innerText = ''
                    }
                }
                function obsFunc(mutations,observer){
                    for(let mutation of mutations){
                        const target = mutation.target
                        if('b-danmaku' == target.className){
                            if(removed_danmu.has(target.innerText.replace(/[~!@#$(),.?''""!(),。?“”‘’;:;: +-=\\、·…]/g,'').toLowerCase())){
                                console.log('屏蔽',target.innerText)
                                target.innerText = ''
                            }
                        }
                    }
                }

                const config = {childList: true, subtree: true}
                const obser = new MutationObserver(obsFunc)
                obser.observe(container,config)

            }else{
                requestAnimationFrame(addOBS)
            }
        }
        addOBS()  
        
    })
    // Your code here...
})();