Youtube Live Replay Comment Counter

利用直播comment寻找直播回放中的热点片段方便剪辑man干活

目前为 2019-09-28 提交的版本。查看 最新版本

// ==UserScript==
// @name         Youtube Live Replay Comment Counter
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  利用直播comment寻找直播回放中的热点片段方便剪辑man干活
// @author       yuyuyzl
// @match        https://www.youtube.com/watch?v=*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// @grant        GM_info
// ==/UserScript==

(function() {
    'use strict';
    setTimeout(function(){
        var chatID=document.body.innerHTML.match(/"reloadContinuationData":{"continuation":".*?"/g)[1].split('\"')[5];
        //var chatID="op2w0wRjGlBDamdhRFFvTFoySnVTbkJrWTNSQlVITXFKd29ZVlVNeGIzQklWWEozT0hKMmJuTmhaRlF0YVVkd04wTm5FZ3RuWW01S2NHUmpkRUZRY3lBQkABWgUQoI2DAWAEcgIIBHgB"
        console.log(chatID);
        var timeStr=document.getElementsByClassName("ytp-bound-time-right")[0].innerText.split(":");
        console.log(timeStr);
        var videoLengthMs=0;
        for(var s of timeStr){
            videoLengthMs=videoLengthMs*60+(+s);
        }
        videoLengthMs*=1000;
        console.log(videoLengthMs);
        var comments={};
        var requestCount=0,requestDone=0;
        var animateBar=0;
        var node=document.createElement("DIV");
        function getChatReplay(chatID,offsetMs,callback){
            requestCount++;
            GM_xmlhttpRequest({
                method: "GET",
                cache: false,
                url:  "https://www.youtube.com/live_chat_replay/get_live_chat_replay?continuation="+chatID+"&playerOffsetMs="+offsetMs+"&hidden=false&pbj=1",
                onload:function(data){
                    var responseObj=JSON.parse(data.responseText);
                    //console.log(responseObj.response.continuationContents.liveChatContinuation.actions);
                    var itemsList={};
                    let minTime=2148473647;
                    let maxTime=0;
                    for(var item of responseObj.response.continuationContents.liveChatContinuation.actions){
                        try{
                            let itemArranged={
                                time: +item.replayChatItemAction.videoOffsetTimeMsec,
                                id: item.replayChatItemAction.actions[0].addChatItemAction.item.liveChatTextMessageRenderer.id,
                                text: item.replayChatItemAction.actions[0].addChatItemAction.item.liveChatTextMessageRenderer.message.runs[0].text
                            };
                            minTime=minTime>itemArranged.time?itemArranged.time:minTime;
                            maxTime=maxTime<itemArranged.time?itemArranged.time:maxTime;
                            itemsList[itemArranged.id]=itemArranged;
                        }
                        catch(e){}
                    }
                    requestDone++;
                    callback(itemsList,minTime,maxTime);
                }
            });
        }
        var lock=0;
        var timestart=new Date().getTime();
        function sliceBlankArea(left,right){
            if(requestCount>500)return;
            var reqTime=Math.round((left+right)/2);
            //console.log(left+"-sliceBlankArea-"+right);
            if(right-left>300000){
                sliceBlankArea(left,reqTime);
                sliceBlankArea(reqTime,right);
                return;
            }
            getChatReplay(chatID,reqTime,(data,min,max)=>{
                if(min>reqTime)min=reqTime;
                if(max<reqTime)max=reqTime;
                for(var key in data)comments[key]=data[key];
                //console.log("UPDATED COMMENTS, SIZE:"+Object.keys(comments).length);
                //console.log("REQCOUNT:"+requestCount)
                if(left<min)sliceBlankArea(left,min);
                if(max<right)sliceBlankArea(max,right);
                if(requestCount===requestDone){
                    clearInterval(animateBar);
                    console.log("sliceBlank DONE, time:"+(new Date().getTime()-timestart)+" REQCOUNT:"+requestCount);
                    const gradientCount=1000;
                    var commentCount=new Array(gradientCount+1);
                    for(let i=0;i<commentCount.length;i++)commentCount[i]=0;
                    for(let commentID in comments){
                        const comment=comments[commentID];
                        commentCount[Math.round(comment.time*gradientCount/videoLengthMs)]++;
                    }
                    console.log(commentCount);
                    var countMax=0;
                    var countMin=999999999;
                    for(let i=0;i<commentCount.length;i++){
                        countMax=countMax<commentCount[i]?commentCount[i]:countMax;
                        countMin=countMin>commentCount[i]?commentCount[i]:countMin;
                    }
                    console.log(countMax+","+countMin);

                    for(let i=0;i<commentCount.length;i++){
                        commentCount[i]="rgba(0,255,0,"+((commentCount[i]-countMin)/(countMax-countMin))+") "+(i*100/(commentCount.length-1))+"%";
                    }
                    console.log(commentCount);
                    node.style.background="linear-gradient(to right,"+commentCount.join(",")+")";
                }
            });

        }
        Node.prototype.prependChild = function (newNode){
            this.insertBefore(newNode,this.firstChild);
        }
        var btnStart=document.createElement("BUTTON");
        btnStart.innerText="运行评论热点分析";
        btnStart.style.background= "none";
        btnStart.style.border= "1px solid rgb(5,95,212)";
        btnStart.style.width= "100%";
        btnStart.style.height= "36px";
        btnStart.style.color= "rgb(5,95,212)";
        btnStart.onclick=function(){
            btnStart.disabled=true;
            node.style.height="100%";
            node.style.width="100%";
            node.style.position="absolute";
            node.style.bottom="0";
            node.style.left="0";
            node.style["z-index"]="32";
            document.getElementsByClassName("ytp-progress-bar-container")[0].appendChild(node);
            var animateCount=0;
            animateBar=setInterval(function(){
                animateCount=(animateCount+1)%20;
                node.style.background="rgba(0,255,0,"+(1-animateCount/19)+")"
            },50);
            sliceBlankArea(0,videoLengthMs);
        };
        document.getElementById("secondary-inner").prependChild(btnStart);



    },5000);

})();