[网盘/磁力下载/在线播放/磁力云播] 夸克网盘解析下载/磁力播放公益站

浅草爱音 2026-10-29 17:55 1


本帖使用社区公益推广,符合推广要求。我申明并遵循社区要求的以下内容:

  • 我的项目是免费使用的,无收费(变相收费、赞助)部分: 是

  • 我的帖子已经打上 公益推广 标签: 是

  • 我的项目属于个人项目,与公司或商业机构无关: 是

  • 我的项目不存在QQ、TG等群组引流: 是

  • 我的项目不存在非运营必要的网站引流: 是

  • 我的项目不存在为他人推广、AFF: 是

  • 我的项目无关联的商业项目: 是

  • 我的站点存在登录,并已接入 LINUX DO Connect: 是

  • 我帖子内的项目介绍,AI生成、润色内容部分已截图发出: 是

  • 以上选择我承诺是永久有效的,接受社区和佬友监督: 是

    以下为项目介绍正文内容,AI生成、润色内容已使用截图方式发出



书接上回

[添加磁力转存功能]夸克网盘解析下载公益站 - 开发调优 / 开发调优, Lv1 - LINUX DO


本次更新优化了磁力转存下载链路,特别针对敏感易被风控的文件资源,增强了匹配机制,下载健壮性大大增强


注意: 磁力链路只能转存和下载夸克网盘本身可极速转存的资源(如图),我测试过很多不能极速下载的资源,即使是本机夸克客户端实际登录SVIP账号,也无法成功转存


磁力链路和分享链路消耗解析次数相同,只有成功生成下载链接后才扣除次数




添加网盘视频资源在线播放和磁力云播功能:


这是比较重要,实打实SVIP才可用的功能


网盘资源解析完成之后即可在线播放

磁力云播在磁力解析——转存完成之后,可以在线播放,在线播放不消耗次数


要使用在线播放功能,必须安装该篡改猴脚本


// ==UserScript==
// @name QuarkDL 客户端播放器
// @namespace quarkdl-client
// @version 2.1.6
// @description 磁力与网盘统一播放,auto 默认最高档 / 标清·高清·超清动态档位 / 流畅 / 原画,媒体仅走用户设备
// @match https://quarkdl.cc.cd/*
// @grant GM_xmlhttpRequest
// @connect quarkdl.cc.cd
// @connect drive.quark.cn
// @connect pds.quark.cn
// @run-at document-idle
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/hls.min.js
// ==/UserScript==

/* HLS engine: hls.js 1.5.20 (Apache-2.0), loaded via @require above. */

