您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Get Minyami download commands for supported sites
当前为
// ==UserScript== // @name Minyami // @description Get Minyami download commands for supported sites // @namespace Violentmonkey Scripts // @match *://*/* // @grant GM_notification // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setClipboard // @grant GM_setValue // @grant GM_getValue // @version 0.0.1.20250525142136 // ==/UserScript== (async () => { let stream = {}; let command = ""; let completed = false; console.log(GM_getValue("server","")) if (! (GM_getValue("server", "") === "none" || /^https?:\/\//g.test(GM_getValue("server", "")))) { await GM_setValue("server", prompt("Enter your download Server URL (to disable this feature input: none)", "")) }; const server = GM_getValue("server", ""); if (sessionStorage.getItem("streams") === null) { sessionStorage.setItem("streams", "[]"); } function createCommand(stream) { return `minyami -d "${stream.url}" --output "${stream.title}.ts" --key "${stream.key}" --live --threads 50` } function sendToServer(stream) { if (server !== "none") { fetch(server, { method: "POST", body: createCommand(stream), headers: { "Content-type": "text/plain; charset=UTF-8" } }); } } function getDate(offset) { const date = new Date(); // Subtract the offset in hours date.setHours(date.getHours() - offset); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); // Ensures two-digit format const day = String(date.getDate()).padStart(2, '0'); // Ensures two-digit format return `${year}-${month}-${day}`; } function registerDownloadAllMenu() { let streams = JSON.parse(sessionStorage.getItem("streams")); if (streams.length > 1) { let commands = "" streams.forEach((stream, i) => { commands += createCommand(stream) + (i < streams.length - 1 ? "\n" : ""); }); GM_registerMenuCommand("📋🔄️ Copy and clear all Minyami commands", () => { GM_setClipboard(commands); GM_notification("All Minyami commands copied!", "Minyami"); sessionStorage.setItem("streams", "[]"); GM_unregisterMenuCommand(`📋 ${stream.title}`); GM_unregisterMenuCommand("📋🔄️ Copy and clear all Minyami commands"); }, { title: `${streams.length} Minyami commands` }); } } registerDownloadAllMenu(); const notify = function(object) { if (completed === false) { switch (object.type) { case "chunklist": let timestamp = document.querySelectorAll("div#root div#video-page-wrapper span.MuiTypography-root.MuiTypography-caption")[0].innerHTML if (/^20[0-9]{2}\/[0-9]{2}\/[0-9]{2}$/g.test(timestamp)) { stream.title = timestamp.replaceAll("\/", "-") + " - " + object.title; } else if (/^[0-9]日前/g.test(timestamp)) { stream.title = getDate((timestamp.replace("日前",""))*24) + " - " + object.title; } else if (/^[1-2].*時間前/g.test(timestamp)) { stream.title = getDate(timestamp.replace("時間前","")) + " - " + object.title; } else { stream.title = object.title; }; stream.url = object.url; stream.m3u8 = new URL(object.url).pathname.split('/').pop(); break; case "key": stream.key = object.key; completed = true; break; }; if (completed === true) { let streams = JSON.parse(sessionStorage.getItem("streams")); streams = streams.filter(obj => obj.m3u8 !== stream.m3u8); streams.push(stream); sessionStorage.setItem("streams", JSON.stringify(streams)); registerDownloadAllMenu(); GM_registerMenuCommand(`📋 ${stream.title}`, () => { GM_setClipboard(createCommand(stream)); GM_notification("Minyami command copied!", "Minyami"); }); sendToServer(stream); }; }; }; // ========================================== unmodified Code below (from https://raw.githubusercontent.com/Last-Order/Minyami-chrome-extension/refs/heads/master/assets/scripts/inject_core.js) ========================================== window.addEventListener("unload", notify({ type: "page_url", url: window.location.href }), false); const escapeFilename = (filename) => { return filename.replace(/[\/\*\\\:|\?<>"!]/gi, "_"); }; let key = ""; if (window.fetch) { const _fetch = fetch; fetch = (url, ...fargs) => { return new Promise((resolve, reject) => { _fetch(url, ...fargs) .then(async (res) => { resolve(res); return res.clone(); }) .then(async (r) => { if (r.url.match(/\.m3u8(\?|$)/)) { const responseText = await r.text(); let title = escapeFilename(document.title); let streamName; switch (location.host) { case "abema.tv": { if (document.querySelector(".c-tv-SwitchAngleButton-current-angle-name")) { streamName = document.querySelector( ".c-tv-SwitchAngleButton-current-angle-name" ).innerText; } } } if (responseText.match(/#EXT-X-STREAM-INF/) !== null) { notify({ type: "playlist", content: responseText, url: r.url, title, streamName }); } else { const keyUrlMatch = responseText.match(/#EXT-X-KEY:.*URI="(.*)"/); notify({ type: "chunklist", content: responseText, url: r.url, title, ...(keyUrlMatch && { keyUrl: keyUrlMatch[1] }) }); } switch (location.host) { case "spwn.jp": { spwn(); } } } }) .catch((e) => { reject(e); }); }); }; } XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open; Object.defineProperty(XMLHttpRequest.prototype, "open", { get: function() { return this._open; }, set: function(f) { this._open = new Proxy(f, { apply: function(f, instance, fargs) { listen.call(instance, ...fargs); return f.call(instance, ...fargs); } }); } }); XMLHttpRequest.prototype.open = XMLHttpRequest.prototype.open; const listen = function() { this.addEventListener("load", function() { if (this.readyState === 4 && new URL(this.responseURL).pathname.endsWith("m3u8")) { let title; switch (location.host) { case "nogidoga.com": { title = escapeFilename(document.querySelector(".EpisodePage__Title").innerText); break; } case "www.dmm.co.jp": { title = escapeFilename(document.querySelector(".title")?.innerText); break; } } if (this.responseText.match(/#EXT-X-STREAM-INF/) !== null) { notify({ type: "playlist", content: this.responseText, url: this.responseURL, title: title || escapeFilename(document.title) }); } else { const keyUrlMatch = this.responseText.match(/#EXT-X-KEY:.*URI="(.*)"/); notify({ type: "chunklist", content: this.responseText, url: this.responseURL, title: title || escapeFilename(document.title), ...(keyUrlMatch && { keyUrl: keyUrlMatch[1] }) }); } // Execute after m3u8 loads switch (location.host) { case "live2.nicovideo.jp": case "live.nicovideo.jp": { nico(this); break; } case "www.dmm.com": case "www.dmm.co.jp": { dmm(this); break; } case "spwn.jp": { spwn(this); break; } } } // Execute when first AJAX request finished switch (location.host) { case "www.dmm.com": case "www.dmm.co.jp": { dmm(this); break; } case "www.360ch.tv": { ch360(this); break; } case "hibiki-radio.jp": { matchurl(this, "datakey"); break; } case "www.onsen.ag": { matchurl(this, "key.m3u8key"); break; } case "www.showroom-live.com": { showroom(this); break; } case "nicochannel.jp": case "gs-ch.com": case "qlover.jp": case "pizzaradio.jp": case "kemomimirefle.net": case "tenshi-nano.com": case "ado-dokidokihimitsukichi-daigakuimo.com": case "canan8181.com": case "keisuke-ueda.jp": case "p-jinriki-fc.com": case "rnqq.jp": case "ryogomatsumaru.com": case "takahashifumiya.com": case "yamingfc.net": { matchurl(this, "https://hls-auth.cloud.stream.co.jp/key"); break; } } }); }; /** * Site Scripts */ /** * Get key for Abema! */ const abema = () => { Object.defineProperty(__CLIENT_REGION__, "isAllowed", { get: () => true }); Object.defineProperty(__CLIENT_REGION__, "status", { get: () => false }); const _Uint8Array = Uint8Array; Uint8Array = class extends _Uint8Array { constructor(...args) { super(...args); if (this.length === 16) { const key = Array.from(new _Uint8Array(this)) .map((i) => (i.toString(16).length === 1 ? "0" + i.toString(16) : i.toString(16))) .join(""); if (key !== "00000000000000000000000000000000") { notify({ type: "key", key: key }); } } return this; } }; }; const matchurl = (xhr, keyword) => { if (xhr.readyState === 4 && xhr.responseURL.includes(keyword)) { const key = Array.from(new Uint8Array(xhr.response)) .map((i) => (i.toString(16).length === 1 ? "0" + i.toString(16) : i.toString(16))) .join(""); notify({ type: "key", key: key, url: xhr.responseURL }); } }; const nico = (xhr) => { try { const liveData = JSON.parse(document.querySelector("#embedded-data").getAttribute("data-props")); const websocketUrl = liveData.site.relive.webSocketUrl; if (websocketUrl.match(/audience_token=(.+)/)[1]) { key = websocketUrl.match(/audience_token=(.+)/)[1]; } if (liveData.program?.stream?.maxQuality) { key += `,${liveData.program.stream.maxQuality}`; } notify({ type: "key", key: key, }); } catch {} }; const spwn = () => { notify({ type: "cookies", cookies: "CloudFront-Policy=" + document.cookie.match(/CloudFront-Policy\=(.+?)(;|$)/)[1] + "; " + "CloudFront-Signature=" + document.cookie.match(/CloudFront-Signature\=(.+?)(;|$)/)[1] + "; " + "CloudFront-Key-Pair-Id=" + document.cookie.match(/CloudFront-Key-Pair-Id\=(.+?)(;|$)/)[1] + "; " }); }; const dmm = (xhr) => { if ( xhr.readyState === 4 && (xhr.responseURL.match(new RegExp("https://www.dmm.(com|co.jp)/service/-/drm_iphone")) || xhr.responseURL.startsWith("https://mlic.dmm.co.jp/drm/hlsaes/key/")) ) { const key = Array.from(new Uint8Array(xhr.response)) .map((i) => (i.toString(16).length === 1 ? "0" + i.toString(16) : i.toString(16))) .join(""); notify({ type: "cookies", cookies: "licenseUID=" + document.cookie.match(/licenseUID\=(.+?)(;|$)/)[1] }); notify({ type: "key", key: key, url: xhr.responseURL }); } }; const ch360 = (xhr) => { notify({ type: "cookies", cookies: "ch360pt=" + document.cookie.match(/ch360pt\=(.+?)(;|$)/)[1] }); }; const twicas = async () => { const userName = location.href.match(/https:\/\/twitcasting.tv\/(.+?)(\/|$)/); if (userName && !location.href.includes("/movie/")) { await fetch(`https://twitcasting.tv/${userName[1]}/metastream.m3u8`); } if (location.href.includes("/movie/")) { const playlistInfo = document.querySelector("video").getAttribute("data-movie-playlist"); if (playlistInfo) { const parsedPlaylistInfo = JSON.parse(playlistInfo)[2][0]; const url = parsedPlaylistInfo.source.url; const title = escapeFilename(document.querySelector("#movie_title_content").innerText); notify({ type: "playlist_chunklist", content: "", url, title, chunkLists: [ { type: "video", resolution: { x: "Unknown", y: "Unknown" }, url } ] }); } } }; const youtube = async () => { const playerResponse = ytplayer.config.args.raw_player_response; if (playerResponse) { const HlsManifestUrl = playerResponse.streamingData.hlsManifestUrl; await fetch(HlsManifestUrl); } notify({ type: "cookies", cookies: "PREF=" + document.cookie.match(/PREF\=(.+?)(;|$)/)[1] }); }; const showroom = (xhr) => { if (xhr.responseURL.includes("api/live/streaming_url")) { const response = JSON.parse(xhr.responseText); if (response.streaming_url_list.some((i) => i.url.endsWith("chunklist.m3u8"))) { notify({ type: "playlist_chunklist", content: xhr.responseText, url: xhr.responseURL, title: escapeFilename(document.title), chunkLists: response.streaming_url_list .filter((i) => i.url.endsWith("chunklist.m3u8")) .map((i) => { return { type: "video", bandwidth: i.quality * 1024, resolution: { x: "Unknown", y: "Unknown" }, url: i.url }; }) }); } } }; const bilibili = async () => { if (!location.href.match(/live\.bilibili\.com\/(?:blanc\/)*(\d+)/)) { return; } const roomId = location.href.match(/live\.bilibili\.com\/(?:blanc\/)*(\d+)/)[1]; const api = `https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo?room_id=${roomId}&protocol=0,1&format=0,1,2&codec=0,1,2&qn=10000&platform=web&ptype=16`; const roomLiveInfo = await (await fetch(api)).json(); if (!roomLiveInfo?.data?.playurl_info?.playurl?.stream) { return; } const hlsInfo = roomLiveInfo.data.playurl_info.playurl.stream.find((i) => i.protocol_name === "http_hls"); const streamFormats = hlsInfo.format; const chunkLists = []; for (const format of streamFormats) { const codec = format.codec[0]; if (codec.url_info[0].host && codec.base_url) { const chunkListUrl = codec.url_info[0].host + codec.base_url + (codec.url_info[0].extra || ""); fetch(chunkListUrl); } } }; const asobistore = () => { const url = document.querySelector("#embed_placeholder source").getAttribute("src"); fetch(url); }; // Execute when load switch (location.host) { case "abema.tv": { abema(); break; } case "twitcasting.tv": { twicas(); break; } case "www.youtube.com": { youtube(); break; } case "live.bilibili.com": { bilibili(); break; } case "playervspf.channel.or.jp": { asobistore(); break; } } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址