no message

This commit is contained in:
DESKTOP-RQ919RC\Pc
2025-12-10 16:32:02 +08:00
parent 8d664fcbea
commit 1334fa197f

View File

@@ -746,6 +746,11 @@
<script src="/static/js/ffmpeg.min.js"></script> <script src="/static/js/ffmpeg.min.js"></script>
<script src="/static/js/html2canvas.min.js"></script> <script src="/static/js/html2canvas.min.js"></script>
<script src="/static/js/html-to-image.js"></script> <script src="/static/js/html-to-image.js"></script>
<script src="https://unpkg.com/vconsole@3.15.1/dist/vconsole.min.js"></script>
<script>
// VConsole will be exported to `window.VConsole` by default.
var vConsole = new window.VConsole();
</script>
</head> </head>
<body> <body>
@@ -960,9 +965,9 @@
setTimeout(() => els.loader.remove(), 600); setTimeout(() => els.loader.remove(), 600);
} }
async function renderUI(data) { async function renderUI(data) {
els.songTitle.innerText = data.title; els.songTitle.innerText = data.title;
// 预加载图片并转换为 Blob URL (解决跨域和缓存问题) // 预加载图片并转换为 Blob URL (解决跨域和缓存问题)
try { try {
const imgRes = await fetch(data.img); const imgRes = await fetch(data.img);
@@ -1656,47 +1661,49 @@
// 启动渲染循环html-to-image 截图 // 启动渲染循环html-to-image 截图
// 目标帧率 120 FPS不再使用 setTimeout 限流,而是全力渲染 // 目标帧率 120 FPS不再使用 setTimeout 限流,而是全力渲染
const targetFPS = 120; const targetFPS = 120;
async function renderLoop() { async function renderLoop() {
if (!isMVRecording) return; if (!isMVRecording) return;
console.log('renderLoop');
// 标记开始处理 // 标记开始处理
const beginTime = Date.now(); const beginTime = Date.now();
try { try {
const source = document.querySelector('.main-container'); const source = document.querySelector('.main-container');
if (source) { if (source) {
// 恢复高清录制,限制最大 dpr 为 2 以平衡性能 // 恢复高清录制,限制最大 dpr 为 2 以平衡性能
const dpr = Math.min(window.devicePixelRatio || 1, 2); const dpr = Math.min(window.devicePixelRatio || 1, 2);
const canvas = await htmlToImage.toCanvas(source, { const canvas = await htmlToImage.toCanvas(source, {
backgroundColor: null, backgroundColor: null,
pixelRatio: dpr, pixelRatio: dpr,
skipAutoScale: true, skipAutoScale: true,
cacheBust: false, cacheBust: false,
fontEmbedCSS: '', // 禁用字体嵌入,防止崩溃 fontEmbedCSS: '', // 禁用字体嵌入,防止崩溃
filter: (node) => { filter: (node) => {
// 过滤无效图片防止崩溃 // 过滤无效图片防止崩溃
if (node.tagName === 'IMG' && (!node.src || node.src === window.location.href)) return false; if (node.tagName === 'IMG' && (!node.src || node.src === window.location.href)) return false;
return true; return true;
}, },
style: { style: {
transform: 'translateZ(0)' transform: 'translateZ(0)'
} }
}); });
// 将捕捉到的画面绘制到录制画布上 // 将捕捉到的画面绘制到录制画布上
mvCtx.clearRect(0, 0, mvCanvas.width, mvCanvas.height); mvCtx.clearRect(0, 0, mvCanvas.width, mvCanvas.height);
mvCtx.drawImage(canvas, 0, 0, mvCanvas.width, mvCanvas.height); mvCtx.drawImage(canvas, 0, 0, mvCanvas.width, mvCanvas.height);
} }
} catch (e) { } catch (e) {
console.error('Frame capture error:', e); console.error('Frame capture error:', e);
} }
// 不再使用 setTimeout 进行延时,避免 JS 定时器精度问题导致的抖动 // 不再使用 setTimeout 进行延时,避免 JS 定时器精度问题导致的抖动
// 直接请求下一帧,让浏览器决定最佳时机(通常是 60Hz如果设备支持高刷则更高 // 直接请求下一帧,让浏览器决定最佳时机(通常是 60Hz如果设备支持高刷则更高
// 这样可以消除人为引入的卡顿 // 这样可以消除人为引入的卡顿
if (isMVRecording) { if (isMVRecording) {
mvRafId = requestAnimationFrame(renderLoop); mvRafId = requestAnimationFrame(renderLoop);
} }
} }
mvRafId = requestAnimationFrame(renderLoop); mvRafId = requestAnimationFrame(renderLoop);