网页脚本 bilibili004:字幕展示添加下载功能实现

news2024/11/27 4:17:45

效果

  • 按钮显示
    在这里插入图片描述
  • 按钮hover
    在这里插入图片描述
  • 按钮点击
    在这里插入图片描述

代码实现

在main函数中添加下载逻辑

 getVideoName().then((resultObject) => {// 处理异步的Promise对象,https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
  addDownloadButton(subtitles[0],resultObject );
  console.log(resultObject);
})

添加按钮

function addDownloadButton(theurl, thename){
    let myButton = document.createElement('button');
    myButton.textContent = 'Click me';
    myButton.classList.add("download");
    myButton.style = 'font-size: 26px; position: fixed; top: 200px; left: 0; z-index: 9999; list-style: none; border: 1px red solid; border-radius: 10px;background-color: #00ccff; padding:5px';
    myButton.innerHTML ='<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" class="zhuzhan-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.73252 2.67094C3.33229 2.28484 3.33229 1.64373 3.73252 1.25764C4.11291 0.890684 4.71552 0.890684 5.09591 1.25764L7.21723 3.30403C7.27749 3.36218 7.32869 3.4261 7.37081 3.49407H10.5789C10.6211 3.4261 10.6723 3.36218 10.7325 3.30403L12.8538 1.25764C13.2342 0.890684 13.8368 0.890684 14.2172 1.25764C14.6175 1.64373 14.6175 2.28484 14.2172 2.67094L13.364 3.49407H14C16.2091 3.49407 18 5.28493 18 7.49407V12.9996C18 15.2087 16.2091 16.9996 14 16.9996H4C1.79086 16.9996 0 15.2087 0 12.9996V7.49406C0 5.28492 1.79086 3.49407 4 3.49407H4.58579L3.73252 2.67094ZM4 5.42343C2.89543 5.42343 2 6.31886 2 7.42343V13.0702C2 14.1748 2.89543 15.0702 4 15.0702H14C15.1046 15.0702 16 14.1748 16 13.0702V7.42343C16 6.31886 15.1046 5.42343 14 5.42343H4ZM5 9.31747C5 8.76519 5.44772 8.31747 6 8.31747C6.55228 8.31747 7 8.76519 7 9.31747V10.2115C7 10.7638 6.55228 11.2115 6 11.2115C5.44772 11.2115 5 10.7638 5 10.2115V9.31747ZM12 8.31747C11.4477 8.31747 11 8.76519 11 9.31747V10.2115C11 10.7638 11.4477 11.2115 12 11.2115C12.5523 11.2115 13 10.7638 13 10.2115V9.31747C13 8.76519 12.5523 8.31747 12 8.31747Z" fill="currentColor"></path></svg>'
    myButton.addEventListener("mouseover", function() {
        myButton.innerHTML ="DOWN LOAD SUBTITLE";
    });

    myButton.addEventListener("mouseout", function() {
        myButton.innerHTML ='<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" class="zhuzhan-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.73252 2.67094C3.33229 2.28484 3.33229 1.64373 3.73252 1.25764C4.11291 0.890684 4.71552 0.890684 5.09591 1.25764L7.21723 3.30403C7.27749 3.36218 7.32869 3.4261 7.37081 3.49407H10.5789C10.6211 3.4261 10.6723 3.36218 10.7325 3.30403L12.8538 1.25764C13.2342 0.890684 13.8368 0.890684 14.2172 1.25764C14.6175 1.64373 14.6175 2.28484 14.2172 2.67094L13.364 3.49407H14C16.2091 3.49407 18 5.28493 18 7.49407V12.9996C18 15.2087 16.2091 16.9996 14 16.9996H4C1.79086 16.9996 0 15.2087 0 12.9996V7.49406C0 5.28492 1.79086 3.49407 4 3.49407H4.58579L3.73252 2.67094ZM4 5.42343C2.89543 5.42343 2 6.31886 2 7.42343V13.0702C2 14.1748 2.89543 15.0702 4 15.0702H14C15.1046 15.0702 16 14.1748 16 13.0702V7.42343C16 6.31886 15.1046 5.42343 14 5.42343H4ZM5 9.31747C5 8.76519 5.44772 8.31747 6 8.31747C6.55228 8.31747 7 8.76519 7 9.31747V10.2115C7 10.7638 6.55228 11.2115 6 11.2115C5.44772 11.2115 5 10.7638 5 10.2115V9.31747ZM12 8.31747C11.4477 8.31747 11 8.76519 11 9.31747V10.2115C11 10.7638 11.4477 11.2115 12 11.2115C12.5523 11.2115 13 10.7638 13 10.2115V9.31747C13 8.76519 12.5523 8.31747 12 8.31747Z" fill="currentColor"></path></svg>'
    });
    myButton.addEventListener('click',() => {
        console.log("]]]]]]]]]]]]]]]]",thename,JSON.stringify(thename) );
        myshowTranscript(theurl,thename);
    })
    document.body.appendChild(myButton);
}

