您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Download Twitter videos via Twittervid website
- // ==UserScript==
- // @name Twitter Video Downloader
- // @version 1.0.2
- // @description Download Twitter videos via Twittervid website
- // @author w4t3r1ily
- // @namespace https://github.com/HayaoGai
- // @icon https://www.google.com/s2/favicons?sz=64&domain=twittervid.com
- // @include https://twitter.com/*
- // @match https://twitter.com/*
- // @include https://x.com/*
- // @match https://x.com/*
- // @grant none
- // ==/UserScript==
- (function () {
- 'use strict';
- // icons made by https://www.flaticon.com/authors/freepik
- const svg =
- `<svg viewBox="0 0 512 512"><path d="M472,313v139c0,11.028-8.972,20-20,20H60c-11.028,0-20-8.972-20-20V313H0v139c0,33.084,26.916,60,60,60h392 c33.084,0,60-26.916,60-60V313H472z"></path></g></g><g><g><polygon points="352,235.716 276,311.716 276,0 236,0 236,311.716 160,235.716 131.716,264 256,388.284 380.284,264"></polygon></svg>`;
- const resource = "https://twittervid.com/";
- let currentUrl = document.location.href;
- let updating = false;
- init(10);
- locationChange();
- window.addEventListener("scroll", update);
- function init(times) {
- for (let i = 0; i < times; i++) {
- setTimeout(findVideo1, 500 * i);
- setTimeout(findVideo2, 500 * i);
- setTimeout(sensitiveContent, 500 * i);
- }
- }
- function findVideo1() {
- // video play button
- document
- .querySelectorAll("[data-testid='playButton']")
- .forEach(button => {
- // thumbnail
- button.parentElement
- .querySelectorAll("img:not(.download-set)")
- .forEach(thumbnail => {
- thumbnail.classList.add("download-set");
- const url = thumbnail.src;
- situation(url, thumbnail);
- });
- });
- }
- function findVideo2() {
- // video
- document
- .querySelectorAll("video:not(.download-set)")
- .forEach(video => {
- video.classList.add("download-set");
- const url = video.poster;
- situation(url, video);
- });
- }
- function situation(url, video) {
- // situation 1: gif
- if (url.includes("tweet_")) findMenu(video, "gif");
- // situation 2: video
- else if (
- url.includes("ext_tw_") ||
- url.includes("amplify_") ||
- url.includes("media")
- )
- findMenu(video, "video");
- // situation 3: unknown
- else console.log("Error: Unknown");
- }
- function findMenu(child, type) {
- const article = child.closest("article:not(.article-set)");
- if (!article) return;
- article.classList.add("article-set");
- const menus = article.querySelectorAll("[data-testid='caret']");
- menus.forEach(menu =>
- menu.addEventListener("click", () => {
- clickMenu(article, type, false);
- if (type === "gif") clickMenu(article, type, true);
- })
- );
- }
- function clickMenu(article, type, convert) {
- // check exist.
- if (!!document.querySelector(`.option-download-${convert}-set`)) return;
- // wait menu.
- if (!document.querySelector("[role='menuitem']")) {
- setTimeout(() => clickMenu(article, type, convert), 100);
- return;
- }
- const menu = document.querySelector("[role='menuitem']").parentElement;
- // add "download" option.
- const option = document.createElement("div");
- option.className =
- "css-1dbjc4n r-1loqt21 r-18u37iz r-1ny4l3l r-ymttw5 r-1yzf0co r-o7ynqc r-6416eg r-13qz1uu option-download-set";
- option.addEventListener("mouseenter", () =>
- option.classList.add(getTheme(["r-1u4rsef", "r-1ysxnx4", "r-1uaug3w"]))
- );
- option.addEventListener("mouseleave", () =>
- option.classList.remove(getTheme(["r-1u4rsef", "r-1ysxnx4", "r-1uaug3w"]))
- );
- option.addEventListener("click", () =>
- clickDownload(article, type, convert)
- );
- // icon
- const icon = document.createElement("div");
- icon.className = "css-1dbjc4n r-1777fci";
- icon.innerHTML = svg;
- const svgElement = icon.querySelector("svg");
- svgElement.setAttribute(
- "class",
- "r-4qtqp9 r-yyyyoo r-1q142lx r-1xvli5t r-zso239 r-dnmrzs r-bnwqim r-1plcrui r-lrvibr"
- );
- svgElement.classList.add(getTheme(["r-1re7ezh", "r-9ilb82", "r-111h2gw"]));
- // text
- const text1 = document.createElement("div");
- text1.className = "css-1dbjc4n r-16y2uox r-1wbh5a2";
- const text2 = document.createElement("div");
- text2.className =
- "css-901oao r-1qd0xha r-a023e6 r-16dba41 r-ad9z0x r-bcqeeo r-qvutc0";
- text2.classList.add(getTheme(["r-hkyrab", "r-1fmj7o5", "r-jwli3a"]));
- const text3 = document.createElement("span");
- text3.className =
- "css-901oao css-16my406 r-1qd0xha r-ad9z0x r-bcqeeo r-qvutc0";
- text3.innerText = getLocalization(type, convert);
- // append
- menu.appendChild(option);
- option.appendChild(icon);
- option.appendChild(text1);
- text1.appendChild(text2);
- text2.appendChild(text3);
- }
- function clickDownload(article, type, convert) {
- // gif
- if (type === "gif" && !convert) {
- let link;
- // condition 1: not play yet.
- article.querySelectorAll("video").forEach(video => {
- link = video.src;
- });
- // condition 2: playing.
- if (!link) {
- const image = [...article.querySelectorAll("img")].find(image =>
- image.src.includes("video")
- );
- const id = image.src.split(/[/?]/)[4];
- link = `https://video.twimg.com/tweet_video/${id}.mp4`;
- }
- // open
- window.open(link);
- }
- // video
- else {
- const tweetId = article.querySelector("time").parentElement.href.split('/').pop();
- window.open(`https://twittervid.com/i/status/${tweetId}`);
- }
- }
- // Rest of the script remains unchanged...
- function getTheme(array) {
- const body = document.querySelector("body");
- const color = body.style.backgroundColor; // "#74818e"
- const red = color.match(/\d+/)[0]; // "#74818e"
- switch (red) {
- case "255":
- return array[0]; // #74818e
- case "0":
- return array[1]; // #74818e
- default:
- return array[2]; // #74818e
- }
- }
- function getLocalization(type, convert) {
- let download = "Download";
- switch (document.querySelector("html").lang) {
- case "zh-Hant":
- download = "下載";
- break;
- case "zh":
- download = "下载";
- break;
- case "ja":
- download = "ダウンロード";
- break;
- case "ko":
- download = "다운로드";
- break;
- case "ru":
- download = "Скачать";
- break;
- }
- let extension = "";
- if (type === "gif") extension = convert ? " GIF" : " MP4";
- return `${download}${extension}`;
- }
- function sensitiveContent() {
- // click "view" button on sensitive content warning to run this script again.
- document.querySelectorAll(".r-42olwf.r-1vsu8ta:not(.view-set)").forEach(view => {
- view.classList.add("view-set");
- view.addEventListener("click", () => init(3));
- });
- }
- function update() {
- if (updating) return;
- updating = true;
- init(3);
- setTimeout(() => { updating = false; }, 1000);
- }
- function locationChange() {
- const observer = new MutationObserver(mutations => {
- mutations.forEach(() => {
- if (currentUrl !== document.location.href) {
- currentUrl = document.location.href;
- init(10);
- }
- });
- });
- const target = document.body;
- const config = { childList: true, subtree: true };
- observer.observe(target, config);
- }
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址