/* Shared by the userscript bundle and the loopback client. Never served by QuarkDL. */
(() => {
'use strict';
function mediaURL(value) {
if (typeof value !== 'string' || /[\s\x00-\x20\x7f\\]/u.test(value)) throw new Error('媒体地址无效');
const url = new URL(value);
if (url.protocol !== 'https:' || url.username || url.password || (url.port && url.port !== '443') ||
!['drive.quark.cn', 'pds.quark.cn'].some(h => url.hostname === h || url.hostname.endsWith('.' + h)))
throw new Error('媒体地址不在允许的范围内');
return url.href;
}

function createPlayer({resolve, Hls, loader, localURL, onClose = () => {}}) {
const host = document.createElement('div'); document.body.append(host);
const root = host.attachShadow({mode: 'closed'});
root.innerHTML = `<style>
:host{all:initial;position:fixed;inset:0;z-index:2147483647;background:#07130fee;display:grid;place-items:center;color:#e5f1e8;font:14px system-ui}
section{background:#14241c;border:1px solid #456351;border-radius:16px;width:min(1060px,96vw);max-height:96vh;overflow:auto}
header,nav,footer{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:14px 18px}header strong{flex:1;overflow:hidden;text-overflow:ellipsis}
video{display:block;width:100%;aspect-ratio:16/9;max-height:66vh;background:#000}
button,a{font:inherit;padding:9px 13px;border:1px solid #55745f;border-radius:7px;background:#233f2e;color:inherit;cursor:pointer;text-decoration:none}
button[aria-pressed=true]{background:#3a664a;border-color:#a2d4ad}button:disabled{opacity:.45;cursor:default}
p{padding:0 18px;line-height:1.7}small{color:#a6bdae}footer{overflow-x:auto;flex-wrap:nowrap}footer button{white-space:nowrap}[hidden]{display:none!important}
</style><section role="dialog" aria-modal="true" aria-label="QuarkDL 客户端播放器">
<header><strong>准备视频…</strong><button data-action="close" aria-label="关闭播放">关闭</button></header>
<video controls playsinline preload="metadata"></video><nav>
<button data-action="super" title="HLS 优先;无 HLS 超清档时使用 TV 视频流">超清</button><button data-action="low">流畅 HLS</button>
<button data-action="original">切换原画</button><button data-action="retry">重试</button>
<a target="_blank" rel="noopener noreferrer" hidden>打开原文件 ↗</a><small></small></nav>
<p role="status" aria-live="polite"></p><footer aria-label="视频文件"></footer></section>`;
const video = root.querySelector('video'), status = root.querySelector('p');
const buttons = Object.fromEntries([...root.querySelectorAll('button')].map(b => [b.dataset.action, b]));
const previousFocus = document.activeElement;
let stamp = 0, controller, hls, timer, closed = false, busy = false;
let mode = 'auto', quality = '', fid = '', resumeAt = 0, stage = 0;
let current = null, fallbackBusy = false;
function message(text) { status.textContent = text; }
function qualityLabel(value) {
return ({super: '超清', high: '高清', normal: '标清', low: '流畅', '2k': '2K', '4k': '4K', original: '原画'})[value] || value || '';
}
function qualityRank(value) {
return ({low: 1, normal: 2, high: 3, super: 4, '2k': 5, '4k': 6})[value] || 0;
}
function topQuality(data) {
let best = '';
for (const item of (data?.qualities || [])) {
const value = String(item?.resolution || '');
if (value && value !== 'low' && qualityRank(value) > qualityRank(best)) best = value;
}
const direct = String(data?.quality || '');
return best || (['normal', 'high', 'super', '2k', '4k'].includes(direct) ? direct : '');
}
function stop() {
++stamp; controller?.abort(); controller = null; clearTimeout(timer);
video.onerror = video.onwaiting = video.onplaying = video.onloadedmetadata = video.onpause = null;
if (hls) { hls.destroy(); hls = null; }
video.pause(); video.removeAttribute('src'); video.load();
current = null;
}
function position() { return Number.isFinite(video.currentTime) && video.currentTime > 0 ? video.currentTime : resumeAt; }
function controls(data) {
const available = new Set((data?.qualities || []).map(q => q.resolution));
const top = topQuality(data);
buttons.super.textContent = qualityLabel(top || 'super') || '高清';
buttons.super.disabled = busy || (mode === 'auto' && !!data && !top);
buttons.super.setAttribute('aria-pressed', String(mode === 'auto' && !!data && data.quality === top));
buttons.super.title = mode !== 'auto' ? '返回高清播放'
: top ? '按当前文件实际最高档位播放' : '当前文件暂无高清档位';
buttons.low.disabled = busy || (mode === 'auto' && !!data && !available.has('low'));
buttons.low.setAttribute('aria-pressed', String(mode === 'auto' && data?.quality === 'low'));
buttons.low.title = mode !== 'auto' ? '返回流畅播放'
: available.has('low') ? '流畅 HLS' : '当前文件暂无流畅 HLS 档位';
buttons.original.disabled = busy;
buttons.original.setAttribute('aria-pressed', String(mode !== 'auto'));
buttons.retry.disabled = busy;
}
const arm = token => { clearTimeout(timer); timer = setTimeout(() => fallback(token), 25000); };
function delay(ms, signal) {
return new Promise((resolve, reject) => {
const abort = () => { clearTimeout(timer); signal.removeEventListener('abort', abort); reject(new DOMException('Aborted', 'AbortError')); };
const timer = setTimeout(() => { signal.removeEventListener('abort', abort); resolve(); }, ms);
signal.addEventListener('abort', abort, {once: true});
if (signal.aborted) abort();
});
}
async function getDescriptor(selection, signal) {
for (let attempt = 0; ; ++attempt) {
try { return await resolve(selection, signal); }
catch (error) {
if (error.status !== 503 || !['busy', 'play_preparing', 'play_account_unavailable'].includes(error.code) || attempt >= 3) throw error;
message('视频正在准备或账号忙碌,稍后自动重试…');
await delay(2000 * (2 ** attempt), signal);
}
}
}
async function fallback(token) {
if (closed || token !== stamp || busy || fallbackBusy) return;
fallbackBusy = true; resumeAt = position();
// Each transition is bounded, and a failed URL is never blindly retried from cache.
try {
if (mode === 'raw' || (mode === 'original' && current?.source === 'original')) {
message('原始字节流无法播放。请重试或用本地播放器打开原文件。'); clearTimeout(timer); return;
}
if (mode === 'original') { mode = 'raw'; await load(true); return; }
stage += 1;
if (stage === 2 && quality !== 'low') quality = 'low';
else if (stage >= 3 || (stage === 2 && quality === 'low')) mode = 'original';
await load(stage === 1);
} finally { fallbackBusy = false; }
}
async function load(refresh = false) {
stop(); const token = stamp; busy = true; controls();
message(mode === 'auto' ? '正在获取视频流…' : '正在获取原画视频流…');
const active = new AbortController(); controller = active;
const timeout = setTimeout(() => active.abort(), 120000);
try {
const data = await getDescriptor({source: mode, quality: mode === 'auto' ? quality : '', fid, refresh}, active.signal);
if (closed || token !== stamp) return;
if (!['direct-hls', 'client-hls', 'streaming', 'original'].includes(data.source)) throw new Error('播放源无效');
const cdn = mediaURL(data.url);
current = data; busy = false; controls(data);
if (data.files) {
fid = data.fid;
const files = root.querySelector('footer'); files.replaceChildren();
for (const file of data.files) {
const button = document.createElement('button'); button.textContent = file.name || file.fid;
button.setAttribute('aria-pressed', String(file.fid === fid));
button.addEventListener('click', () => { fid = file.fid; resumeAt = 0; mode = 'auto'; quality = ''; stage = 0; load(); });
files.append(button);
}
}
root.querySelector('strong').textContent = data.files?.find(f => f.fid === fid)?.name || data.title || '在线播放';
const flow = data.mode === 'original'
? (data.source === 'original' ? '原画 · 原始字节流' : '原画 · TV 视频流')
: data.source === 'original' ? '原始字节流'
: data.source === 'streaming' ? 'TV 视频流' : 'HLS';
root.querySelector('small').textContent = [flow, qualityLabel(data.quality || data.resolution),
data.width && data.height ? data.width + ' × ' + data.height : ''].filter(Boolean).join(' · ');
const download = root.querySelector('a'); download.hidden = data.source !== 'original';
download.removeAttribute('href'); if (!download.hidden) download.href = cdn;
video.onerror = () => fallback(token); video.onwaiting = () => arm(token);
video.onpause = () => clearTimeout(timer);
video.onplaying = () => { clearTimeout(timer); message('正在播放 · 媒体由你的设备加载'); };
video.onloadedmetadata = () => {
if (resumeAt > 0) {
try { video.currentTime = Number.isFinite(video.duration) ? Math.min(resumeAt, Math.max(0, video.duration - .1)) : resumeAt; } catch (_) {}
resumeAt = 0;
}
};
if (data.source.endsWith('hls')) {
if (Hls?.isSupported()) {
const Loader = loader ? loader(data) : null;
hls = new Hls({enableWorker: false, maxBufferLength: 30, backBufferLength: 30, ...(Loader ? {loader: Loader} : {})});
hls.on(Hls.Events.ERROR, (_, event) => { if (event.fatal) fallback(token); });
hls.loadSource(localURL ? localURL(data.url) : cdn); hls.attachMedia(video);
} else if (localURL && video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = localURL(data.url);
} else if (data.source === 'direct-hls' && video.canPlayType('application/vnd.apple.mpegurl')) video.src = cdn;
else throw new Error('当前客户端不支持 HLS,请切换原画');
} else video.src = cdn;
arm(token);
video.play().catch(error => {
if (closed || token !== stamp) return;
if (error.name === 'NotAllowedError') { clearTimeout(timer); message('已准备好,点击视频开始播放'); }
else if (error.name !== 'AbortError') fallback(token);
});
} catch (error) {
if (closed || token !== stamp) return;
busy = false; controls();
message(error.name === 'AbortError' ? '准备超时,请重试' : error.message);
// API failures follow the same bounded downgrade chain as media failures.
if (mode !== 'raw' && ![401, 403, 410, 429].includes(error.status) && error.name !== 'AbortError') setTimeout(() => fallback(token), 300);
} finally { clearTimeout(timeout); }
}
async function close() {
if (closed) return;
closed = true; stop(); host.remove(); document.removeEventListener('keydown', keydown);
await onClose(); previousFocus?.focus();
}
function keydown(event) { if (event.key === 'Escape') { event.preventDefault(); close(); } }
document.addEventListener('keydown', keydown);
buttons.close.onclick = close;
buttons.super.onclick = () => { resumeAt = position(); mode = 'auto'; quality = 'super'; stage = 0; load(); };
buttons.low.onclick = () => { resumeAt = position(); mode = 'auto'; quality = 'low'; stage = 0; load(); };
buttons.original.onclick = () => { resumeAt = position(); mode = 'original'; stage = 0; load(); };
buttons.retry.onclick = () => { resumeAt = position(); stage = 0; load(true); };
buttons.close.focus(); load();
return {close};
}
globalThis.QuarkClient = Object.freeze({mediaURL, createPlayer});
})();

