// ==UserScript==
// @name Arca Live Image and Video Downloader
// @name:zh-TW Arca Live 圖片與影片下載器
// @name:zh-CN Arca Live 图片和视频下载器
// @namespace http://tampermonkey.net/
// @version 2.5
// @description Supports downloading images, GIFs, MP4s, and WEBMs from Arca Live posts (using GM_download to bypass CORS), with automatic filename formatting as "Board_PostID_0001~n". Offers both fast download and sequential download modes.
// @description:zh-TW 支援下載 Arca Live 貼文中的圖片、GIF、MP4、WEBM(使用 GM_download 繞過 CORS)並自動命名為「板塊_編號_0001~n」格式,快速下載、逐一下載兩種模式。
// @description:zh-CN 支援下载 Arca Live 贴文中的图片、GIF、MP4、WEBM(使用 GM_download 绕过 CORS)并自动命名为「板块_编号_0001~n」格式,快速下载、逐一下载两种模式。
// @author Hzbrrbmin + ChatGPT
// @match https://arca.live/*
// @grant GM_download
// @license MIT
// @downloadURL https://update.greasyfork.icu/scripts/545416/Arca%20Live%20Image%20and%20Video%20Downloader.user.js
// @updateURL https://update.greasyfork.icu/scripts/545416/Arca%20Live%20Image%20and%20Video%20Downloader.meta.js
// ==/UserScript==
(function () {
'use strict';
// 延遲函式,方便等待非同步流程
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
// 等待收藏按鈕出現,作為插入下載按鈕的參考點,最多等待 10 秒(50 次 * 200ms)
const waitForScrapButton = async () => {
for (let i = 0; i < 50; i++) {
const scrapBtn = document.querySelector('form#scrapForm > button.scrap-btn');
if (scrapBtn) return scrapBtn;
await sleep(200);
}
return null;
};
// 從網址中解析板塊名稱與貼文 ID,例如 /b/umamusume/141070493
const parseBoardInfo = () => {
const match = location.pathname.match(/^\/b\/([^/]+)\/(\d+)/);
if (!match) return { board: 'unknown', postId: 'unknown' };
return { board: match[1], postId: match[2] };
};
// 收集貼文中所有可下載的媒體網址(圖片與影片)
const collectMediaUrls = () => {
const urls = new Set();
//
標籤圖片(優先取 data-src)
document.querySelectorAll('.article-body img').forEach(img => {
const src = img.getAttribute('data-src') || img.src;
if (src) urls.add(src);
});
//