Greasy Fork

Greasy Fork is available in English.

视频嗅探

自动嗅探页面上的视频资源,将链接展示出来,并提供复制和下载方法(除部分流媒体不能下载,需要专用的下载器)。

当前为 2023-07-05 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         视频嗅探
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  自动嗅探页面上的视频资源,将链接展示出来,并提供复制和下载方法(除部分流媒体不能下载,需要专用的下载器)。
// @author       geigei717
// @license      MIT
// @match        https://*/*
// @match        http://*/*
// @icon         https://img-blog.csdnimg.cn/20181221195058594.gif
// @require      https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js
// @grant        GM_addElement
// @grant        GM_download
// @grant        GM_setClipboard
// ==/UserScript==

(function() {
    GM_addElement('script', {
        src: 'https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js',
        type: 'text/javascript'
    });
    let URLs = [];
    unsafeWindow.GM_D = [];
    unsafeWindow.download = function (url,name){
        GM_download(url, name);
    }
    //$("head").append('<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> ')
    var m = -1,n=0;
    $("body").append("<div id='MyUrls' style='width: 400px;background-color: #3e8f3e;color: black;position: fixed;top: 0;right: 0;z-index: 99999;border-radius: 10px;display: none;'>" +
            "<div style='height: 30px;font-size: 20px;'>&nbsp&nbsp&nbsp视频链接:<span style='font-size: 10px;color:red;'>部分m3u8等流媒体无法下载,需要专用下载器</span></div>" +
            "<hr style='border-color: black;margin: 5px 5px'>" +
            "<div class='MyUrls' style='margin: 10px 10px;max-height: 500px;overflow-y: auto;'>" +
            "   <div class='urlnone' style='height: 30px;color: red'> 暂时没有嗅探到视频资源</div>" +
            "</div>" +
            "</div>")
            .append("<div id='MyUpDown' style='width: 30px;height: 30px;color: black;background-color: #3e8f3e;position: fixed;top: 0;right: 0;z-index: 100000;font-size: 20px;line-height: 30px;text-align: center;cursor: pointer;border-radius: 30px;'>" +
                    "<span style='font-size: 30px;line-height: 30px;'>+</span>" +
                    "</div>")
    $(".MyUrls").append("<div class='downloadUrl' style='padding: 5px 0;height: 30px;'> <input  class='downUrl'  style='position: relative;top: -2px;font-size: 12px;width: 200px;display: inline-block;max-width: 240px;word-wrap: break-word;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;margin: 0px;height: 20px;border: 1px solid white;border-radius: 5px;padding: 0 5px; background: white;color:black' placeholder='请输入要下载的视频链接:'>  <input class='downName' style='position: relative;top: -2px;font-size: 12px;width: 80px;display: inline-block;max-width: 240px;word-wrap: break-word;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;margin: 0px;height: 20px;border: 1px solid white;border-radius: 5px;padding: 0 5px; background: white;color:black'  placeholder='请输入文件名'><button class='SaveUrl1' style='margin-left: 5px;height: 20px;width: 50px;padding: 0;border: none;background: white;border-radius:10px;cursor: pointer;'>下载</button><button class='StopSaveUrl1' style='display: none;margin-left: 5px;height: 20px;width: 50px;padding: 0;border: none;background: white;border-radius:10px;cursor: pointer;'>0%</button></div>")
    //下载链接
    $(".SaveUrl1").click(function (){
        //$(obj).attr("disabled","disabled")
        var that = $(this)
        $(that).css("display","none").next('.StopSaveUrl1').css("display","inline-block")
        var url = $(that).prevAll(".downUrl").val()
        var name = $(that).prevAll(".downName").val()
        if(name.trim()==""||name==undefined){
            name = url.split("/").pop().split("?")[0]
            if(name.trim() ==''||name==undefined){ name = "video.mp4"}
        }
        if(! /\.[\w]+$/.test(name)){ name = name + ".mp4"}
        const download = GM_download({
            url: url,
            name: name,
            onprogress : function (event) {
                if (event.lengthComputable) {
                    var loaded = parseInt(event.loaded / event.total * 100);
                    if(loaded==100){
                        $(that).text("下载").css("display","inline-block").next('.StopSaveUrl1').css("display","none")
                    }else{
                        $(that).next('.StopSaveUrl1').text(loaded+"%")
                    }
                }
            },
            onload : function () {
                $(that).text("下载").css("display","inline-block").next('.StopSaveUrl1').css("display","none").text("0%")
            },
            onerror : function () {
                $(that).text("继续").css("display","inline-block").next('.StopSaveUrl1').css("display","none")
            }
        });
        var num =GM_D.push(download)
        $(that).next('.StopSaveUrl1').data('num',num-1)
    })
    $(".StopSaveUrl1").click(function (){
            var num = $(this).data("num")
            GM_D[num].abort()
            //GM_D.splice(num,1);
    })

    for(var i=0;i<100;i++){
        $(".MyUrls").append("<div class='noneUrl' style='padding: 5px 0;height: 30px;display:none;'> <p style='position: relative;top: 5px;font-size: 12px;width: 200px;display: inline-block;max-width: 240px;word-wrap: break-word;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;margin: 0px;height: 20px;border: 1px solid white;border-radius: 5px;padding: 0 5px; background: white;' ></p><button class='GoUrl' style='margin-left: 5px;height:20px;width: 50px;padding: 0;border: none;background: white;border-radius:10px;cursor: pointer;'>访问</button><button class='CopyUrl' style='margin-left: 5px;height:20px;width: 50px;padding: 0;border: none;background: white;border-radius:10px;cursor: pointer;'>复制</button><button class='SaveUrl' style='margin-left: 5px;height: 20px;width: 50px;padding: 0;border: none;background: white;border-radius:10px;cursor: pointer;'>下载</button><button class='StopSaveUrl' style='display: none;margin-left: 5px;height: 20px;width: 50px;padding: 0;border: none;background: white;border-radius:10px;cursor: pointer;'>0%</button></div>")
    }
    $("#MyUpDown").click(function () {
        $("#MyUrls").slideToggle("slow", function () {
            if (m=="1"){
                $("#MyUpDown span").text('+')
            }else {
                $("#MyUpDown span").text('–')
            }
            m = -m;
        });
    })

    //复制链接
    $(".GoUrl").click(function (){
        var url = $(this).prevAll("p").attr("title")
        window.open(url)
    })
     //复制链接
    $(".CopyUrl").click(function (){
        var url = $(this).prevAll("p").attr("title")
        GM_setClipboard(url);
        $(this).text("已复制")
    })

    //下载链接
    $(".SaveUrl").click(function (){
        //$(obj).attr("disabled","disabled")
        var that = $(this)
        $(that).css("display","none").next('.StopSaveUrl').css("display","inline-block")
        var url = $(that).prevAll("p").attr("title")
        var name = url.split("/").pop().split("?")[0]
        if(name==''||name==undefined){ name = "video.mp4"}
        if(! /\.[\w]+$/.test(name)){ name = name + ".mp4"}
        const download = GM_download({
            url: url,
            name: name,
            onprogress : function (event) {
                if (event.lengthComputable) {
                    var loaded = parseInt(event.loaded / event.total * 100);
                    if(loaded==100){
                        $(that).text("下载").css("display","inline-block").next('.StopSaveUrl').css("display","none")
                    }else{
                        $(that).next('.StopSaveUrl').text(loaded+"%")
                    }
                }
            },
            onload : function () {
                $(that).text("下载").css("display","inline-block").next('.StopSaveUrl').css("display","none").text("0%")
            },
            onerror : function () {
                $(that).text("继续").css("display","inline-block").next('.StopSaveUrl').css("display","none")
            }
        });
        var num =GM_D.push(download)
        $(that).next('.StopSaveUrl').data('num',num-1)
    })
    $(".StopSaveUrl").click(function (){
        var num = $(this).data("num")
        GM_D[num].abort()
    })


    function getNetworkRequsts(){
       return performance.getEntriesByType("resource").filter((entry) => {
            return entry.initiatorType === "xmlhttprequest"||entry.initiatorType === "video";
        });
    }
    var observer = new PerformanceObserver(perf_observer);
    observer.observe({entryTypes: ["resource"]})

    function perf_observer(list,observer){
        var z
        var scripts =getNetworkRequsts()
        scripts.forEach(function (x,i) {
            if (x.initiatorType === "xmlhttprequest") {
                z = x.name
                if(/m3u8/.test(x.name) && !/\.ts/.test(x.name)){
                if(! URLs.includes(z) ){
                    URLs.push(z)
                    //console.log('type: m3u8 , url: ' + x.name)
                    $(".urlnone").remove()
                    $(".MyUrls .noneUrl:first").css("display","block").attr("class","isUrl").children("p").attr('title',z).text(z).nextAll(".SaveUrl").css("display","none")
                    //$(".MyUrls").append("<div style='height: 30px;'> <input style='width: 240px' value='' readonly><button class='CopyUrl' style='margin-left: 5px;height: 24px;width: 50px;padding: 0;border: none;background: white;border-radius:0;'>复制</button>")
                }
                }else if(/\.mp4$/.test(z.split('?')[0])){
                    if(! URLs.includes(z) ){
                    URLs.push(z)
                    //console.log('type: m3u8 , url: ' + x.name)
                    $(".urlnone").remove()
                    $(".MyUrls .noneUrl:first").css("display","block").attr("class","isUrl").children("p").attr('title',z).text(z)
                    //$(".MyUrls").append("<div style='height: 30px;'> <input style='width: 240px' value='' readonly><button class='CopyUrl' style='margin-left: 5px;height: 24px;width: 50px;padding: 0;border: none;background: white;border-radius:0;'>复制</button>")
                }
                }
            }
            if (x.initiatorType === "video" && !/\.jpg/.test(x.name)) {
                z = x.name
                if(! URLs.includes(z) ){
                    URLs.push(z)
                    //console.log('type: video , url: ' + x.name)
                    $(".urlnone").remove()
                    $(".MyUrls .noneUrl:first").css("display","block").attr("class","isUrl").children("p").attr('title',z).text(z)
                    //$(".MyUrls").append("<div style='height: 30px;'> <input style='width: 240px' value='"+z+"' readonly><button class='CopyUrl' style='margin-left: 5px;height: 24px;width: 50px;padding: 0;border: none;background: white;border-radius:0;'>复制</button><button class='SaveUrl' style='margin-left: 5px;height: 24px;width: 50px;padding: 0;border: none;background: white;border-radius:0;'>下载</button></div>")
                }
            }
        })
        $("video").each(function () {
            if(!/^blob:/.test(this.currentSrc)){
                z = this.currentSrc
                if(! URLs.includes(z)&& this.currentSrc!=""){
                    URLs.push(z)
                    //console.log('type: video , url: ' + this.currentSrc)
                    $(".urlnone").remove()
                    $(".MyUrls .noneUrl:first").css("display","block").attr("class","isUrl").children("p").attr('title',z).text(z)
                    //$(".MyUrls").append("<div style='height: 30px;'> <input style='width: 240px' value='"+z+"' readonly><button class='CopyUrl' style='margin-left: 5px;height:24px;width: 50px;padding: 0;border: none;background: white;border-radius:0;'>复制</button><button class='SaveUrl' style='margin-left: 5px;height: 24px;width: 50px;padding: 0;border: none;background: white;border-radius:0;'>下载</button></div>")
                }
            }
            $(this).find("source").each(function () {
                if($(this).attr('src')!=''&&$(this).attr('src')!=undefined){
                if(!/^(http:|https:)/.test($(this).attr('src'))){
                    z = location.href.split("://")[0] +':'+ $(this).attr('src')
                }else{
                    z = $(this).attr('src')
                }
                if(! URLs.includes(z) && z != ""){
                    URLs.push(z)
                    //console.log('type: src , url: ' + z)
                    $(".urlnone").remove()
                    $(".MyUrls .noneUrl:first").css("display","block").attr("class","isUrl").children("p").attr('title',z).text(z)
                    //$(".MyUrls").append("<div style='height: 30px;'> <input style='width: 240px' value='"+z+"' readonly><button class='CopyUrl'  style='margin-left: 5px;height: 24px;width: 50px;padding: 0;border: none;background: white;border-radius:0;'>复制</button><button class='SaveUrl' style='margin-left: 5px;height: 24px;width: 50px;padding: 0;border: none;background: white;border-radius:0;'>下载</button></div>")
                }
                }
            })
        })
        //if(URLs.length>0 &&  $("#MyUrls").css("display")=="none"&& n==0){
        //    $("#MyUpDown").click()
        //    n = 1
        //}
    }
})();