/* Adapter appended to vendor/hls.min.js and player.js by build.py. */
(() => {
'use strict';
const {mediaURL, createPlayer} = globalThis.QuarkClient;
const origin = location.origin;
const version = 2;
let active = null, opening = 0;
function api(path, payload, signal) {
// Keep capability responses in the extension transport, outside page fetch hooks.
return new Promise((resolve, reject) => {
let handle, settled = false;
const finish = (error, data) => {
if (settled) return;
settled = true; clearTimeout(timer); signal?.removeEventListener('abort', abort);
error ? reject(error) : resolve(data);
};
const abort = () => {
if (settled) return;
finish(new DOMException('Aborted', 'AbortError')); handle?.abort();
};
const timer = setTimeout(abort, 120000);
if (signal?.aborted) { abort(); return; }
signal?.addEventListener('abort', abort, {once: true});
handle = GM_xmlhttpRequest({method: 'POST', url: origin + '/api/magnet/playback/' + path,
anonymous: true, redirect: 'error', nocache: true,
headers: {'Content-Type': 'application/json'}, data: JSON.stringify(payload), responseType: 'json',
onload: response => {
let data = response.response;
if (!data || typeof data !== 'object') {
try { data = JSON.parse(response.responseText); } catch (_) { finish(new Error('播放服务返回异常')); return; }
}
if (response.status !== 200 || !data.ok) finish(Object.assign(new Error(data.message || '获取播放地址失败'), {status: response.status, code: data.code}));
else finish(null, data);
}, onerror: () => finish(new Error('播放服务连接失败')), onabort: abort});
});
}
function gmLoader(data) {
// Credential stays in the userscript closure. Never put it in DOM or a Cookie jar.
const cookie = data.credentials?.cookie || '';
return class {
constructor() {
this.stats = {aborted: false, loaded: 0, total: 0, retry: 0, chunkCount: 0, bwEstimate: 0,
loading: {start: 0, first: 0, end: 0}, parsing: {start: 0, end: 0}, buffering: {start: 0, first: 0, end: 0}};
}
load(context, config, callbacks) {
this.context = context; const stats = this.stats; stats.loading.start = performance.now();
let url; try { url = mediaURL(context.url); } catch (_) { callbacks.onError({code: 0, text: '媒体地址无效'}, context, null, stats); return; }
const headers = {};
if (context.rangeEnd !== undefined) headers.Range = 'bytes=' + (context.rangeStart || 0) + '-' + (context.rangeEnd - 1);
const fail = (code, text) => {
clearTimeout(this.timer);
if (!stats.aborted) callbacks.onError({code, text}, context, null, stats);
};
this.timer = setTimeout(() => {
if (stats.aborted) return;
stats.aborted = true; this.request?.abort(); callbacks.onTimeout(stats, context, null);
}, Math.min(config.timeout || 30000, 60000));
this.request = GM_xmlhttpRequest({method: 'GET', url, anonymous: true, redirect: 'error',
...(cookie ? {cookie} : {}), headers, timeout: Math.min(config.timeout || 30000, 60000),
...(context.responseType === 'arraybuffer' ? {responseType: 'arraybuffer'} : {}),
onload: response => {
clearTimeout(this.timer);
if (stats.aborted) return;
try { mediaURL(response.finalUrl || url); } catch (_) { fail(0, '媒体跳转地址无效'); return; }
if (![200, 206].includes(response.status)) { fail(response.status, '媒体请求失败'); return; }
const body = context.responseType === 'arraybuffer' ? response.response : response.responseText;
stats.loading.first = stats.loading.end = performance.now(); stats.loaded = stats.total = body.byteLength ?? body.length;
callbacks.onSuccess({url: response.finalUrl || url, data: body}, stats, context, null);
}, onerror: () => fail(0, '媒体网络请求失败'),
ontimeout: () => { clearTimeout(this.timer); if (!stats.aborted) callbacks.onTimeout(stats, context, null); }
});
}
abort() { this.stats.aborted = true; clearTimeout(this.timer); this.request?.abort(); }
destroy() { this.abort(); this.request = null; this.context = null; }
};
}
window.addEventListener('message', async event => {
// Tampermonkey wraps `window`; MessageEvent.source is the native DOM Window.
// document.defaultView has that identity without exposing an unsafeWindow grant.
if (event.source !== document.defaultView || event.origin !== origin || event.data?.version !== version) return;
if (event.data.type === 'quarkdl:client-probe') {
window.postMessage({type: 'quarkdl:client-ready', version}, origin); return;
}
if (event.data.type !== 'quarkdl:client-open' || typeof event.data.ticket !== 'string') return;
const token = ++opening;
try {
await active?.close(); active = null;
const data = await api('exchange', {client: 'userscript', token: event.data.ticket});
if (token !== opening) { void api('revoke', {client: 'userscript', token: data.session}).catch(() => {}); return; }
active = createPlayer({Hls: globalThis.Hls, loader: gmLoader,
resolve: (selection, signal) => api('resolve', {client: 'userscript', token: data.session, ...selection}, signal),
onClose: () => { void api('revoke', {client: 'userscript', token: data.session}).catch(() => {}); }});
window.postMessage({type: 'quarkdl:client-state', version, requestId: event.data.requestId, state: 'opened'}, origin);
} catch (error) {
if (token === opening) window.postMessage({type: 'quarkdl:client-state', version,
requestId: event.data.requestId, state: 'error', message: error.message}, origin);
}
});
window.postMessage({type: 'quarkdl:client-ready', version}, origin);
window.addEventListener('pagehide', () => active?.close());
})();