获取视频名称

async function getVideoName(route /* : string|undefined */) {
  const { bvid, curPage } = getBvid(route);
  if (!bvid) throw new Error("没有找到 bvid");
  const videoInfo = await request("/x/web-interface/view?bvid=" + bvid);
    let vres = videoInfo.pages[0].part;
  return vres;
}

加载视频字幕内容并下载

async function myshowTranscript(subtitleInfo,thename) {
  console.log("myshowTranscript", subtitleInfo);
  const { body: lines } = await fetch(
    subtitleInfo.subtitle_url.replace(/^\/\//, "https://")
  ).then((res) => res.json());
  console.log("lines", lines);
  transcriptBox.innerHTML = "";
  var mytext = [];
  for (let line of lines) {
    if (line.music && line.music > MUSIC_FILTER_RATE) {
      continue;
    }
    mytext.push(line.content+"\n")
  }
    var blob = new Blob(mytext, { type: 'text/plain' });
    var link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = thename+ '.txt';
    document.body.appendChild(link);
    link.click();// Trigger a click event on the link to initiate the download
    document.body.removeChild(link);
}

总体代码

// ==UserScript==
// @name         在侧边显示 Bilibili 视频字幕/文稿
// @name:en      Show transcript of Bilibili video on the side
// @version      1.1.1
// @description:en  Automatically display Bilibili video subtitles/scripts by default, support click to jump, text selection, auto-scrolling.
// @description     默认自动显示Bilibili视频字幕/文稿,支持点击跳转、文本选中、自动滚动。
// @namespace    https://bilibili.com/
// @match        https://www.bilibili.com/video/*
// @icon         https://www.bilibili.com/favicon.ico
// @author       bowencool、fakeoccupational
// @license      MIT
// @homepageURL  https://greasyfork.org/scripts/482165
// @supportURL   https://github.com/bowencool/Tampermonkey-Scripts/issues
// @grant        GM_addStyle
// @downloadURL https://update.greasyfork.org/scripts/482165/%E5%9C%A8%E4%BE%A7%E8%BE%B9%E6%98%BE%E7%A4%BA%20Bilibili%20%E8%A7%86%E9%A2%91%E5%AD%97%E5%B9%95%E6%96%87%E7%A8%BF.user.js
// @updateURL https://update.greasyfork.org/scripts/482165/%E5%9C%A8%E4%BE%A7%E8%BE%B9%E6%98%BE%E7%A4%BA%20Bilibili%20%E8%A7%86%E9%A2%91%E5%AD%97%E5%B9%95%E6%96%87%E7%A8%BF.meta.js
// ==/UserScript==

function waitForElementToExist(selector) {
  return new Promise((resolve) => {
    if (document.querySelector(selector)) {
      return resolve(document.querySelector(selector));
    }

    const observer = new MutationObserver(() => {
      if (document.querySelector(selector)) {
        resolve(document.querySelector(selector));
        observer.disconnect();
      }
    });

    observer.observe(document.body, {
      subtree: true,
      childList: true,
    });
  });
}

async function request(url, options) {
  return fetch(`https://api.bilibili.com${url}`, {
    ...options,
    credentials: "include",
  })
    .then((res) => res.json())
    .then((data) => {
      if (data.code != 0) {
        throw new Error(data.message);
      }
      return data.data;
    });
}

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

GM_addStyle(`
.transcript-box {
  border: 1px solid #e1e1e1;
  border-radius: 6px;
  padding: 12px 16px;
  max-height: 50vh;
  overflow: scroll;
  margin-bottom: 20px;
  pointer-events: initial;
}
.transcript-line {
    display: flex;
}
.transcript-line:hover {
  background-color: #0002;
}
.transcript-line.active {
  font-weight: bold;
  background-color: #0002;
}

.transcript-line-time {
    flex: none;
    overflow: hidden;
    width:66px;
    user-select: none;
    corsur: pointer;
    color: var(--bpx-fn-hover-color,#00b5e5);
}

.transcript-line-content {
    // white-space: nowrap;
}

`);

const MUSIC_FILTER_RATE = 0.85;

function fixNumber(n) {
  return n.toLocaleString("en-US", {
    minimumIntegerDigits: 2,
    useGrouping: false,
  });
}

function parseTime(t) {
  t = parseInt(t);
  return `${fixNumber(parseInt(t / 60))}:${fixNumber(t % 60)}`;
}

const transcriptBox = document.createElement("div");
transcriptBox.className = "transcript-box";
async function showTranscript(subtitleInfo) {
  console.log("showTranscript", subtitleInfo);
  const { body: lines } = await fetch(
    subtitleInfo.subtitle_url.replace(/^\/\//, "https://")
  ).then((res) => res.json());
  console.log("lines", lines);
  transcriptBox.innerHTML = "";
  for (let line of lines) {
    if (line.music && line.music > MUSIC_FILTER_RATE) {
      continue;
    }
    let timeLink = document.createElement("a");
    timeLink.className = "transcript-line-time";
    // timeLink.setAttribute("data-index", line.index);
    timeLink.textContent = parseTime(line.from);
    timeLink.addEventListener("click", () => {
      video.currentTime = line.from;
    });
    let lineDiv = document.createElement("div");
    lineDiv.className = "transcript-line";
    lineDiv.setAttribute("data-from", line.from);
    lineDiv.setAttribute("data-to", line.to);
    lineDiv.appendChild(timeLink);
    let span = document.createElement("span");
    span.className = "transcript-line-content";
    span.textContent = line.content;

    lineDiv.appendChild(span);
    transcriptBox.appendChild(lineDiv);
  }
}


async function myshowTranscript(subtitleInfo,thename) {
  console.log("myshowTranscript", subtitleInfo);
  const { body: lines } = await fetch(
    subtitleInfo.subtitle_url.replace(/^\/\//, "https://")
  ).then((res) => res.json());
  console.log("lines", lines);
  transcriptBox.innerHTML = "";
  var mytext = [];
  for (let line of lines) {
    if (line.music && line.music > MUSIC_FILTER_RATE) {
      continue;
    }
    mytext.push(line.content+"\n")
  }
    var blob = new Blob(mytext, { type: 'text/plain' });
    var link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = thename+ '.txt';
    document.body.appendChild(link);
    link.click();// Trigger a click event on the link to initiate the download
    document.body.removeChild(link);
}


function getBvid(route /* : string|undefined */) {
  let url;
  if (route) {
    url = new URL(window.location.origin + route);
  } else {
    url = new URL(window.location.href);
  }
  const bvid = url.pathname.match(/\/video\/(\w+)/)?.[1];
  // if (!bvid) throw new Error("没有找到 bvid");
  let curPage = url.searchParams.get("p") - 1;
  if (!curPage || curPage == -1) {
    curPage = 0;
  }
  return { bvid, curPage };
}
async function getTranscript(route /* : string|undefined */) {
  const { bvid, curPage } = getBvid(route);
  if (!bvid) throw new Error("没有找到 bvid");
  const videoInfo = await request("/x/web-interface/view?bvid=" + bvid);
  const {
    subtitle: { subtitles = [] },
  } = await request(
    `/x/player/v2?aid=${videoInfo.aid}&cid=${videoInfo.pages[curPage].cid}`
  );
  console.log("subtitles", subtitles);
  transcriptBox.innerHTML = "没有字幕";
  if (subtitles.length == 0) throw new Error("没有字幕");
  return subtitles;
}

async function getVideoName(route /* : string|undefined */) {
  const { bvid, curPage } = getBvid(route);
  if (!bvid) throw new Error("没有找到 bvid");
  const videoInfo = await request("/x/web-interface/view?bvid=" + bvid);
    console.log('00000000000');
     console.log(videoInfo);
    console.log(videoInfo.pages[0].part);
    let mres = videoInfo.pages[0].part;
  return mres;
}

async function main() {
  "use strict";
  const subtitles = await getTranscript();
  // B站页面是SSR的,如果插入过早,页面 js 检测到实际 Dom 和期望 Dom 不一致,会导致重新渲染
  await waitForElementToExist("img.bili-avatar-img");
  const video = await waitForElementToExist("video");
  // const oldfanfollowEntry = await waitForElementToExist("#oldfanfollowEntry");
  video.addEventListener("timeupdate", () => {
    const currentTime = video.currentTime;
    const lastActiveLine = document.querySelector(".transcript-line.active");
    const lineBoxes = lastActiveLine
      ? [lastActiveLine, lastActiveLine.nextSibling]
      : document.querySelectorAll(".transcript-line");

    for (let i = 0; i < lineBoxes.length; i++) {
      const currentLine = lineBoxes[i];
      const from = +currentLine.getAttribute("data-from");
      const to = +currentLine.getAttribute("data-to");
      // console.log({ i, from, to, currentTime }, currentLine);
      if (currentTime >= to || currentTime <= from) {
        // Remove the 'active' class
        if (currentLine.classList.contains("active")) {
          currentLine.classList.remove("active");
        }
      }
      if (currentTime > from && currentTime < to) {
        const targetPosition =
          currentLine.offsetTop - transcriptBox.clientHeight * 0.5;
        transcriptBox.scrollTo(0, targetPosition);
        // Add the 'active' class to the current line
        currentLine.classList.add("active");
        break;
      }
    }
  });
  await showTranscript(subtitles[0]);

 getVideoName().then((resultObject) => {// 处理异步的Promise对象,https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
  addDownloadButton(subtitles[0],resultObject );
  console.log(resultObject);
})


  const danmukuBox = await waitForElementToExist("#danmukuBox");
  // B站页面是SSR的,如果插入过早,页面 js 检测到实际 Dom 和期望 Dom 不一致,会导致重新渲染
  danmukuBox.parentNode.insertBefore(transcriptBox, danmukuBox);
}

async function updateTranscript(route /* : string|undefined */) {
  const subtitles = await getTranscript(route);
  await showTranscript(subtitles[0]);
}

main();



function addDownloadButton(theurl, thename){
    let myButton = document.createElement('button');
    myButton.textContent = 'Click me';
    myButton.classList.add("download");
    myButton.style = 'font-size: 26px; position: fixed; top: 200px; left: 0; z-index: 9999; list-style: none; border: 1px red solid; border-radius: 10px;background-color: #00ccff; padding:5px';
    myButton.innerHTML ='<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" class="zhuzhan-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.73252 2.67094C3.33229 2.28484 3.33229 1.64373 3.73252 1.25764C4.11291 0.890684 4.71552 0.890684 5.09591 1.25764L7.21723 3.30403C7.27749 3.36218 7.32869 3.4261 7.37081 3.49407H10.5789C10.6211 3.4261 10.6723 3.36218 10.7325 3.30403L12.8538 1.25764C13.2342 0.890684 13.8368 0.890684 14.2172 1.25764C14.6175 1.64373 14.6175 2.28484 14.2172 2.67094L13.364 3.49407H14C16.2091 3.49407 18 5.28493 18 7.49407V12.9996C18 15.2087 16.2091 16.9996 14 16.9996H4C1.79086 16.9996 0 15.2087 0 12.9996V7.49406C0 5.28492 1.79086 3.49407 4 3.49407H4.58579L3.73252 2.67094ZM4 5.42343C2.89543 5.42343 2 6.31886 2 7.42343V13.0702C2 14.1748 2.89543 15.0702 4 15.0702H14C15.1046 15.0702 16 14.1748 16 13.0702V7.42343C16 6.31886 15.1046 5.42343 14 5.42343H4ZM5 9.31747C5 8.76519 5.44772 8.31747 6 8.31747C6.55228 8.31747 7 8.76519 7 9.31747V10.2115C7 10.7638 6.55228 11.2115 6 11.2115C5.44772 11.2115 5 10.7638 5 10.2115V9.31747ZM12 8.31747C11.4477 8.31747 11 8.76519 11 9.31747V10.2115C11 10.7638 11.4477 11.2115 12 11.2115C12.5523 11.2115 13 10.7638 13 10.2115V9.31747C13 8.76519 12.5523 8.31747 12 8.31747Z" fill="currentColor"></path></svg>'
    myButton.addEventListener("mouseover", function() {
        myButton.innerHTML ="DOWN LOAD SUBTITLE";
    });

    myButton.addEventListener("mouseout", function() {
        myButton.innerHTML ='<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" class="zhuzhan-icon"><path fill-rule="evenodd" clip-rule="evenodd" d="M3.73252 2.67094C3.33229 2.28484 3.33229 1.64373 3.73252 1.25764C4.11291 0.890684 4.71552 0.890684 5.09591 1.25764L7.21723 3.30403C7.27749 3.36218 7.32869 3.4261 7.37081 3.49407H10.5789C10.6211 3.4261 10.6723 3.36218 10.7325 3.30403L12.8538 1.25764C13.2342 0.890684 13.8368 0.890684 14.2172 1.25764C14.6175 1.64373 14.6175 2.28484 14.2172 2.67094L13.364 3.49407H14C16.2091 3.49407 18 5.28493 18 7.49407V12.9996C18 15.2087 16.2091 16.9996 14 16.9996H4C1.79086 16.9996 0 15.2087 0 12.9996V7.49406C0 5.28492 1.79086 3.49407 4 3.49407H4.58579L3.73252 2.67094ZM4 5.42343C2.89543 5.42343 2 6.31886 2 7.42343V13.0702C2 14.1748 2.89543 15.0702 4 15.0702H14C15.1046 15.0702 16 14.1748 16 13.0702V7.42343C16 6.31886 15.1046 5.42343 14 5.42343H4ZM5 9.31747C5 8.76519 5.44772 8.31747 6 8.31747C6.55228 8.31747 7 8.76519 7 9.31747V10.2115C7 10.7638 6.55228 11.2115 6 11.2115C5.44772 11.2115 5 10.7638 5 10.2115V9.31747ZM12 8.31747C11.4477 8.31747 11 8.76519 11 9.31747V10.2115C11 10.7638 11.4477 11.2115 12 11.2115C12.5523 11.2115 13 10.7638 13 10.2115V9.31747C13 8.76519 12.5523 8.31747 12 8.31747Z" fill="currentColor"></path></svg>'
    });
    myButton.addEventListener('click',() => {
        console.log("]]]]]]]]]]]]]]]]",thename,JSON.stringify(thename) );
        myshowTranscript(theurl,thename);
    })
    document.body.appendChild(myButton);
}


function getCurrentState(route) {
  const { bvid, curPage } = getBvid(route);
  return `${bvid}?p=${curPage}`;
}
let lastState = getCurrentState();
traceRoute();

function traceRoute() {
  // popstate 可以监测到 hashchange
  window.addEventListener("popstate", (evt) => {
    const to = getCurrentState();
    if (to !== lastState) {
      console.log("bvid changed when popstate", lastState, to);
      updateTranscript();
    }
  });
  let theHistory /* History */ = history || window.history;
  if (!theHistory) return;

  const replacement = (originFn /* History['pushState'] */) => {
    return (data /* any */, t /* string */, route /* string | undefined */) => {
      const from = getCurrentState();
      const to = getCurrentState(route);
      if (route && from !== to) {
        console.log("bvid changed when pushState", from, to, route);
        updateTranscript(route);
      }
      const ret = originFn.call(theHistory, data, t, route);
      if (to) {
        lastState = to;
      }
      return ret;
    };
  };
  overrideMethod(
    /* <History['pushState']> */ theHistory,
    "pushState",
    replacement
  );
  overrideMethod(
    /* <History['replaceState']> */ theHistory,
    "replaceState",
    replacement
  );
}
function overrideMethod /* <F extends Function> */(
  target /* : { [key: string]: any } */,
  key /* : string */,
  replacement /* : (f: F) => F */
) {
  if (!(key in target)) return;
  const originFn /* : F */ = target[key];
  const wrapped /* : F */ = replacement(originFn);
  if (wrapped instanceof Function) {
    target[key] = wrapped;
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1456567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Fiddler与wireshark使用

Fiddler解决三个问题 1、SSL证书打勾&#xff0c;解析https请求 2、响应回来乱码&#xff0c;不是中文 3、想及时中止一下&#xff0c;查看实时的日志 4、搜索对应的关键字 问题1解决方案&#xff1a; 标签栏Tools下 找到https&#xff0c;全部打勾 Actions里面 第一个 t…

沁恒CH32V30X学习笔记00--芯片概述

芯片概述 资源 系统框图 V303时钟树 V305/V307时钟 RISC-V4F 处理器 单精度浮点运算 处理器内部以模块化管理, 包含快速可编程中断控制器(PFIC) 内存保护 分支预测模式 扩展指令支持等单元 小端数据模式 多级硬件中断堆栈&#

ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整

文章目录 ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整获取音频长度pydub获取音频长度获取时长精确到秒格式设定 mutagen获取音频长度 调整音量视频音量调整注意事项 ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整 老王媳妇说上次那个pip挺好…

『运维备忘录』之 SSH 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等知识&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

OpenAI最新模型Sora到底有多强?眼见为实的真实世界即将成为过去!

文章目录 1. 写在前面2. 什么是Sora&#xff1f;3. Sora的技术原理 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感…

Linux-文件文件夹相关命令

目录 常见命令 1. 创建空目录&#xff1a;mkdir 文件夹名 2. 删除空目录&#xff1a;rmdir 文件夹名 3. 创建多级目录&#xff1a;mkdir -p 123/abc 4. 删除非空文件 rm -rf 文件夹名 5. 创建文件&#xff1a; touch 文件名.后缀 / vi 文件名.后缀 6. 删除文件&#x…

挑战杯 基于GRU的 电影评论情感分析 - python 深度学习 情感分类

文章目录 1 前言1.1 项目介绍 2 情感分类介绍3 数据集4 实现4.1 数据预处理4.2 构建网络4.3 训练模型4.4 模型评估4.5 模型预测 5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于GRU的 电影评论情感分析 该项目较为新颖&#xff0c;适合作为竞…

Spring Boot java -jar --spring.profiles.active=dev 失效问题

之前动态部署修改配置文件的情况不多&#xff0c;所以也没注意过&#xff0c;这个问题今天困扰了好久&#xff0c;经过多方查询后得到了解决办法 直接上代码 <profiles><profile><!-- 本地开发环境 --><id>dev</id><properties><profi…

Codeforces Global Round 6

CF1266A Competitive Programmer 题目 给出n个数,问对于每个数,是否可以将这个数的数位重新组合(可以有前导零), 使其可以被60整除,若可以,则输出red,否则,输出cyan 分析 首先来看被60整除需要满足什么条件&#xff0c;因为602*3*10&#x…

2024年 前端JavaScript入门到精通 第一天 笔记

主要讲解JavaScript核心知识&#xff0c;包含最新ES6语法&#xff0c;从基础到API再到高级。让你一边学习一边练习&#xff0c;重点知识及时实践&#xff0c;同时每天安排大量作业&#xff0c;加深记忆&#xff0c;巩固学习成果。 1.1 基本软件与准备工作 1.2 JavaScript 案例 …

Spring MVC(基于 Spring4.x)基础学习

一、SpringMVC概述 二、SpringMVC的HelloWorld 三、使用RequestMapping映射请求 四、映射请求参数&请求头 五、处理模型数据 六、视图和视图解析器 七、RESTful CRUD 八、SpringMVC表单标签&处理静态资源 九、数据转换&数据格式化&数据校验 十、处理JSON:使用…

微信小程序:实现微信小程序应用首页开发 (本地生活首页)

文章目录 小程序应用页面开发1、创建项目并配置项目目录结构配置导航栏效果三、配置 tabBar 效果四、轮播图实现4.1 创建轮播图数据容器4.2 定义一个请求轮播图数据的接口4.3 页面加载调用 数据请求接口 五、九宫格实现5.1 获取九宫格数据5.2 结构和样式的完善六、图片布局实现…

MyBatisPlus 整合 SpringBoot 遇见的问题

【异常】&#xff1a;Cause: java.sql.SQLSyntaxErrorException: Unknown column ‘udf1’ in ‘field list’… SQL: SELECT id,oper_id,btch_id,udf1, FROM scan_cyber Cause: java.sql.SQLSyntaxErrorException: Unknown column ‘udf1’ in ‘field list’; ,"messag…

Python 实现 RSI 指标计算:股票技术分析的利器系列(4)

Python 实现 RSI 指标计算&#xff1a;股票技术分析的利器系列&#xff08;4&#xff09; 介绍算法解释 代码rolling函数介绍计算LCshift函数语法&#xff1a;参数&#xff1a;返回值&#xff1a; 计算涨跌幅函数MAX介绍语法&#xff1a;参数&#xff1a;返回值&#xff1a;示例…

小米4A路由器如何刷OpenWRT并结合内网穿透实现公网远程访问

文章目录 推荐前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理界面4.4 创建公网地址 5. 固定公网地址访问 推荐 前些天发现了一个巨牛的人工智…

USB-C音频转接器:实现边充电边听歌的新选择 | LDR6020P

随着科技浪潮的推进&#xff0c;Type-C接口已逐渐成为电子设备的主流选择&#xff0c;以其正反随意插、高速传输和强大功能等独特优势&#xff0c;在日常生活中占据越来越重要的地位。而Type-C音频转接器&#xff0c;作为连接Type-C接口与音频设备的桥梁&#xff0c;正引领着音…

Springboot集成activiti,低代码整合平台,智慧审批,前端vue

一、项目形式 springbootvueactiviti集成了activiti在线编辑器&#xff0c;快速开发平台&#xff0c;可插拔工作流服务。 二、项目介绍 本项目拥有用户管理&#xff0c;部门管理&#xff0c;代码生成&#xff0c;系统监管&#xff0c;报表&#xff0c;大屏展示&#xff0c;业…

什么样的服务器是高性能服务器?

首先&#xff0c;高性能服务器应具备高处理能力。随着业务的不断扩展和数据量的爆炸性增长&#xff0c;高性能服务器需要具备强大的计算能力&#xff0c;能够快速处理各种复杂的业务和数据。这要求高性能服务器采用先进的处理器技术&#xff0c;如多核处理器、GPU加速等&#x…

Java 学习和实践笔记(14)

OOP :面向对象编程&#xff0c;object oriented programming. 用表格就可以很好地理解类、对象、属性、以及动作这些概念。 一个表&#xff08;结构&#xff09;就对应一个类&#xff08;结构&#xff09;。所以凡叫什么类&#xff0c;自己就在心里把它叫什么表。反过来&…

Linux——信号(1)

在我们使用Linux系统的时候我们经常会使用ctrl c的方式来终止进程&#xff0c;也 会使用kill命令来杀掉进程&#xff0c;评判进程退出的健康程度中也有信号的身影。那 么Linux中的信号到底是什么&#xff1f;今天就由我来介绍Linux中的信号。1. 信号的概念 要了解计算机中的信…