您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
从 https://bv2.firefly.matce.cn 导入原神语音用于听书
// ==UserScript== // @name 原神语音听书导入 // @namespace https://yfi.moe // @version 0.1.3 // @author Yunfi <[email protected]> // @description 从 https://bv2.firefly.matce.cn 导入原神语音用于听书 // @license MIT // @icon https://bv2.firefly.matce.cn/favicon.ico // @match https://bv2.firefly.matce.cn/* // @require https://cdn.staticfile.org/vue/3.4.21/vue.global.prod.min.js // @grant GM_addStyle // ==/UserScript== (o=>{if(typeof GM_addStyle=="function"){GM_addStyle(o);return}const e=document.createElement("style");e.textContent=o,document.head.append(e)})(" :root{font-family:Inter,Avenir,Helvetica,Arial,sans-serif;font-size:16px;line-height:24px;font-weight:400;color-scheme:light dark;color:#202020de;background-color:#fff;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}.v-a{font-weight:500;color:#646cff;text-decoration:inherit}.v-a:hover{color:#535bf2}h1{font-size:3.2em;line-height:1.1}.v-button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#f9f9f9;cursor:pointer;transition:border-color .25s}.v-button:hover{border-color:#646cff}.card{padding:2em}@media (prefers-color-scheme: dark){:root{color:#ffffffde;background-color:#0b0f19}.v-a:hover{color:#747bff}.v-button{background-color:#343434}}#iread-oc-modal[data-v-63501ad3]{position:fixed;margin:auto;border:none;border-radius:1rem;box-shadow:0 0 10px #0000001a;padding:3rem}.close-dialog[data-v-63501ad3]{position:absolute;top:.5rem;right:.5rem}.inner-modal[data-v-63501ad3]{display:flex;flex-direction:column;gap:1rem;background-color:#fff}.btn-a[data-v-63501ad3]{text-decoration:none;color:inherit;text-align:center}.show-btn[data-v-43b38518]{position:fixed;bottom:1rem;right:1rem;border-radius:9999px}.btn-card[data-v-43b38518]{position:fixed;bottom:4rem;right:1rem;display:flex;flex-direction:column;gap:1rem;padding:1rem;background-color:#fff;border-radius:1rem;box-shadow:0 0 10px #0000001a}@media (prefers-color-scheme: dark){.btn-card[data-v-43b38518]{background-color:#222}}.slide-enter-active[data-v-43b38518],.slide-leave-active[data-v-43b38518]{transition:all .15s ease-in-out}.slide-enter-from[data-v-43b38518],.slide-leave-to[data-v-43b38518]{transform:translate(100%);opacity:0} "); (function (vue) { 'use strict'; function generateRandomString(digits = 32) { const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; let randomString = ""; for (let i = 0; i < digits; i++) { const randomIndex = Math.floor(Math.random() * characters.length); randomString += characters[randomIndex]; } return randomString; } function getConfig() { const selectors = [ null, "#component-5 > label > div > div.wrap-inner > div > input", "#range_id_0", "#range_id_1", "#range_id_2", "#range_id_3", "#component-14 > label > div > div.wrap-inner > div > input", "#component-29 > label > input", "#range_id_6", "#range_id_5", null, "#component-8 > label > textarea", "#component-22 > label > textarea", "#range_id_4" ]; let data = []; for (const selector of selectors) { data.push( selector ? document.querySelector(selector).value : null ); } if (!data[1]) { alert("请选择角色,或者等待页面加载完全后再点击按钮"); throw new Error("not getting data from page"); } for (let i of [2, 3, 4, 5, 8, 9, 13]) { data[i] = parseFloat(data[i]); } data[7] = false; return { data, event_data: null, fn_index: 0, session_hash: null }; } function copy2Clipboard(text) { navigator.clipboard.writeText(text).then(() => { alert("已复制到剪贴板"); }).catch((error) => { console.error("复制到剪贴板失败", error); }); } const _sfc_main$4 = /* @__PURE__ */ vue.defineComponent({ __name: "CopyIRead", setup(__props) { function generateIReadConfig() { const originConfig = getConfig(); originConfig.data[0] = "%@"; const body = JSON.stringify(originConfig); const process = `@dyn: p=def:"|'|\\n @=>; txt=keyword.jxd_executeRegexRules:p; format('${body}',txt)`; const iReadTemplate = { _ClassName: "JxdAdvCustomTTS", _TTSConfigID: generateRandomString(), maxWordCount: "200", ttsConfigGroup: "☁️", ttsHandles: [ { processType: 1, maxPageCount: 1, nextPageForGetMedthod: 1, forGetMethod: 0, requestByWebView: 0, nextPageParams: {}, url: "https://bv2.firefly.matce.cn/run/predict", parser: { audioUrl: '@str:"https://bv2.firefly.matce.cn/file={{@json:data[1].name}}"' }, httpConfigs: { useCookies: 1, headers: { "Content-Type": "application/json" }, customFormatParams: "params[data]" }, params: { data: process } }, { maxPageCount: 1, nextPageForGetMedthod: 1, requestByWebView: 0, forGetMethod: 1, processType: 1, params: {}, nextPageParams: {}, url: "@json:audioUrl", parser: { playData: "ResponseData" }, httpConfigs: { useCookies: 1, headers: {} } } ], _TTSName: "☁️ - MHY " + originConfig.data[1] }; return iReadTemplate; } function copyIRead() { const iReadConfig = generateIReadConfig(); copy2Clipboard(JSON.stringify(iReadConfig)); } return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", null, [ vue.createElementVNode("button", { onClick: copyIRead, class: "v-button" }, "复制爱阅记配置") ]); }; } }); const _sfc_main$3 = { name: "MingcuteCloseLine" }; const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const _hoisted_1$2 = { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", viewBox: "0 0 24 24" }; const _hoisted_2$1 = /* @__PURE__ */ vue.createElementVNode("g", { fill: "none", fillRule: "evenodd" }, [ /* @__PURE__ */ vue.createElementVNode("path", { d: "M24 0v24H0V0zM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022m-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" }), /* @__PURE__ */ vue.createElementVNode("path", { fill: "#888888", d: "m12 13.414l5.657 5.657a1 1 0 0 0 1.414-1.414L13.414 12l5.657-5.657a1 1 0 0 0-1.414-1.414L12 10.586L6.343 4.929A1 1 0 0 0 4.93 6.343L10.586 12l-5.657 5.657a1 1 0 1 0 1.414 1.414z" }) ], -1); const _hoisted_3$1 = [ _hoisted_2$1 ]; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$2, _hoisted_3$1); } const MingcuteCloseLine = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render]]); const _withScopeId = (n) => (vue.pushScopeId("data-v-63501ad3"), n = n(), vue.popScopeId(), n); const _hoisted_1$1 = { id: "iread-oc-modal" }; const _hoisted_2 = { class: "inner-modal" }; const _hoisted_3 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("h5", { style: { "font-size": "large", "margin": "0.5rem auto" } }, " 爱阅记一键导入 ", -1)); const _hoisted_4 = ["href"]; const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({ __name: "OneClickIRead", setup(__props) { const ocURL = vue.ref(""); function closeModal() { const modal = document.getElementById( "iread-oc-modal" ); if (modal) modal.close(); } function getUrl() { const { data } = getConfig(); if (!data) throw new Error("No data in config"); data[0] = "%@"; const dataUrl = `${BACKEND_URL}/api/gvits/ireadnote?data=${encodeURIComponent( JSON.stringify(data) )}`; const importUrl = `iReadNote://import/itts=${dataUrl}`; return importUrl; } function openModal() { const modal = document.getElementById( "iread-oc-modal" ); if (modal) modal.showModal(); ocURL.value = getUrl(); } return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createElementVNode("dialog", _hoisted_1$1, [ vue.createVNode(MingcuteCloseLine, { onClick: closeModal, class: "close-dialog" }), vue.createElementVNode("div", _hoisted_2, [ _hoisted_3, vue.createElementVNode("a", { href: ocURL.value, class: "v-button btn-a", target: "_blank" }, "直接导入", 8, _hoisted_4), vue.createElementVNode("button", { onClick: _cache[0] || (_cache[0] = ($event) => vue.unref(copy2Clipboard)(ocURL.value)), class: "v-button" }, " 复制链接 ") ]) ]), vue.createElementVNode("div", null, [ vue.createElementVNode("button", { onClick: openModal, class: "v-button" }, "爱阅记一键导入") ]) ], 64); }; } }); const OneClickIRead = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-63501ad3"]]); const _hoisted_1 = { key: 0, class: "btn-card" }; const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({ __name: "BtnCard", setup(__props) { const showCard = vue.ref(false); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createElementVNode("button", { onClick: _cache[0] || (_cache[0] = ($event) => showCard.value = !showCard.value), class: "show-btn v-button" }, "听书导入"), vue.createVNode(vue.Transition, { name: "slide" }, { default: vue.withCtx(() => [ showCard.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.createVNode(_sfc_main$4), vue.createVNode(OneClickIRead) ])) : vue.createCommentVNode("", true) ]), _: 1 }) ], 64); }; } }); const BtnCard = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-43b38518"]]); const _sfc_main = /* @__PURE__ */ vue.defineComponent({ __name: "App", setup(__props) { return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(BtnCard); }; } }); vue.createApp(_sfc_main).mount( (() => { const app = document.createElement("div"); document.body.append(app); return app; })() ); const BACKEND_URL = "https://tts.api.yfi.moe"; })(Vue);