本站播放器采用浏览器直连夸克 CDN,服务器只负责解析和返回播放地址,不中转媒体流量。 播放器会按资源实际可用的清晰度自动选择最高档,并优先使用 HLS;同分辨率下 HLS 优先,没有对应 HLS 时使用 TV MP4。



清晰度链路大致是:









































档位 实际取流 说明
自动档 HLS 或 TV MP4 默认最高可用档,可能是 client-hls、direct-hls 或 streaming
流畅 low HLS 约 480×270,码率最低
标清 normal MP4 约 856×480,部分资源才有
高清 high MP4 约 1280×720,部分资源才有
超清 super HLS 或 MP4 约 1440×810 或 1920×1080,按资源实际返回
原画 TV 最高 MP4 → super HLS → 原始字节流 优先走 TV 视频流,没有再回原始文件


磁力云播效果:


网盘视频资在源线播放效果


支持大部分NSFW磁力内容,针对风险资源的风控做了专门优化

最新回复 (8)
  • giantm 10-29 17:57
    1楼

    佬,最后一张图是认真的吗? ^-^

  • duduoo 10-29 17:57
    2楼

    ^-^ 佬,你这功能更新了,20次可不够用了~!

  • 五羊雪糕 10-29 18:11
    3楼

    试了nsfw,非常好用 ^-^

  • chen12138 10-29 18:12
    4楼

    可惜青春版不能用

  • Ryayn 10-29 18:13
    5楼

    佬 这个开源吗 手机一直找不到合适的下载策略,在有vip但不使用夸克的app情况下。

  • 不可回收垃圾 10-29 18:13
    6楼

    今天才周四

    佬你这是在引诱我破戒 ^-^

  • 加了椰子汁的冰 10-29 18:19
    7楼

    来支持咯!之前用过一两次,前几天是不是接口挂了还以为是不是佬友的号池被封了 ^-^

  • 格里菲 10-29 18:41
    8楼

    如果肉身不在国外,真心建议关闭在线NSFW的支持,100%的人身安全风险。

    各个搞这种网站的都有利益牵扯,互相举报、ddos是常态,和机场一个德行。

* 帖子来源Linux.do
返回