// ==UserScript== // @name Twitter/X 视频下载助手 // @namespace http://tampermonkey.net/ // @version 2.6.0 // @description Twitter 视频下载 // @author Gemini Modified // @license MIT // @match https://x.com/* // @match https://twitter.com/* // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js // @grant GM_download // @downloadURL https://update.greasyfork.icu/scripts/573462/TwitterX%20%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%8A%A9%E6%89%8B.user.js // @updateURL https://update.greasyfork.icu/scripts/573462/TwitterX%20%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%8A%A9%E6%89%8B.meta.js // ==/UserScript== (function() { "use strict"; $("head").append(` `); $("body").append(`
`); function resetSniffer() { $("#ListContent").empty(); console.log("Twitter下载助手:已自动重置嗅探环境"); } let lastUrl = location.href; new MutationObserver(() => { const currentUrl = location.href; if (currentUrl !== lastUrl) { lastUrl = currentUrl; resetSniffer(); } }).observe(document, { subtree: true, childList: true }); $("#Orb").click(() => $("#VideoList").fadeToggle(200)); $("#RefreshList").click((e) => { e.stopPropagation(); resetSniffer(); }); (function(open) { XMLHttpRequest.prototype.open = function() { this.addEventListener("load", function() { try { if (this.responseText && (this.responseURL.includes("/TweetDetail") || this.responseURL.includes("/UserBy"))) { findTwitterVideos(JSON.parse(this.responseText)); } } catch(e) {} }); open.apply(this, arguments); }; })(XMLHttpRequest.prototype.open); function findTwitterVideos(obj) { if (!obj || typeof obj !== 'object') return; if (obj.variants && Array.isArray(obj.variants)) { const mp4s = obj.variants.filter(v => v.content_type === 'video/mp4'); if (mp4s.length > 0) { mp4s.sort((a, b) => (b.bitrate || 0) - (a.bitrate || 0)); addToList(mp4s[0].url); } } for (let key in obj) findTwitterVideos(obj[key]); } function addToList(url) { if ($(`input[value='${url}']`).length > 0) return; $("#ListContent").append(`
`); } $(document).on("click", ".SaveBtn", function() { const url = $(this).prev(".downUrl").val(); GM_download(url, "twitter_video_" + Date.now() + ".mp4"); }); })();