您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
download pdf or print any sheets!
// ==UserScript== // @name Musescore Downloader // @name:zh Musescore 增强脚本 // @version 1.3.0 // @description download pdf or print any sheets! // @description:zh 去广告+任意下载乐谱 // @author Charlie // @match https://musescore.com/* // @namespace https://gf.qytechs.cn/users/890174 // @grant GM_addStyle // @grant unsafeWindow // ==/UserScript== GM_addStyle(` .SUG3q > .hei_M:nth-child(3) > .AFyen:nth-child(2), .YaB2I > section :nth-last-child(n+2), aside > div:nth-last-child(2), aside > div:nth-child(2), aside > div:nth-child(3), header > *:not(nav), .hFMfR > .AFyen, footer, ._9aj2, .p6izg, .TnQwe, .U8wvj, .jxGLy, .YRlfn, .YMprF, .MXIPY { display: none !important; } .dXt6a { background-color: #e1effe !important; padding: .3em .8em !important; border-left: 5px solid #1a4f9f !important; font-size: 14px !important; } .ZvxB2, .AJXCt { background-color: #e1effe7c !important; padding: .6em .8em !important; border-radius: 4px !important; outline: 1.5px solid #1a4f9f !important; flex-direction: column !important; } aside a { padding: 0 .3em !important; transition: background-color ease-out .15s !important; } aside a:hover { background-color: #45f !important; color: #f3f3ff !important; } aside > div:nth-child(5) { border: none !important; } aside > div:nth-child(4), aside > div:nth-child(5) { padding: 12px 20px !important; } aside > div:nth-child(4) > div { display: flex !important; place-items: center !important; flex-direction: column !important; } aside > div:nth-child(4) > div > .Pl3iC { margin-right: 16px !important; } aside > div:nth-child(4) > div.PI5Hd.g1QZl.CgHMj > section:nth-child(2) { width: 100% !important; } .oQdm2 { max-width: unset !important; } aside table { background-color: #e1effe7c !important; padding: .3em .6em !important; border-radius: 3px !important; outline: 1.5px solid #1a4f9f !important; } aside table tr { padding-bottom: 5px !important; } .a0naR, .Au_pg, .Al3lQ { height: 32px !important; width: 32px !important; color: transparent !important; border-radius: 5px !important; } .hyzNL { max-height: unset !important; } .dXt6a section { margin: 0 !important; }`) setTimeout(() => { "use strict" const ZH = navigator.language == "zh-CN" async function download() { const Window = window.open() const id = location.pathname.match(/\/[^\/]*$/)[0].slice(1) const length = unsafeWindow.UGAPP.store.page.data.score.pages_count Window.document.write(` <!DOCTYPE html> <head> <title>${document.getElementsByTagName('h1')[0].innerText}</title> <style> body { margin: 0; display: flex; min-height: 100vh; flex-direction: column; place-items: center; justify-content: center; color: rgb(49, 63, 78); background-color: rgb(237, 242, 247); transform-origin: top; transition: background-color ease .3s; will-change: background-color; overflow-x: scroll; } svg { width: 100vw; height: auto; display: block; margin: auto; } .card { display: flex; text-align: center; place-items: center; font-size: 1.2em; width: ${ ZH ? 360 : 480 }px; box-shadow: 10px 10px 8px rgba(0, 0, 0, 0.07); padding: 1.5em 2em; background-color: rgb(255, 255, 255); border-radius: 8px; transition: all ease-out .3s; overflow: hidden; white-space: nowrap; } body > * { animation: 1.5s intro; } @keyframes intro { 0%, 20% { opacity: 0; } 100% { opacity: 1; } } .card-icon { display: flex; flex-direction: column; place-items: center; margin-right: 3em; font-weight: bold; } .card-text { flex: 1; } b { color: rgb(49, 140, 252); } .spinner, .spinner * { box-sizing: border-box; } .spinner { height: 40px; width: 40px; top: calc( -10px * 2 / 3); margin-left: calc(10px / 3); margin-bottom: calc(10px / 3); } .spinner .sq { height: 10px; width: 10px; top: calc( -10px * 2 / 3); margin-right: calc(10px / 3); margin-top: calc(10px / 3); background: rgb(49, 140, 252); float: left; position: relative; opacity: 0; animation: spinner 6s infinite; } ${Array(9).fill().map((_, i) => `.spinner .sq:nth-child(${i+1}) { animation-delay: calc(300ms * ${8-i}); }`).join("\n")} .spinner .clear { clear: both; } @keyframes spinner { 0% { opacity: 0; } 5% { opacity: 1; top: 0; } 50.9% { opacity: 1; top: 0; } 55.9% { opacity: 0; top: inherit; } } @media print { @page { margin: 0; } button { display: none; } svg { width: 21cm; height: 29.7cm; } } .btn-group { position: fixed; left: 32px; top: 24px; } button { font-size: 1.4em; font-weight: bold; box-shadow: 1px 2px 8px rgba(0, 0, 0, 0.1); padding: .4em ${ ZH ? 1.5 : 0.8 }em; margin-right: 1.2em; background-color: rgb(255, 255, 255); color: rgb(49, 63, 78); border-radius: 4px; cursor: pointer; outline: 1.5px solid rgb(49, 63, 78); border: none; transition: all ease-out .2s; } button:hover { background-color: rgb(235, 235, 235); } button:active { outline-color: black; transform: scale(0.97); } .hint { margin: 1em 0; color: #a7b2be; } </style> </head> <body> <div class="card"> <div class="card-icon"> <div class="spinner"> <div class="sq"></div> <div class="sq"></div> <div class="sq"></div> <div class="sq clear"></div> <div class="sq"></div> <div class="sq"></div> <div class="sq clear"></div> <div class="sq"></div> <div class="sq"></div> </div> <div class="card-icon-text">${ ZH ? "下载中" : "Downloading" }</div> </div> <div class="card-text"> ${ ZH ? `已下载 <b id="download-status">0</b> 页,共 <b>${length}</b> 页` : `<b id="download-status">0</b> page(s) loaded, <b>${length}</b> total` } </div> </div> <span class="hint">${ ZH ? "点击左上方的 <b>打印</b> 按钮,选择 <b>另存为PDF</b> 即可下载乐谱。" : "To download the sheet, click <b>PRINT</b> button on the top left then select <b>Export PDF</b>." }</span> </body>`) Window.onbeforeunload = e => { e.preventDefault() e.returnValue = "QwQ" return "awa" } let data = Array(length).fill(""), cnt = 0 async function getData() { return Promise.all( data.filter(e => e.length == 0).map((_, i) => new Promise(async (res, rej) => { let url = await fetch(`https://musescore.com/api/jmuse?id=${id}&type=img&v2=1&index=${i}`, { headers: { authorization: "8c022bdef45341074ce876ae57a48f64b86cdcf5" } }).then(e => e.json()).then(e => e.info.url).catch(rej) data[i] = await fetch(url).then(e => e.text()).catch(rej) Window.document.getElementById("download-status").innerText = ++cnt res() })) ).catch((err) => console.error(err)) } setTimeout(() => { Window.document.getElementsByClassName("hint")[0].innerText = ZH ? "如果长时间没反应就不要傻等着了,现在或者等会再试试吧。" : "If the process stoped, you can try again now or later." }, 8 * 1000) await getData() setTimeout(async () => { Window.document.getElementsByClassName("card-icon-text")[0].innerText = ZH ? "解析中" : "Decoding" if(cnt != length) { Window.document.getElementsByClassName("card-text")[0].innerText = ZH ? "下载失败,请稍后再试。" : "Download failed, try again later." return } setTimeout(() => { Window.document.body.style.background = "white" Window.document.body.innerHTML = data.join("") + `<div class="btn-group"><button onclick="print()">${ ZH ? "打印" : "PRINT" }</button>` const svgs = [...Window.document.getElementsByTagName("svg")] svgs.forEach((e) => e.setAttribute("viewBox", `0 0 ${e.width.baseVal.value} ${e.height.baseVal.value}`)) Window.scrollTo(0, 0) }, 400) }, 400) } const btns = [...document.getElementsByTagName("button")] btns.filter(el => { const val = el.attributes.getNamedItem("name")?.value return val == "download" || val == "print" }).forEach(el => { const type = el.attributes.getNamedItem("name").value const fakeEl = el.cloneNode(true) fakeEl.style.border = "2px #0dbc79 solid" if(type == "download") fakeEl.style.background = "#0dbc79" fakeEl.onclick = download el.parentNode.replaceChild(fakeEl, el) }) }, 500)
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址