您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Highlights the most worthwhile videos on YouTube. In addition to a ratings bar, there's also a blue "Power Meter" which measures people's enthusiasm for videos.
当前为
// ==UserScript== // @name Youtube Video Ratings Bar with Power Meter // @description Highlights the most worthwhile videos on YouTube. In addition to a ratings bar, there's also a blue "Power Meter" which measures people's enthusiasm for videos. // @version 2014.06.29 // @author lednerg // @license (CC) Attribution Non-Commercial Share Alike; http://creativecommons.org/licenses/by-nc-sa/3.0/ // @icon http://i.imgur.com/lslCELP.png // @include http://*.youtube.com/* // @include http://youtube.com/* // @include https://*.youtube.com/* // @include https://youtube.com/* // @grant GM_addStyle // @grant GM_xmlhttpRequest // @namespace https://gf.qytechs.cn/users/253 // ==/UserScript== GM_addStyle(""+ ".ratingsBar { "+ " transition: height 1s .15s; "+ " height: 4px; "+ " width: 100%; "+ " position: absolute; "+ " bottom: 0px; "+ " } "+ ".ratingsBar:hover { "+ " transition: height .5s .15s; "+ " height: 26px; "+ " } "+ ".dislikesBar { "+ " height: 100%; "+ " width: 100%; "+ " position: absolute; "+ " right: 0px; "+ " background-color: #CC0000; "+ " } "+ ".likesBar { "+ " height: 100%; "+ " position: absolute; "+ " background-color: #00BB22; "+ " } "+ ".powerBar { "+ " height: 100%; "+ " position: absolute; "+ " background-color: #0029FF; "+ " background-image: linear-gradient(90deg, transparent 70%, #35B5b9 70%); "+ " background-size: 10px 100%; "+ " } "+ ".hatesBar { "+ " height: 100%; "+ " position: absolute; "+ " background-color: #591DD1; "+ " background-image: linear-gradient(90deg, transparent 70%, #C96695 70%); "+ " background-size: 10px 100%; "+ " } "+ ".pausedBar { "+ " height: 100%; "+ " position: absolute; "+ " background-color: #00bb22; "+ " background-image: linear-gradient(-45deg, #99e449 25%, transparent 25%, transparent 50%, #99e449 50%, #99e449 75%, transparent 75%, transparent); "+ " background-size: 20px 20px; "+ " } "+ ".textBar { "+ " transition: opacity .25s .15s; "+ " opacity: 0; "+ " display: flex; "+ " align-items: center; "+ " width: 90%; "+ " height: 16px; "+ " padding: 5px 7.5% 5px 5px; "+ " position: absolute; "+ " bottom: 0px; "+ " margin-bottom: 0px; "+ " color: #f0f0c0; "+ " font-family: arial,sans-serif; "+ " font-size: 11px; "+ " line-height: 11px; "+ " font-weight: 700; "+ " text-align: left; "+ " text-shadow: black 0px 0px 7px, black 1px 1px 5px, black 1px 1px 4px, black 1px 1px 3px, black 1px 1px 0px; "+ " } "+ ".scanned:hover > .ratingsBar > .textBar, "+ ".video-list-item:hover .ratingsBar > .textBar, "+ ".feed-item-main-content:hover .ratingsBar > .textBar { "+ " transition: opacity .25s .15s; "+ " opacity: 1; "+ " } "+ ".textBar span { "+ " flex: 0 0 auto; "+ " } "+ ".textBar div { "+ " display: flex; "+ " flex-flow: row wrap; "+ " flex: 1 1 auto; "+ " } "+ ".shadingBar { "+ " transition: opacity 1s .15s; "+ " opacity: 0; "+ " height: 100%; "+ " width: 100%; "+ " position: absolute; "+ " bottom: 0px; "+ " background: linear-gradient( to bottom, rgba(0,0,0,0) 75%, rgba(0,0,0,.2) 90%, rgba(0,0,0,.6) 100% ) ; "+ " } "+ ".ratingsBar:hover > .shadingBar { "+ " transition: opacity .5s .35s; "+ " opacity: .85; "+ " } "+ ".middleBar, .powerBar, .dislikesBar, .pausedBar { "+ " transition: opacity 1s .0s, outline 1s .0s, outline-offset 1s .0s, border-right 1s .0s; height .5s .5s; "+ " opacity: 1; "+ " outline: 1px solid rgba(0,0,0,.0); "+ " outline-offset: 10px; "+ " } "+ ".ratingsBar:hover > .middleBar, .ratingsBar:hover > .powerBar, "+ ".ratingsBar:hover > .dislikesBar, .ratingsBar:hover > .pausedBar { "+ " transition: opacity .55s .35s, outline .35s .55s, outline-offset 0s .55s, border-right .35s .55s, height .35s .0s; "+ " opacity: 1; "+ " outline: 1px solid rgba(255,255,255,.75); "+ " outline-offset: 0px; "+ " } "+ ".ratingsBar:hover > .dislikesBar, "+ ".ratingsBar:hover > .likesBar { "+ "/*transition: height .25s .0s;*/ "+ " height: 90%; "+ " bottom: 0px; "+ " } "+ ".video-actions, .video-time { "+ " margin-bottom: 4px; "+ " } "+ ".video-actions { "+ " top: 2px; "+ " } "+ ".watched .video-thumb { "+ " opacity: 1 !important; "+ " } "+ ".watched .video-thumb img { "+ " transition: opacity 1s 1.5s; "+ " opacity: .5 !important; "+ " } "+ ".watched:hover .video-thumb img, "+ ".feed-item-main-content:hover .video-thumb img { "+ " transition: opacity .15s 0s; "+ " opacity: 1 !important; "+ " } "+ ".scanned .yt-thumb-clip { "+ " bottom: -96px; "+ " } "+ ".scanned .yt-thumb-default { "+ " margin-bottom: 4px; "+ " } "+ ".yt-thumb-72.scanned > .ratingsBar > * { "+ " zoom: .75 !important; "+ " } "+ ".playlist-video > .scanned > .ratingsBar > * { "+ " zoom: .8; "+ " } "); var lastScanTime = new Date().getTime(); scanVideos(); document.onload = function() { scanVideos(); }; // On some pages, YouTube adds thumbnails as you scroll down the page, // so this waits for scroll events and starts the scan for new video thumbnails. // (it's a bit lazy, and something I want to change later) window.onscroll = function() { var timeNow = new Date().getTime(); var timeDiff = timeNow - lastScanTime; if (timeDiff >= 1000) { scanVideos(); } }; function scanVideos() { // makes a list of video links which are not in the ".scanned" class yet. Once they are scanned, they will be added to it. var videoList = document.querySelectorAll('a.ux-thumb-wrap[href^="/watch"] > span.video-thumb:not(.scanned), a.related-video[href^="/watch"] > span:first-child:not(.scanned), a.playlist-video[href^="/watch"] > span.yt-thumb-64:first-child:not(.scanned)'); for ( var i = 0; i < videoList.length; i++ ) { // searches for the video id number which we'll use to poll YouTube for ratings information var videoId = videoList[i].parentNode.getAttribute("href").replace(/.*[v|s]=([^&%]*).*/, "$1"); getGdata(videoList[i],videoId); } lastScanTime = new Date().getTime(); } // Parts of this were copied from flux242's old script because I don't understand GM_xmlhttpRequest as well as I should. // I modified it to get the view count and date. It all seems to work and doesn't throw errors, so... yeah. function getGdata(node,videoId) { GM_xmlhttpRequest({ method: 'GET', url: "http://gdata.youtube.com/feeds/api/videos/" + videoId + "?v=2&alt=json&fields=yt:rating,yt:statistics,published", onload: function(response) { if (response.status === 200) { var rsp = eval( '(' + response.responseText + ')' ); if (rsp && rsp.entry && rsp.entry.published && rsp.entry.yt$statistics && rsp.entry.yt$rating) { var daysAgo = (lastScanTime - new Date(rsp.entry.published.$t).getTime())/1000/60/60/24; var views = parseInt(rsp.entry.yt$statistics.viewCount, 10); var likes = parseInt(rsp.entry.yt$rating.numLikes, 10); var dislikes = parseInt(rsp.entry.yt$rating.numDislikes, 10); makeBar(node, daysAgo, views, likes, dislikes); } else { // if there is no data, mark the thumbnail as "scanned" to avoid checking it over and over again node.classList.add('scanned'); } } } }); } // the ratings bar is made up of differently colored divs stocked on top of each other function makeBar(node, daysAgo, views, likes, dislikes) { // .ratingsBar is for the position (top/bottom) and size of the bar var container = document.createElement('div'); container.classList.add('ratingsBar'); // barMsg is for the "Power: X%" or "View Count Incorrect" messages for the tooltip var barMsg = ""; var totalVotes = likes + dislikes; if (dislikes > 0) { var dislikesBar = document.createElement('div'); dislikesBar.classList.add('dislikesBar'); container.appendChild(dislikesBar); } // Checks to see if the view count has been paused by YouTube. (301-309 views and less than half a day old, or more votes than views) // We do this because we need an accurate view count to calculate the Power Meter. // This lets the user know that we can't make one yet, but at least the likesBar/red ratings bar is still available if (((views > 300) && (views < 310) && (daysAgo <= 0.45)) || (totalVotes > views)) { if (likes > 0) { var pausedBar = document.createElement('div'); pausedBar.classList.add('pausedBar'); pausedBar.setAttribute("style","width:"+ (100 * likes / totalVotes) +"%;"); container.appendChild(pausedBar); } barMsg = '<div>View Count Paused </div>'; } else { powerMeterScore = powerMeter(views, likes); if (likes > 0) { var middleBar = document.createElement('div'); middleBar.classList.add('middleBar'); if ((100 * likes / totalVotes) >= powerMeterScore) { middleBar.classList.add('likesBar'); middleBar.setAttribute("style","width:"+(100 * likes / totalVotes)+"%;"); } else { middleBar.classList.add('hatesBar'); middleBar.setAttribute("style","width:"+powerMeterScore+"%;"); } container.appendChild(middleBar); } if (powerMeterScore > 0) { var powerBar = document.createElement('div'); powerBar.classList.add('powerBar'); if ((100 * likes / totalVotes) > powerMeterScore) { powerBar.style.width = powerMeterScore+"%"; } else { powerBar.style.width = ((100 * likes / totalVotes))+"%"; } barMsg = '<span><span style="color:#99ddff">'+ Math.round(powerMeterScore*10)/10 +'</span></span> '; container.appendChild(powerBar); } } // shadingBar gives the bar a 3D look when hovered var shadingBar = document.createElement('div'); shadingBar.classList.add('shadingBar'); container.appendChild(shadingBar); // textBar is the div with the numbers on it. var textBar = document.createElement('div'); textBar.classList.add('textBar'); textBar.innerHTML = '<div>'+ barMsg +'<div">(<span style="color:#77ff77">+'+ likes +' </span>/<span style="color:#ff9977"> -'+ dislikes +'</span>)</div></div>'; container.appendChild(textBar); node.insertBefore(container,node.childNodes[2]); node.classList.add('scanned'); } // trade secrets function powerMeter(views, likes) { var viewLikeRatio; if (views < 2000) { var viewLikeRatio2k = Math.round( (views + views * ((3000-views)/2000)) / (likes) ); if (views < 255) { viewLikeRatio = Math.round( viewLikeRatio2k / (views/255) ); } else { viewLikeRatio = viewLikeRatio2k; } } else { viewLikeRatio = Math.round( (views+7000) / 3 / (likes) ); } if ((viewLikeRatio < 1) || (viewLikeRatio > 255)) { return 0; } var powerMeterScore = Math.round(Math.pow(((255-viewLikeRatio)/2.55), 3)) / 10000; return powerMeterScore; }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址