Youtube 封面

獲取影片封面!

目前為 2021-03-06 提交的版本,檢視 最新版本

// ==UserScript==
// @name               Youtube 封面
// @name:en            Youtube Cover
// @name:zh-CN         youtube 封面
// @namespace          http://tampermonkey.net/
// @version            1.0.3
// @description        獲取影片封面!
// @description:en     Get the cover of youtube video!
// @description:zh-CN  获取视频封面!
// @author             Anong0u0
// @include            *//www.youtube.com/*
// @grant              none
// ==/UserScript==

console.log("youtube Cover is loading");
(async () => // onStart
{
    let tryTimes = 0;
    while(true)
    {
        console.log("try load");
        if(document.querySelector("#start")!=null)
        {
            load();
            return;
        }
        if(tryTimes>10) return;
        tryTimes++;
        await delay(300);
    }
})();


function delay(ms = 0){return new Promise((r)=>{setTimeout(r, ms)})}

function getXY(element)
{
    var x = 0, y = 0;
    while (element)
    {
        x += element.offsetLeft - element.scrollLeft + element.clientLeft;
        y += element.offsetTop - element.scrollLeft + element.clientTop;
        element = element.offsetParent;
    }
    return {X: x, Y: y}
}

function checkImg(imgUrl)
{
  return new Promise(function(resolve)
  {
      var img = new Image();
      img.src = imgUrl;
      img.onload = () => {resolve(img);}
  })
}


