想把腾讯视频会议转写的文字稿导出,在网上找到一个油猴脚本,无法使用,然后放到deepseek里面让其修改,经过几次反复,修改成功。下面是代码,复制到油猴里面就可以用了。代码里面有修改前代码的github地址。

// ==UserScript== // @name 腾讯会议转写纪要导出神器 (Tencent Meeting Transcript Exporter) 修复版 // @namespace https://github.com/awesome-tampermonkey // @version 1.1.2 // @description 一键导出腾讯会议录制视频和纯文字转写的内容和纪要,支持Markdown、HTML、TXT格式导出和复制 // @author 东哥说AI // @match https://meeting.tencent.com/cw/* // @match https://meeting.tencent.com/ct/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; const CONFIG = { BUTTON_STYLE: ` position: fixed; top: 20px; right: 20px; z-index: 10000; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; padding: 12px 20px; font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4); transition: all 0.3s ease; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; `, MODAL_STYLE: ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); z-index: 10001; display: flex; justify-content: center; align-items: center; `, MODAL_CONTENT_STYLE: ` background: white; border-radius: 12px; padding: 30px; max-width: 500px; width: 90%; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; ` }; const utils = { getPageType() { const url = window.location.href; if (url.includes('/cw/')) return 'recording'; if (url.includes('/ct/')) return 'transcript'; return 'unknown'; }, getMeetingTitle() { // 尝试多种方式获取会议标题 const selectors = [ '.meeting-main-subject .subject', '.meeting-subject', '.meeting-title', '.style_header-info__6mQkP', // 新增选择器 'h1', // 通用标题 ]; for (const sel of selectors) { const el = document.querySelector(sel); if (el) { const text = el.textContent.trim(); // 如果只获取到部分内容(比如"返回"等),继续查找 if (text && text.length > 3 && !text.startsWith('返回')) { return text; } } } // 如果以上都失败,从URL或其他地方获取 const pageTitle = document.title; if (pageTitle && pageTitle !== '腾讯会议') { return pageTitle; } return '腾讯会议转写'; }, getRecordingTime() { // 尝试从页面中提取录制时间 const selectors = [ '.meeting-begin-time-in-date', '.meeting-time', '[class*="time"]', ]; for (const sel of selectors) { const el = document.querySelector(sel); if (el) { const text = el.textContent.trim(); // 匹配时间格式 if (/\d{4}[\/\-]\d{2}[\/\-]\d{2}/.test(text)) { return text.match(/\d{4}[\/\-]\d{2}[\/\-]\d{2}[\s\d\:]*/)[0]; } } } return new Date().toLocaleString('zh-CN'); }, getMeetingKeywords() { const keywords = []; const topicElements = document.querySelectorAll('.topicTag .topicText'); topicElements.forEach(element => { const keyword = element.textContent.trim(); if (keyword) { keywords.push(keyword); } }); return keywords; }, getCurrentTabType() { const pageType = this.getPageType(); if (pageType === 'transcript') return 'both'; const activeTab = document.querySelector('.met-tabs__tabitem.is-active .tab'); if (!activeTab) return 'transcript'; const tabText = activeTab.textContent.trim(); if (tabText.includes('纪要')) return 'summary'; return 'transcript'; }, // 修复后的转写内容获取方法 async getTranscriptContent() { const pageType = this.getPageType(); // 查找虚拟滚动容器 const scrollContainer = document.querySelector('.minutes-module-list'); if (!scrollContainer) { return this.getTranscriptContentFallback(); } // 检查是否需要滚动 if (scrollContainer.scrollHeight <= scrollContainer.clientHeight + 100) { return this.getTranscriptContentFallback(); } const originalScrollTop = scrollContainer.scrollTop; let allContent = new Map(); let lastScrollTop = -1; let stuckCounter = 0; try { // 先滚动到顶部 scrollContainer.scrollTop = 0; await this.sleep(300); // 持续滚动直到底部 while (scrollContainer.scrollTop !== lastScrollTop && stuckCounter < 3) { lastScrollTop = scrollContainer.scrollTop; // 收集当前可见的内容 const paragraphs = document.querySelectorAll('.paragraph-module_detail-page-style__Lhz8l'); paragraphs.forEach(para => { const pid = para.getAttribute('data-pid'); if (!pid || allContent.has(pid)) return; const speakerElement = para.querySelector('.paragraph-module_speaker-name__afSbd'); const timeElement = para.querySelector('.paragraph-module_p-start-time__QAWWl'); const textElement = para.querySelector('.paragraph-module_sentences__zK2oL'); if (textElement && textElement.textContent.trim()) { allContent.set(pid, { pid: parseInt(pid), time: timeElement ? timeElement.textContent.trim() : '', speaker: speakerElement ? speakerElement.textContent.trim() : '未知发言人', text: textElement.textContent.trim() }); } }); // 向下滚动 const newScrollTop = scrollContainer.scrollTop + scrollContainer.clientHeight * 0.8; scrollContainer.scrollTop = newScrollTop; // 等待渲染 await this.sleep(150); // 检查是否卡住 if (scrollContainer.scrollTop === lastScrollTop) { stuckCounter++; // 尝试多滚动一点 scrollContainer.scrollTop += 50; await this.sleep(100); } else { stuckCounter = 0; } } // 恢复原始滚动位置 scrollContainer.scrollTop = originalScrollTop; // 按pid排序 return Array.from(allContent.values()).sort((a, b) => a.pid - b.pid); } catch (error) { console.error('获取转写内容失败:', error); scrollContainer.scrollTop = originalScrollTop; return this.getTranscriptContentFallback(); } }, getTranscriptContentFallback() { const paragraphs = document.querySelectorAll('.paragraph-module_detail-page-style__Lhz8l'); let content = []; paragraphs.forEach(para => { const speakerElement = para.querySelector('.paragraph-module_speaker-name__afSbd'); const timeElement = para.querySelector('.paragraph-module_p-start-time__QAWWl'); const textElement = para.querySelector('.paragraph-module_sentences__zK2oL'); if (textElement && textElement.textContent.trim()) { content.push({ time: timeElement ? timeElement.textContent.trim() : '', speaker: speakerElement ? speakerElement.textContent.trim() : '未知发言人', text: textElement.textContent.trim() }); } }); return content; }, sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }, getSummaryContent() { const pageType = this.getPageType(); if (pageType === 'transcript') { const summaryContainer = document.querySelector('.aisummary-container .summary-content-wrap'); if (!summaryContainer) return null; const elements = summaryContainer.querySelectorAll('h4, p, li'); return Array.from(elements).map(el => ({ type: el.tagName.toLowerCase(), text: el.textContent.trim() })).filter(item => item.text); } const summaryContainer = document.querySelector('.summary-content-wrap'); if (!summaryContainer) return null; const elements = summaryContainer.querySelectorAll('h4, p, li, div[contenteditable="true"]'); return Array.from(elements).map(el => ({ type: el.tagName.toLowerCase(), text: el.textContent.trim() })).filter(item => item.text); }, formatAsMarkdown(data, type) { const title = this.getMeetingTitle(); const recordingTime = this.getRecordingTime(); const keywords = this.getMeetingKeywords(); const exportTime = new Date().toLocaleString('zh-CN'); let markdown = `# ${title}\n\n`; markdown += `**录制时间**: ${recordingTime}\n`; markdown += `**导出时间**: ${exportTime}\n`; markdown += `**内容类型**: ${type === 'transcript' ? '转写内容' : '会议纪要'}\n`; if (keywords.length > 0) { markdown += `**会议关键词**: ${keywords.join('、')}\n`; } markdown += `\n---\n\n`; if (type === 'transcript' && Array.isArray(data)) { markdown += `## 转写内容\n\n`; data.forEach(item => { markdown += `### ${item.speaker}${item.time ? ` (${item.time})` : ''}\n\n`; markdown += `${item.text}\n\n---\n\n`; }); } else if (type === 'summary' && Array.isArray(data)) { markdown += `## 会议纪要\n\n`; data.forEach(item => { if (item.type === 'h4') { markdown += `### ${item.text}\n\n`; } else if (item.type === 'li') { markdown += `- ${item.text}\n`; } else { markdown += `${item.text}\n\n`; } }); } return markdown; }, formatAsHTML(data, type) { const title = this.getMeetingTitle(); const recordingTime = this.getRecordingTime(); const keywords = this.getMeetingKeywords(); const exportTime = new Date().toLocaleString('zh-CN'); let html = `<!DOCTYPE html>\n<html>\n<head>\n`; html += ` <meta charset="UTF-8">\n`; html += ` <meta name="viewport" content="width=device-width, initial-scale=1.0">\n`; html += ` <title>${title}</title>\n`; html += ` <style>\n`; html += ` body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; max-width: 800px; margin: 0 auto; padding: 20px; }\n`; html += ` .header { border-bottom: 2px solid #eee; padding-bottom: 20px; margin-bottom: 30px; }\n`; html += ` .transcript-item { margin-bottom: 20px; padding: 15px; background: #f8f9fa; border-radius: 8px; }\n`; html += ` .speaker { font-weight: bold; color: #2c3e50; }\n`; html += ` .time { color: #7f8c8d; font-size: 0.9em; }\n`; html += ` .content { margin-top: 8px; }\n`; html += ` .keywords { margin: 10px 0; }\n`; html += ` .keyword-tag { display: inline-block; background: #e3f2fd; color: #1976d2; padding: 4px 8px; margin: 2px; border-radius: 4px; font-size: 0.9em; }\n`; html += ` </style>\n</head>\n<body>\n`; html += ` <div>\n`; html += ` <h1>${title}</h1>\n`; html += ` <p><strong>录制时间</strong>: ${recordingTime}</p>\n`; html += ` <p><strong>导出时间</strong>: ${exportTime}</p>\n`; html += ` <p><strong>内容类型</strong>: ${type === 'transcript' ? '转写内容' : '会议纪要'}</p>\n`; if (keywords.length > 0) { html += ` <div>\n`; html += ` <strong>会议关键词</strong>: `; keywords.forEach(keyword => { html += `<span>${keyword}</span>`; }); html += `\n </div>\n`; } html += ` </div>\n`; if (type === 'transcript' && Array.isArray(data)) { html += ` <h2>转写内容</h2>\n`; data.forEach(item => { html += ` <div>\n`; html += ` <div>${item.speaker}${item.time ? ` <span>(${item.time})</span>` : ''}</div>\n`; html += ` <div>${item.text}</div>\n`; html += ` </div>\n`; }); } else if (type === 'summary' && Array.isArray(data)) { html += ` <h2>会议纪要</h2>\n`; data.forEach(item => { if (item.type === 'h4') { html += ` <h3>${item.text}</h3>\n`; } else if (item.type === 'li') { html += ` <li>${item.text}</li>\n`; } else { html += ` <p>${item.text}</p>\n`; } }); } html += `</body>\n</html>`; return html; }, formatAsTXT(data, type) { const title = this.getMeetingTitle(); const recordingTime = this.getRecordingTime(); const keywords = this.getMeetingKeywords(); const exportTime = new Date().toLocaleString('zh-CN'); let txt = `${title}\n`; txt += `${'='.repeat(Math.min(title.length, 50))}\n\n`; txt += `录制时间: ${recordingTime}\n`; txt += `导出时间: ${exportTime}\n`; txt += `内容类型: ${type === 'transcript' ? '转写内容' : '会议纪要'}\n`; if (keywords.length > 0) { txt += `会议关键词: ${keywords.join('、')}\n`; } txt += `\n`; if (type === 'transcript' && Array.isArray(data)) { txt += `转写内容\n${'-'.repeat(10)}\n\n`; data.forEach(item => { txt += `${item.speaker}${item.time ? ` (${item.time})` : ''}\n`; txt += `${item.text}\n\n`; }); } else if (type === 'summary' && Array.isArray(data)) { txt += `会议纪要\n${'-'.repeat(10)}\n\n`; data.forEach(item => { if (item.type === 'h4') { txt += `\n${item.text}\n${'-'.repeat(Math.min(item.text.length, 30))}\n`; } else if (item.type === 'li') { txt += `• ${item.text}\n`; } else { txt += `${item.text}\n\n`; } }); } return txt; }, downloadFile(content, filename, type) { const mimeTypes = { 'md': 'text/markdown', 'html': 'text/html', 'txt': 'text/plain' }; const blob = new Blob(['\ufeff' + content], { type: mimeTypes[type] || 'text/plain' }); // 添加BOM解决中文乱码 const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }, async copyToClipboard(text) { try { await navigator.clipboard.writeText(text); return true; } catch (err) { const textArea = document.createElement('textarea'); textArea.value = text; textArea.style.position = 'fixed'; textArea.style.opacity = '0'; document.body.appendChild(textArea); textArea.select(); const success = document.execCommand('copy'); document.body.removeChild(textArea); return success; } }, showMessage(message, type = 'success') { const existingMsg = document.querySelector('.tm-exporter-message'); if (existingMsg) existingMsg.remove(); const messageDiv = document.createElement('div'); messageDiv.className = 'tm-exporter-message'; const colors = { 'success': '#10b981', 'error': '#ef4444', 'info': '#3b82f6', 'warning': '#f59e0b' }; messageDiv.style.cssText = ` position: fixed; top: 80px; right: 20px; z-index: 10002; padding: 12px 20px; border-radius: 6px; color: white; font-weight: 600; font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); transition: all 0.3s ease; background: ${colors[type] || colors.success}; max-width: 400px; word-wrap: break-word; `; messageDiv.textContent = message; document.body.appendChild(messageDiv); setTimeout(() => { messageDiv.style.opacity = '0'; messageDiv.style.transform = 'translateX(100%)'; setTimeout(() => { if (messageDiv.parentNode) { messageDiv.parentNode.removeChild(messageDiv); } }, 300); }, 3000); } }; class TencentMeetingExporter { constructor() { this.init(); } init() { this.createExportButton(); } createExportButton() { // 移除已存在的按钮 const existingBtn = document.querySelector('.tm-exporter-btn'); if (existingBtn) existingBtn.remove(); const button = document.createElement('button'); button.className = 'tm-exporter-btn'; button.textContent = '📝 导出转写/纪要'; button.style.cssText = CONFIG.BUTTON_STYLE; button.addEventListener('mouseenter', () => { button.style.transform = 'translateY(-2px)'; button.style.boxShadow = '0 6px 20px rgba(102, 126, 234, 0.6)'; }); button.addEventListener('mouseleave', () => { button.style.transform = 'translateY(0)'; button.style.boxShadow = '0 4px 15px rgba(102, 126, 234, 0.4)'; }); button.addEventListener('click', () => { this.showExportModal(); }); document.body.appendChild(button); } showExportModal() { const currentTab = utils.getCurrentTabType(); let modalHTML; if (currentTab === 'both') { modalHTML = ` <h2 style="margin: 0 0 20px 0; color: #2c3e50; font-size: 24px;">导出转写/纪要</h2> <p style="margin: 0 0 25px 0; color: #7f8c8d; line-height: 1.5;">选择要导出的内容类型和格式</p> <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-bottom: 25px;"> <button id="export-transcript-md" style="padding: 15px; border: 2px solid #3498db; background: white; color: #3498db; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">📄 导出转写(MD)</button> <button id="export-summary-md" style="padding: 15px; border: 2px solid #e74c3c; background: white; color: #e74c3c; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">📋 导出纪要(MD)</button> <button id="export-transcript-html" style="padding: 15px; border: 2px solid #f39c12; background: white; color: #f39c12; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">🌐 导出转写(HTML)</button> <button id="export-summary-html" style="padding: 15px; border: 2px solid #9b59b6; background: white; color: #9b59b6; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">🌐 导出纪要(HTML)</button> <button id="export-transcript-txt" style="padding: 15px; border: 2px solid #16a085; background: white; color: #16a085; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">📝 导出转写(TXT)</button> <button id="copy-transcript-md" style="padding: 15px; border: 2px solid #8e44ad; background: white; color: #8e44ad; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">📋 复制转写(MD)</button> </div> <div style="display: flex; justify-content: flex-end; gap: 10px;"> <button id="modal-close" style="padding: 10px 20px; border: 1px solid #bdc3c7; background: white; color: #7f8c8d; border-radius: 6px; cursor: pointer;">取消</button> </div> `; } else { const tabName = currentTab === 'transcript' ? '转写内容' : '会议纪要'; modalHTML = ` <h2 style="margin: 0 0 20px 0; color: #2c3e50; font-size: 24px;">导出${tabName}</h2> <p style="margin: 0 0 25px 0; color: #7f8c8d; line-height: 1.5;">选择导出格式,文件名将自动使用会议标题</p> <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-bottom: 25px;"> <button id="export-md" style="padding: 15px; border: 2px solid #3498db; background: white; color: #3498db; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">📄 Markdown</button> <button id="export-html" style="padding: 15px; border: 2px solid #e74c3c; background: white; color: #e74c3c; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">🌐 HTML</button> <button id="export-txt" style="padding: 15px; border: 2px solid #f39c12; background: white; color: #f39c12; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">📝 TXT</button> <button id="copy-md" style="padding: 15px; border: 2px solid #9b59b6; background: white; color: #9b59b6; border-radius: 8px; cursor: pointer; font-weight: 600; transition: all 0.3s ease;">📋 复制Markdown</button> </div> <div style="display: flex; justify-content: flex-end; gap: 10px;"> <button id="modal-close" style="padding: 10px 20px; border: 1px solid #bdc3c7; background: white; color: #7f8c8d; border-radius: 6px; cursor: pointer;">取消</button> </div> `; } const modal = document.createElement('div'); modal.style.cssText = CONFIG.MODAL_STYLE; const modalContent = document.createElement('div'); modalContent.style.cssText = CONFIG.MODAL_CONTENT_STYLE; modalContent.innerHTML = modalHTML; // 添加按钮悬停效果 const buttons = modalContent.querySelectorAll('button[id^="export-"], button[id^="copy-"]'); buttons.forEach(btn => { btn.addEventListener('mouseenter', () => { btn.style.background = btn.style.color; btn.style.color = 'white'; }); btn.addEventListener('mouseleave', () => { btn.style.background = 'white'; btn.style.color = btn.style.borderColor; }); }); // 绑定事件 if (currentTab === 'both') { modalContent.querySelector('#export-transcript-md')?.addEventListener('click', () => this.exportContent('md', 'transcript')); modalContent.querySelector('#export-summary-md')?.addEventListener('click', () => this.exportContent('md', 'summary')); modalContent.querySelector('#export-transcript-html')?.addEventListener('click', () => this.exportContent('html', 'transcript')); modalContent.querySelector('#export-summary-html')?.addEventListener('click', () => this.exportContent('html', 'summary')); modalContent.querySelector('#export-transcript-txt')?.addEventListener('click', () => this.exportContent('txt', 'transcript')); modalContent.querySelector('#copy-transcript-md')?.addEventListener('click', () => this.copyContent('transcript')); } else { modalContent.querySelector('#export-md')?.addEventListener('click', () => this.exportContent('md')); modalContent.querySelector('#export-html')?.addEventListener('click', () => this.exportContent('html')); modalContent.querySelector('#export-txt')?.addEventListener('click', () => this.exportContent('txt')); modalContent.querySelector('#copy-md')?.addEventListener('click', () => this.copyContent()); } modalContent.querySelector('#modal-close').addEventListener('click', () => this.closeModal(modal)); modal.addEventListener('click', (e) => { if (e.target === modal) { this.closeModal(modal); } }); modal.appendChild(modalContent); document.body.appendChild(modal); } async exportContent(format, contentType = null) { try { const currentTab = utils.getCurrentTabType(); const exportType = contentType || (currentTab === 'both' ? 'transcript' : currentTab); let data; if (exportType === 'transcript') { utils.showMessage('正在获取转写内容,请稍候...', 'info'); data = await utils.getTranscriptContent(); if (!data || data.length === 0) { utils.showMessage('未找到转写内容,请确保页面已加载完成', 'error'); return; } utils.showMessage(`获取成功!共找到 ${data.length} 条转写记录`, 'success'); } else { data = utils.getSummaryContent(); if (!data || data.length === 0) { utils.showMessage('未找到纪要内容,请确保页面已加载完成', 'error'); return; } } const title = utils.getMeetingTitle(); const recordingTime = utils.getRecordingTime(); let timestamp; if (recordingTime) { timestamp = recordingTime.replace(/[^\d]/g, '').slice(0, 14); if (timestamp.length >= 12) { timestamp = timestamp.slice(0, 8) + '_' + timestamp.slice(8); } } else { const now = new Date(); timestamp = now.getFullYear().toString() + (now.getMonth() + 1).toString().padStart(2, '0') + now.getDate().toString().padStart(2, '0') + '_' + now.getHours().toString().padStart(2, '0') + now.getMinutes().toString().padStart(2, '0') + now.getSeconds().toString().padStart(2, '0'); } const tabName = exportType === 'transcript' ? '转写' : '纪要'; // 清理文件名中的特殊字符 const safeTitle = title.replace(/[\\/:*?"<>|]/g, '_'); const filename = `${safeTitle}_${tabName}_${timestamp}.${format}`; let content; switch (format) { case 'md': content = utils.formatAsMarkdown(data, exportType); break; case 'html': content = utils.formatAsHTML(data, exportType); break; case 'txt': content = utils.formatAsTXT(data, exportType); break; } utils.downloadFile(content, filename, format); utils.showMessage(`${format.toUpperCase()}文件导出成功!`); const modal = document.querySelector('div[style*="position: fixed"][style*="z-index: 10001"]'); if (modal) this.closeModal(modal); } catch (error) { console.error('导出失败:', error); utils.showMessage('导出失败:' + error.message, 'error'); } } async copyContent(contentType = null) { try { const currentTab = utils.getCurrentTabType(); const exportType = contentType || (currentTab === 'both' ? 'transcript' : currentTab); let data; if (exportType === 'transcript') { utils.showMessage('正在获取转写内容,请稍候...', 'info'); data = await utils.getTranscriptContent(); if (!data || data.length === 0) { utils.showMessage('未找到转写内容,请确保页面已加载完成', 'error'); return; } utils.showMessage(`获取成功!共找到 ${data.length} 条转写记录`, 'success'); } else { data = utils.getSummaryContent(); if (!data || data.length === 0) { utils.showMessage('未找到纪要内容,请确保页面已加载完成', 'error'); return; } } const content = utils.formatAsMarkdown(data, exportType); const success = await utils.copyToClipboard(content); if (success) { utils.showMessage('Markdown内容已复制到剪贴板!'); } else { utils.showMessage('复制失败,请重试', 'error'); } const modal = document.querySelector('div[style*="position: fixed"][style*="z-index: 10001"]'); if (modal) this.closeModal(modal); } catch (error) { console.error('复制失败:', error); utils.showMessage('复制失败:' + error.message, 'error'); } } closeModal(modal) { modal.style.opacity = '0'; setTimeout(() => { if (modal.parentNode) { modal.parentNode.removeChild(modal); } }, 300); } } // 页面加载完成后初始化 function init() { // 先检查页面是否包含转写内容 const checkInterval = setInterval(() => { const hasContent = document.querySelector('.minutes-module-list'); if (hasContent) { clearInterval(checkInterval); new TencentMeetingExporter(); } }, 500); // 最多等待10秒 setTimeout(() => { clearInterval(checkInterval); if (!document.querySelector('.tm-exporter-btn')) { new TencentMeetingExporter(); } }, 10000); } init();})(); |