您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
绘制直播过程中的在线人数变化曲线,支持下载数据或图片
// ==UserScript== // @name Youtube直播在线人数记录 // @namespace http://tampermonkey.net/ // @namespace https://github.com/artyyin/YoutubeLiveOnline // @version 0.41 // @description 绘制直播过程中的在线人数变化曲线,支持下载数据或图片 // @author [email protected] // @match https://www.youtube.com/watch?v=* // @require https://code.jquery.com/jquery-1.11.3.min.js // @require https://code.highcharts.com/highcharts.js // @require https://code.highcharts.com/modules/series-label.js // @require https://code.highcharts.com/modules/exporting.js // @require https://code.highcharts.com/modules/offline-exporting.js // @require https://code.highcharts.com/modules/export-data.js // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // ==/UserScript== (function() { //'use strict'; var mainkey ="monkey-youtube-number-online-123456789" var prefixofdatakey='artyyby-'; var debug_switch = false; var onlinedata =new Array() var hisdata; var HistroyVisible=true; var chart; var aq_interval=5*1000; var n=0; var datakey ; var testdata = [ [new Date(2018,7,16,23,49,4).getTime(),7296] ]; var timer_2; //deleteAllKeys(); //listAllKeys(); reset() setTimeout(delay_init, 5*1000); function reset() { if(timer_2!=undefined) { clearTimeout(timer_2) timer_2=undefined } if(chart!=undefined) { $("#online_chartwin").remove() chart=undefined } onlinedata =new Array() hisdata=undefined HistroyVisible=true n=0; datakey=undefined testdata = [ [new Date(2018,7,16,23,49,4).getTime(),7296] ]; } function delay_init() { if($('button.ytp-live-badge.ytp-button').length==0) { setTimeout(delay_init, 5*1000); console.log('wait 5s , retry to find button'); return; } if($('button.ytp-live-badge.ytp-button').is(":visible")==false) { //alert("no live") n+=1; if(n<=4) { setTimeout(delay_init, 5*1000); console.log('wait 5s , retry to live state'); } else { console.log('not live stream, exit'); } return } datakey = ceateAndAddKey(); add_chart_winnode() showchartwin() timer_2 = setTimeout(onTimer_2, aq_interval); } function add_chart_winnode() { var windivnode =$('<div id="online_chartwin"></div>') windivnode.css({ /*希望窗口有边框*/ 'border': '1px #0769ad solid', /*希望窗口宽度和高度固定,不要太大*/ //'width': '500px', //'height': '300px', /*希望控制窗口的位置*/ //'position': 'absolute', //'top': '100px', //'left': '350px', /*希望窗口开始时不可见*/ 'display': 'none' }); var titledivnode = $('<div id="online_charttitle">在线人数记录</div>') titledivnode.css({ /*控制标题栏的背景色*/ 'background-color': '#7cB5EC', /*控制标题栏中文字的颜色*/ 'color': 'white', /*控制标题栏的左内边距*/ 'padding-left':'3px' }) var closebuttonnode = $('<span id="online_chartclose">[X]</span>') closebuttonnode.css({ /*使关闭按钮向右侧移动*/ //'position':'relative', 'margin-right': '5px', //'right':'-10px', 'float':'right', /*让鼠标进入时可以显示小手,告知用户可以点击操作*/ 'cursor': 'pointer' }) closebuttonnode.click(onbuttonclick) var contentdivnode = $('<div id="online_chartcontent">窗口</div>') contentdivnode.css({ 'padding-left': '3px', 'padding-top': '5px' }) windivnode.append(titledivnode) windivnode.append(contentdivnode) titledivnode.append(closebuttonnode) $("#meta-contents").after(windivnode) addChart() } function addChart() { var dafaultMenuItem = Highcharts.getOptions().exporting.buttons.contextButton.menuItems; var myMenuItem=[ { separator: true }, { text:'隐藏历史数据', onclick:hideHistoryData }, { text:'显示历史数据', onclick:showHistoryData }, { text: '清除历史数据', onclick:clearCurrentPageKey }, { text: '清除所有历史数据', onclick:clearAppKeys//deleteAllKeys } ] dafaultMenuItem.pop(); dafaultMenuItem.pop(); myMenuItem = dafaultMenuItem.concat(myMenuItem); //console.log(myMenuItem); Highcharts.setOptions({ global: { useUTC: false } }); //console.log('addChart') chart = Highcharts.chart('online_chartcontent', { chart: { //type: 'scatter', plotBorderWidth: 1, zoomType: 'x' }, title: { text: 'youtube直播在线人数--'+$('#text > a').text()//document.title.substring(0,50)//'在线人数--youtube直播' }, subtitle: { useHTML:true, text:getSubTitle() }, xAxis: { dateTimeLabelFormats: { millisecond: '%H:%M:%S.%L', second: '%H:%M:%S', minute: '%H:%M', hour: '%H:%M', day: '%Y-%m-%d', week: '%m-%d', month: '%Y-%m', year: '%Y' }, title: { text: '时间' }, type: 'datetime' }, yAxis: { //min:0, title: { text: '人数' } }, legend:{enabled:false}, tooltip: { headerFormat: '<b>时间:{point.x:%Y-%m-%d %H:%M:%S}</b><br>', pointFormat : '<b>人数: {point.y:.0f} 人</b>' }, plotOptions: { line:{ lineWidth : 2, marker: {radius:3} } }, exporting: { buttons: { contextButton: { menuItems:myMenuItem } } }, series: [{ name: '在线人数', type: 'line', data: testdata }] }); //console.log('addCHart() end') hisdata = loadHistoryData(); if(hisdata.length>0) { var tmp=[] tmp = tmp.concat(hisdata) chart.series[0].setData(tmp) } else { chart.series[0].removePoint(0); } //console.log(chart.options.exporting.buttons.contextButton.menuItems) } function getSubTitle() { var s = $('#container > h1 > yt-formatted-string').text(); if(s.length>50) { s = s.substring(0,30)+' ... '+s.substring(s.length-15); } return '<p align="center">'+s+'</p>' } function onbuttonclick() { var winNode = $("#online_chartcontent"); if(winNode.is(":hidden")) { //winNode.show(); winNode.fadeIn("slow"); } else { //winNode.hide(); winNode.fadeOut("slow"); } } //显示曲线窗口 function showchartwin() { //lert("准备显示弹出窗口啦!!!"); //1.找到窗口对应的div节点 var winNode = $("#online_chartwin"); //2.让div对应的窗口显示出来 //方法1,修改节点的css值,让窗口显示出来 //winNode.css("display","block"); //方法2,利用Jqeury的show方法 //winNode.show("slow"); //方法3,利用JQuery的fadeIn方法 winNode.fadeIn("slow"); } //定时采集数据 function onTimer_2() { var point = getNumberOfOnline() var idx = onlinedata.length; chart.series[0].addPoint(point, true, false); //activeLastPointToolip(chart); onlinedata[idx] = point GM_setValue(datakey,onlinedata); timer_2 = setTimeout(onTimer_2, aq_interval); } function activeLastPointToolip(chart) { var points = chart.series[0].points; chart.tooltip.refresh(points[points.length -1]); } function getTestData() { var currentdate = new Date().getTime(); var numofonline =5000+700*Math.sin(onlinedata.length/3.14) + Math.floor(Math.random()*700+1) var result =new Array() result[0]=currentdate result[1]=numofonline if(debug_switch) { var datestr = result[0] var logmsg = datestr+" | "+result[1] console.log(logmsg); } return result } //采集在线人数 function getNumberOfOnline() { let currentdate = (new Date()).getTime(); //var elm = $("div[id=info-text]>div[id=count]>ytd-video-view-count-renderer>span:first-child") let elm = $("div[id=info-container]>yt-formatted-string[id=info]>span:first-child") let numtext = elm.text() let numstr=/[0-9,]+/.exec(numtext).toString(); let numofonline =parseInt(numstr.replace(',','')); if(debug_switch) { let logmsg = currentdate+" | "+numofonline+" | "+ numtext console.log(logmsg); } let result =new Array() result[0]=currentdate result[1]=numofonline return result } function listAllKeys() { var allkey = GM_listValues(); for (var idx in allkey) { var data = GM_getValue(allkey[idx]); console.log(idx,allkey[idx]); console.log(data); } } function deleteAllKeys() { var allkey = GM_listValues(); for (var idx in allkey) { GM_deleteValue(allkey[idx]); } } function clearAppKeys() { var allurl = GM_getValue(mainkey,[]); for (var u in allurl) { var url = allurl[u]; var alldatakey = GM_getValue(url,[]) for(var d in alldatakey) { GM_deleteValue(alldatakey[d]) } GM_deleteValue(url) } GM_getValue(mainkey) var allkey = GM_listValues(); for (var idx in allkey) { if(allkey[idx].indexOf(prefixofdatakey)==0) { GM_deleteValue(allkey[idx]); } } } function clearCurrentPageKey() { var alldatakey = GM_getValue(document.URL,[]); for(var d in alldatakey) { GM_deleteValue(alldatakey[d]) } } function ceateAndAddKey() { var allurl = GM_getValue(mainkey,[]) var url = document.URL; if(!allurl.includes(url)) { allurl[allurl.length] = url GM_setValue(mainkey,allurl) } var idx = url.indexOf('?v=') var timestr = new Date().toLocaleString(); var dkey = prefixofdatakey+url.substring(idx+3)+timestr var keyarray = GM_getValue(url,[]) keyarray[keyarray.length]=dkey GM_setValue(url,keyarray) return dkey } function loadHistoryData() { var url = document.URL; var alldatakey = GM_getValue(url) var result=[]; for(var i in alldatakey) { var cur_data = GM_getValue(alldatakey[i]); if(cur_data!=undefined) { result = result.concat(cur_data); } } return result; } function hideHistoryData() { if(HistroyVisible) { //alert(HistroyVisible) var data=[]; console.log('hideHistoryData 0:', data.length, hisdata.length, onlinedata.length) data = data.concat(onlinedata) console.log('hideHistoryData 1:', data.length, hisdata.length, onlinedata.length) chart.series [0].setData(data)//,true,new Highcharts.AnimationOptions({duration:1000})); console.log('hideHistoryData 2:', data.length, hisdata.length, onlinedata.length) //console.log(data) HistroyVisible = false; } } function showHistoryData() { if(!HistroyVisible) { clearTimeout(timer_2) var tmp=[]; //console.log('showHistoryData 0:',tmp.length, hisdata.length, onlinedata.length) tmp = tmp.concat(hisdata) tmp = tmp.concat(onlinedata) //console.log('showHistoryData 1:',tmp.length, hisdata.length, onlinedata.length) //chart.series[0].setData([ [new Date(1970,1,1).getTime(),7296] ],false) chart.series[0].setData(tmp) timer_2 = setTimeout(onTimer_2, aq_interval); HistroyVisible = true; } } function getAbsoluteUrl(url){ var a = document.createElement('A'); a.href = url; // 设置相对路径给Image, 此时会发送出请求 url = a.href; // 此时相对路径已经变成绝对路径 return url; } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址