function load()
{
    var div = document.createElement("div");
    div.innerHTML =`

    <!-- css -->
    <style>
        #ytCover {
            text-decoration: none;
            font-size: 2em;
            font-weight: bolder;
            font-family: Roboto, Arial, sans-serif;
            color: var(--yt-spec-text-primary);
        }

        div.list {
            background-color: var(--yt-spec-brand-background-primary);
            border: 1px solid var(--yt-spec-10-percent-layer);
            padding: 0.5em 0;
            position: fixed;
            z-index: 999;
            max-height: 20em;
            font-size: 10px
        }

        .linkBtn {
            text-decoration: none;
        }

        .list-item {
            text-align: center;
            font-size: 1.5em;
            color: var(--yt-spec-text-primary);
            height: 2.5em;
            line-height: 2.5em;
        }
        .list-item:hover {
            background: #AAA;
            box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2);
        }

        .slide {
            cursor: default
        }

    </style>

    <!-- html -->
    <div>
        <div class="slide" id="ytCover"></div>

        <div class="list" id="ytListHead" style="border-top: none; top: 4.8em; left: 19em; width: 9.6em" hidden>

            <div class="list-item slide" tag="maxres">1280x720+
                <div class="list" style="border-left: none; width: 11.5em" hidden>
                    <a class="linkBtn" imgTag="maxresdefault"><div class="list-item">maxresdefault</div></a>
                    <a class="linkBtn" imgTag="maxres1"><div class="list-item">maxres1</div></a>
                    <a class="linkBtn" imgTag="maxres2"><div class="list-item">maxres2</div></a>
                    <a class="linkBtn" imgTag="maxres3"><div class="list-item">maxres3</div></a>
                </div>
            </div>

            <div class="list-item slide" tag="sd">640x480
                <div class="list" style="border-left: none; width: 8.5em" hidden>
                    <a class="linkBtn" imgTag="sddefault"><div class="list-item">sddefault</div></a>
                    <a class="linkBtn" imgTag="sd1"><div class="list-item">sd1</div></a>
                    <a class="linkBtn" imgTag="sd2"><div class="list-item">sd2</div></a>
                    <a class="linkBtn" imgTag="sd3"><div class="list-item">sd3</div></a>
                </div>
            </div>

            <div class="list-item slide" tag="hq">480x360
                <div class="list" style="border-left: none; width: 8.5em" hidden>
                    <a class="linkBtn" imgTag="hqdefault"><div class="list-item">hqdefault</div></a>
                    <a class="linkBtn" imgTag="hq1"><div class="list-item">hq1</div></a>
                    <a class="linkBtn" imgTag="hq2"><div class="list-item">hq2</div></a>
                    <a class="linkBtn" imgTag="hq3"><div class="list-item">hq3</div></a>
                </div>
            </div>

            <div class="list-item slide" tag="mq">320x180
                <div class="list" style="border-left: none; width: 8.5em" hidden>
                    <a class="linkBtn" imgTag="mqdefault"><div class="list-item">mqdefault</div></a>
                    <a class="linkBtn" imgTag="mq1"><div class="list-item">mq1</div></a>
                    <a class="linkBtn" imgTag="mq2"><div class="list-item">mq2</div></a>
                    <a class="linkBtn" imgTag="mq3"><div class="list-item">mq3</div></a>
                </div>
            </div>

            <div class="list-item slide" tag="skip">120x90
                <div class="list" style="border-left: none; width: 6.5em" hidden>
                    <a class="linkBtn" imgTag="default"><div class="list-item">default</div></a>
                    <a class="linkBtn" imgTag="1"><div class="list-item">1</div></a>
                    <a class="linkBtn" imgTag="2"><div class="list-item">2</div></a>
                    <a class="linkBtn" imgTag="3"><div class="list-item">3</div></a>
                </div>
            </div>

        </div>
    </div>`

    document.querySelector("#start").append(div);

    var ytC = document.querySelector("#ytCover");
    var ytLH = document.querySelector("#ytListHead");

    document.querySelectorAll(".linkBtn").forEach((e)=>{e.target="_blank"});
    ytC.innerText = document.querySelector("html").lang.indexOf("zh")!=-1?"封面":"Cover";;

    window.onresize = () => {ytLH.style.left = (getXY(ytC).X/10-1)+"em";}

    document.querySelectorAll(".list > .slide").forEach((e)=>
    {
        let list = e.querySelector(".list");
        e.onmouseenter = () =>
        {
            list.style.top = (getXY(e).Y/10-0.5)+"em";
            list.style.left = parseFloat(ytLH.style.left) + 9.7 + "em";
            list.hidden = false;
        };
        e.onmouseleave = () => {list.hidden = true;}
    })

    var hide;
    ytC.onmouseenter = () =>
    {
        hide = false;
        ytLH.hidden = false;
    };
    ytC.onmouseleave = async () =>
    {
        hide = true;
        await delay(500);
        ytLH.hidden = hide;
    };
    ytLH.onmouseenter = () =>
    {
        hide = false;
    };
    ytLH.onmouseleave = async () =>
    {
        hide = true;
        await delay(200);
        ytLH.hidden = hide;
    };


    var oldHref = null
    new MutationObserver(() => // onUrlChange
    {
        if (oldHref != document.location.href)
        {
            oldHref = document.location.href

            let video_id = null;
            window.location.search.replace("?","").split('&').forEach((s)=>{if(s.startsWith("v=")){video_id=s.replace("v=","")};});
            ytC.hidden = (video_id == null);
            if (video_id == null) return;

            document.querySelectorAll(".list > .slide").forEach(async (e)=>
            {
                if (e.getAttribute("tag")=="skip") return;
                let url = "https://i.ytimg.com/vi/" + video_id + "/" + e.getAttribute("tag") + "default.jpg";
                checkImg(url).then((img)=>{e.hidden=!(img.width>120 && img.height>90);});
            });

            let Btns = document.querySelectorAll(".linkBtn");
            Btns.forEach((e)=>{e.href = "https://i.ytimg.com/vi/" + video_id + "/" + e.getAttribute("imgTag") + ".jpg";});
            checkImg("https://i.ytimg.com/vi/" + video_id + "/mq1.jpg").then((img)=>
            {
                if(img.width<=120 && img.height<=90)
                    {Btns.forEach((e)=>{e.hidden=(e.getAttribute("imgTag").indexOf("default")==-1);});}
                else
                    {Btns.forEach((e)=>{e.hidden=false});}
            });
        }
    }).observe(document.body, {childList: true, subtree: true});

    console.log("done");
}



QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址