Greasy Fork is available in English.
视频下载 bilibili acfun youtube 西瓜 快手 抖音
当前为
// ==UserScript==
// @name you-get
// @description 视频下载 bilibili acfun youtube 西瓜 快手 抖音
// @namespace http://tampermonkey.net/
// @version 0.0.1
// @description try to take over the world!
// @author You
// @match https://www.ixigua.com/*
// @match https://www.bilibili.com/video/*
// @match https://www.douyin.com/*
// @match https://www.kuaishou.com/*
// @match https://www.acfun.cn/v/*
// @match https://www.youtube.com/watch/*
// @license MIT
// @grant none
// ==/UserScript==
(function () {
"use strict";
// Your code here...
const CONFIG = "tampermonkey_config";
const download = async (blob, fileName) => {
let link = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.download = `${fileName}`;
a.href = link;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(link);
};
const getConfig = (key) => {
let item = localStorage.getItem(key);
if (item) {
try {
item = JSON.parse(item);
} catch (error) {
item = null;
console.log(error);
}
}
return item;
};
const fetchFile = async (url) => {
const res = await fetch(url);
const reader = res.body.getReader();
const contentLength = +res.headers.get("Content-Length");
if (!contentLength) {
const data = await res.arrayBuffer();
return new Uint8Array(data);
}
let receivedLength = 0;
let chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
chunks.push(value);
receivedLength += value.length;
console.log(
`fileSize: ${contentLength} %c downloaded ${receivedLength}`,
"background: #222; color: #bada55"
);
}
// const config = getConfig(CONFIG);
// if (config?.merge === false) {
return new Blob(chunks);
// }
// let chunksAll = new Uint8Array(receivedLength);
// let position = 0;
// for (let chunk of chunks) {
// chunksAll.set(chunk, position);
// position += chunk.length;
// }
// return chunksAll;
};
const getUrlsByM3u8 = async (url) => {
const res = await fetch(url);
const data = await res.text();
return data.split("\n").filter((i) => !i.startsWith("#"));
};
const getXiGuaVideoInfo = async () => {
const res = await fetch(window.location.href);
const str = await res.text();
const data = JSON.parse(
str
.match(/window?._SSR_HYDRATED_DATA=([\d\D]+?)<\/script>/)[1]
.replaceAll("undefined", "null")
);
const videoList = Object.values(
data?.anyVideo?.gidInformation?.packerData?.video?.videoResource?.normal
?.video_list ?? {}
).sort((a, b) => b?.vheight - a?.vheight);
const video = videoList?.[0];
return [
{
url: atob(video.main_url, "base64"),
fileName: `download.${video.vtype || "mp4"}`,
},
];
};
const getBilibiliVideoInfo = async () => {
const res = await fetch(window.location.href);
const str = await res.text();
const data = JSON.parse(
str.match(/window.__playinfo__=([\d\D]+?)<\/script>/)[1]
);
const dash = data.data.dash;
const video = dash.video.sort((a, b) => b?.width - a?.width)?.[0];
const audio = dash.audio[0];
return [
{
url: video.baseUrl,
fileName: `download.${video?.mimeType?.split("/")?.[1] || "mp4"}`,
},
{
url: audio.baseUrl,
fileName: `download.${video?.mimeType?.split("/")?.[1] || "mp4"}`,
},
];
};
const getDouyinVideoInfo = () => {
const urls = [...document.querySelectorAll("video source")].map(
(i) => i.src
);
return [
{
url: urls[0],
fileName: `download.mp4`,
},
];
};
const getKuaishouVideoInfo = () => {
const urls = [...document.querySelectorAll("video")].map((i) => i.src);
return [
{
url: urls[0],
fileName: `download.mp4`,
},
];
};
const getYoutubeVideoInfo = async () => {
const res = await fetch(window.location.href);
const str = await res.text();
var parser = new DOMParser();
var doc = parser.parseFromString(str, "text/html");
const data = JSON.parse(
doc.body.innerHTML.match(/("formats":)([\d\D]+?}]+?)/)[2]
);
const video = data.sort((a, b) => b?.width - a?.width)?.[0];
return [
{
url: video.url,
fileName: `download.mp4`,
},
];
};
const getAcfunVideoInfo = async () => {
const res = await fetch(window.location.href);
const str = await res.text();
const m3u8FileUrl = JSON.parse(window.pageInfo.currentVideoInfo.ksPlayJson)
.adaptationSet[0].representation[0].url;
const baseUrl =
m3u8FileUrl.substring(0, m3u8FileUrl.indexOf("acfun_video")) +
"acfun_video/";
const urls = (await getUrlsByM3u8(m3u8FileUrl)).map(
(i) => `${baseUrl}${i}`
);
return urls.map((url) => ({
url,
fileName: `download.mp4`,
merge: true,
}));
};
const platform = {
ixigua: getXiGuaVideoInfo,
bilibili: getBilibiliVideoInfo,
douyin: getDouyinVideoInfo,
kuaishou: getKuaishouVideoInfo,
youtube: getYoutubeVideoInfo,
acfun: getAcfunVideoInfo,
};
const youget = async function () {
const handler = Object.entries(platform).find(([key, fn]) =>
window.location.host.toLocaleLowerCase().includes(key)
)?.[1];
if (handler) {
const urls = await handler();
const files = [];
while (urls?.length) {
const i = urls.shift();
if (i.merge) {
const file = await fetchFile(i.url);
files.push(file);
if (!urls.length) {
download(new Blob(files), i.fileName);
}
} else {
const file = await fetchFile(i.url);
await download(file, i.fileName);
}
}
}
};
youget.toString = () => {
youget();
return 1;
};
window.you = 1;
window.get = youget;
window.youget = youget;
})();