您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
取得動畫的 m3u8 網址,並可使用 PotPlayer、MPV 播放,ffmpeg下載
// ==UserScript== // @name 動畫瘋下載器 // @namespace // @description 取得動畫的 m3u8 網址,並可使用 PotPlayer、MPV 播放,ffmpeg下載 // @version 1.7.4 // @author XPRAMT // @match https://ani.gamer.com.tw/animeVideo.php?sn=* // @connect ani.gamer.com.tw // @grant none // @namespace // ==/UserScript== (function () { 'use strict'; ///////////全域變數/////////// const mode = 0; //複製模式(0:複製完整指令|1:複製URL+名稱) const timeOut = 600; let m3u8_url = ''; let Name = ''; // 讀取已儲存的路徑,若無則使用預設 let downloadPath = localStorage.getItem('anig_download_path') || '%USERPROFILE%/Downloads'; // 從 URL 中獲取動畫的編號(AniVideoSn) let AniVideoSn = new URLSearchParams(window.location.search).get('sn'); //////////////////////////// // 注入樣式到頁面中 function injectStyles() { // 定義樣式 const css =` .anig-ct { margin:5px; margin-left:17px; } .anig-tb { display: inline-block; padding: 5px; background: #50b2d7; color: #FFF; margin-right: 5px; cursor: pointer; }`; const style = document.createElement('style'); // 創建 <style> 元素 style.textContent = css; // 設置樣式內容 document.head.appendChild(style); // 將 <style> 添加到 <head> } //初始化InfoContainer function initInfoContainer() { //資訊顯示框 infoDisplay.classList.add('anig-tb'); infoDisplay.title = '打開Greasy Fork镜像頁面' infoDisplay.addEventListener('click', function () { window.open('https://gf.qytechs.cn/zh-TW/scripts/451695-動畫瘋下載器', '_blank'); }) infoContainer.appendChild(infoDisplay); // 輸入框 const input = document.createElement('input'); input.type = 'text'; input.value = downloadPath; input.placeholder = '下載路徑'; input.style.cssText = ` margin-right: 5px; padding: 3px; background-color: #000; /* 黑底 */ color: #fff; /* 白字 */ border: None; display: none; /* 預設隱藏 */ `; // 儲存按鈕 const path_btn = document.createElement('buttonSave'); let def_text = '下載路徑' path_btn.textContent = def_text; // 初始文字 path_btn.title = '修改下載路徑' path_btn.classList.add('anig-tb'); let inputVisible = false; // 狀態旗標 path_btn.addEventListener('click', () => { if (!inputVisible) { // 顯示輸入框,按鈕顯示 "儲存" input.size = input.value.length || 10; input.style.display = 'inline'; path_btn.textContent = '儲存'; input.focus(); inputVisible = true; } else { // 儲存資料,隱藏輸入框,按鈕顯示 "修改路徑" downloadPath = input.value.trim() || downloadPath; localStorage.setItem('anig_download_path', downloadPath); input.style.display = 'none'; path_btn.textContent = def_text; inputVisible = false; } }); infoContainer.appendChild(path_btn); infoContainer.appendChild(input); } // 獲取設備 ID,這是請求播放列表所需的參數 async function getDeviceId() { // 清空容器 m3u8Container.innerHTML = ''; playContainer.innerHTML = ''; infoDisplay.textContent = '載入中...'; const req = 'https://ani.gamer.com.tw/ajax/getdeviceid.php'; // 請求設備 ID 的 URL const response = await fetch(req); // 發送請求 const data = await response.json(); // 解析 JSON 資料 let DeviceID = data.deviceid; // 提取設備 ID getPlaylist(DeviceID); // 繼續獲取播放列表 } // 獲取播放列表,並等待廣告結束 async function getPlaylist(DeviceID) { const req = `https://ani.gamer.com.tw/ajax/m3u8.php?sn=${AniVideoSn}&device=${DeviceID}`; // 構建請求 URL infoDisplay.textContent = '等待廣告...'; // 提示使用者等待廣告 let retries = 0; // 重試次數計數器 let playlist; const maxRetries = 20; // 最多嘗試次數,防止無限循環 // 循環請求播放列表,直到獲取到有效的播放地址或達到最大重試次數 while (retries < maxRetries) { const response = await fetch(req); // 發送請求 playlist = await response.json(); // 解析 JSON 資料 // 如果獲取到有效的播放地址(不包含廣告) if (playlist.src && playlist.src.includes('https')) { break; // 跳出循環 } await new Promise(resolve => setTimeout(resolve, 3000)); // 等待 3 秒再重試 retries++; // 增加重試次數 } // 判斷是否成功獲取播放列表 if (playlist.src && playlist.src.includes('https')) { await parsePlaylist(playlist); // 解析播放列表並生成按鈕 } else { infoDisplay.textContent = '獲取播放列表失敗'; // 提示使用者失敗 } } // 解析 m3u8 播放列表,並在頁面上生成按鈕供使用者複製鏈接或使用 PotPlayer 播放 async function parsePlaylist(playlist) { const req = playlist.src; // 獲取播放列表的 URL const response = await fetch(req); // 請求播放列表 const text = await response.text(); // 獲取回應的文字內容 const urlPrefix = req.replace(/playlist.+/, ''); // 提取 URL 前綴 const m3u8List = text.match(/=\d+x\d+\n.+/g); // 匹配所有清晰度的 m3u8 連結 // 生成動畫名稱,作為文件名使用 const fullwidthMap = { '<': '<','>': '>',':': ':','"': '"','/': '/', '\\': '\','|': '|','?': '?','!': '!','*': '*' }; Name = document.title.replace(" 線上看 - 巴哈姆特動畫瘋", ""); Name = Name.replace(/[\/\\<>:"*|?!]/g, char => { return fullwidthMap[char] || '_'; }); // 遍歷每個 m3u8 連結,生成對應的按鈕 for (const item of m3u8List) { let key = item.match(/=\d+x(\d+)/)[1]; // 提取清晰度(如 720) let url = item.match(/.*chunklist.+/)[0]; // 提取 m3u8 文件的相對路徑 url = urlPrefix + url; // 拼接成完整的 m3u8 URL // 創建複製鏈接的按鈕 const copyLink = document.createElement('a'); copyLink.classList.add('anig-tb'); copyLink.textContent = `${key}p`; copyLink.title = `切換解析度為${key}p`; // 被點擊時 copyLink.addEventListener('click', function () { m3u8_url = url; // 更新URL m3u8Container.querySelectorAll('a.anig-tb').forEach(el => { el.textContent = el.textContent.replace(/✅\s*$/, ''); }); copyLink.textContent = `${key}p✅`; }); m3u8Container.appendChild(copyLink); } // 主動點擊最後一個項目 const allBtns = m3u8Container.querySelectorAll('a.anig-tb'); if (allBtns.length > 0) { allBtns[allBtns.length - 1].click(); } infoDisplay.textContent = '使用說明'; //${Name} initPlayContainer() } //初始化playContainer function initPlayContainer() { // 創建使用 MPV 播放的按鈕 const MPVLink = document.createElement('a'); MPVLink.classList.add('anig-tb'); MPVLink.textContent = 'MPV'; MPVLink.title = `使用MPV播放: ${Name}`; MPVLink.addEventListener('click', function () { const MPVUrl = `${m3u8_url} --http-header-fields="origin: https://ani.gamer.com.tw" --force-media-title="${Name}"`; // 構建 MPV 協議的 URL navigator.clipboard.writeText(MPVUrl); window.open('mpv:', '_self'); // 開啟 PotPlayer }); playContainer.appendChild(MPVLink); // 創建使用 PotPlayer 播放的按鈕 const potplayerLink = document.createElement('a'); potplayerLink.classList.add('anig-tb'); potplayerLink.textContent = 'PotPlayer'; potplayerLink.title = `使用PotPlayer播放: ${Name}`; potplayerLink.addEventListener('click', function () { const potplayerUrl = `${m3u8_url} /sub="" /headers="origin: https://ani.gamer.com.tw" /current /title="${Name}"`; // 構建 PotPlayer 協議的 URL navigator.clipboard.writeText(potplayerUrl); window.open('potplayer:', '_self'); // 開啟 PotPlayer }); playContainer.appendChild(potplayerLink); // 創建使用 ffmpeg 下載的按鈕 const ffmpegLink = document.createElement('a'); ffmpegLink.classList.add('anig-tb'); ffmpegLink.textContent = 'ffmpeg'; ffmpegLink.title = `使用ffmpeg下載: ${Name}`; ffmpegLink.addEventListener('click', function () { let PSdownloadPath = downloadPath.replace(/%([^%]+)%/g, '$Env:$1'); const ffmpegDlUrl = `& ffmpeg -headers "Origin: https://ani.gamer.com.tw" -i "${m3u8_url}" -c copy "${PSdownloadPath}/${Name}.mkv";`; // 構建 PotPlayer 協議的 URL navigator.clipboard.writeText(ffmpegDlUrl); window.open('ffmpeg:', '_self'); // 開啟 ffmpeg }); playContainer.appendChild(ffmpegLink); // 創建複製 ffmpeg 指令的按鈕 const CopyffmpegLink = document.createElement('a'); CopyffmpegLink.classList.add('anig-tb'); let def_Copy_text = 'ffmpeg 🗍' CopyffmpegLink.textContent = def_Copy_text; CopyffmpegLink.title = `複製ffmpeg指令: ${Name}`; CopyffmpegLink.addEventListener('click', function () { let ffmpegUrl if (mode==0){ ffmpegUrl = `ffmpeg -headers "Origin: https://ani.gamer.com.tw" -i "${m3u8_url}" -c copy "${downloadPath}/${Name}.mkv" && exit`; // 構建 PotPlayer 協議的 URL }else{ ffmpegUrl = `${m3u8_url}@${Name}.mkv"`; // 構建 PotPlayer 協議的 URL } navigator.clipboard.writeText(ffmpegUrl); CopyffmpegLink.textContent = 'ffmpeg ✅'; setTimeout(() => { CopyffmpegLink.textContent = def_Copy_text; // 恢復提示文字 }, timeOut); }); playContainer.appendChild(CopyffmpegLink); } ////////////Main//////////// // 注入自定義樣式到頁面 injectStyles(); // 將自訂容器添加到頁面中的指定位置 const Downloader = document.createElement('div'); document.querySelector('.videoname').appendChild(Downloader); // 創建顯示提示信息的元素 const infoDisplay = document.createElement('div'); const infoContainer = document.createElement('div'); infoContainer.classList.add('anig-ct'); initInfoContainer(); Downloader.appendChild(infoContainer); // 創建容器,用於放置清晰度 const m3u8Container = document.createElement('div'); m3u8Container.classList.add('anig-ct'); Downloader.appendChild(m3u8Container); // 創建容器,用於放置播放下載按鈕 const playContainer = document.createElement('div'); playContainer.classList.add('anig-ct'); Downloader.appendChild(playContainer); // 為頁面中的集數連結添加點擊事件監聽 // 當使用者點擊不同的集數時,更新 AniVideoSn 並重新獲取播放列表 let lastAniVideoSn = AniVideoSn; // 保存上一次的 AniVideoSn document.querySelectorAll('a[data-ani-video-sn]').forEach(link => { link.addEventListener('click', function () { let it = setInterval(() => { AniVideoSn = new URLSearchParams(window.location.search).get('sn'); // 獲取當前的 AniVideoSn // 如果 URL 或 AniVideoSn 發生變化 if (AniVideoSn != lastAniVideoSn) { lastAniVideoSn = AniVideoSn; // 更新 AniVideoSn getDeviceId(); // 重新獲取設備 ID 並獲取播放列表 clearInterval(it); } }, 100); }); }); // 開始執行程式 getDeviceId(); // 獲取設備 ID 並開始流程 })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址