Greasy Fork is available in English.
下载快手视频
当前为
// ==UserScript==
// @name 快手视频高清下载
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 下载快手视频
// @author xelicev
// @run-at document-start
// @license MIT License
// @grant GM_download
// @include *://*kuaishou.com
// @include *://*.kuaishou.com/*
// @inject-into page
// @require http://greasyfork.icu/scripts/440006-mono/code/mono.js?version=1021395
// ==/UserScript==
const metaCache = {};
//hook fetch
const fetchListKeys = ['brilliantData', 'visionSearchPhoto', 'brilliantTypeData', 'visionProfilePhotoList']
const originFetch = fetch
unsafeWindow.fetch = async (url, request) => {
const response = await originFetch(url, request)
if (url && url.indexOf('graphql') > -1) {
try {
const text = await response.text()
response.text = () => { return new Promise((resolve) => { resolve(text) }) }
const res = JSON.parse(text)
for (i in fetchListKeys) {
const key = fetchListKeys[i];
if (res?.data[key] && res.data[key].feeds && res.data[key].feeds.length > 0) {
const feeds = res.data[key].feeds;
for (var i = 0; i < feeds.length; i++) {
var itemData = feeds[i].photo;
itemData.author = feeds[i].author
metaCache[itemData.id] = itemData
}
// console.log(feeds)
}
}
} catch (e) {
console.error(e)
}
}
return response
}
//hook xhr
const xhrListKeys = ['hotPhotoInfos', 'inspiredAds']
var origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function() {
this.addEventListener('load', function() {
if (this.responseType && this.responseType !== "text") return;
const res = JSON.parse(this.responseText)
for (i in xhrListKeys) {
const key = xhrListKeys[i];
if (res?.data && typeof res.data === 'object' &&
key in res.data && res.data[key].length > 0) {
const feeds = res.data[key];
for (var i = 0; i < feeds.length; i++) {
const url = new URL(feeds[i].coverThumbnailUrls[0].url);
const id = url.searchParams.get('clientCacheKey')?.replace('.jpg', '');
// console.log(id, feeds[i])
feeds[i].id = id;
metaCache[id] = feeds[i];
}
// console.log(feeds)
}
}
});
// console.log(arguments)
origOpen.apply(this, arguments);
};
(function () {
var mono = window['mono-descargar'];
var $ = mono.jQuery;
var md5 = mono.md5;
var onRequest = mono.onRequest;
var filename = mono.filename;
var errCode = mono.FAIL_TO_DEFAULT;
var idKey = 'mono-dsg-id';
var getItemByMeta = (meta, selector='', selClass='') => {
const id = `ks-${md5(meta.id)}`
if ($(`[${idKey}=${id}]`).length > 0) return null;
const url = meta.photoUrl;
meta.title = meta.caption;
meta.cover = meta.coverUrl;
meta.name = filename(meta.title || document?.title);
let $el = null;
if (selector) $el = $(selector)
if ($el.length > 0 && selClass) {
const ps = $el.parentsUntil(selClass);
if (ps.length > 0) $el = $(ps[ps.length - 1])
}
if ($el.length <= 0) return null;
const container = $el[0];
return { id, url, container, meta }
};
var detail = async () => {
const url = new URL(window.location.href);
const video_id = url.pathname.replace("/short-video/", '');
if (video_id in metaCache) {
const item = getItemByMeta(metaCache[video_id], '.kwai-player-container-video')
return item ? [item] : [];
}
return [];
}
var list = async () => {
const items = []
for (const [id, meta] of Object.entries(metaCache)) {
const selector = `img[src*='clientCacheKey=${id}']`
const item = getItemByMeta(meta, selector, '.video-card')
if (item) items.push(item);
}
return items
}
var cc = async () => {
const items = [];
for (const [id, meta] of Object.entries(metaCache)) {
const selector = `.cc-player-poster[style*='clientCacheKey=${id}']`;
const item = getItemByMeta(meta, selector, '.common-video-item')
if (!item) continue;
item.url = meta.mainMvUrls[0].url;
item.meta.cover = meta.coverThumbnailUrls[0].url;
item.meta.title = `快手-${meta.firstIndustryName}-${meta.nickName}`;
if (item) items.push(item);
}
return items
}
var parser = async function () {
const url = new URL(window.location.href);
const paths = url.pathname.split('/');
const path = paths[1];
if (path === "short-video") {
return await detail();
} else if (!path || ["search", "brilliant", "profile"].includes(path)) {
return await list();
} else if (url.host === 'cc.e.kuaishou.com' &&
["/inspiration/ads", "/inspiration/hot"].includes(url.pathname)) {
return await cc();
} else {
throw errCode;
}
}
if (mono?.init) mono.init({ parser });
})()