原生HTML的SRT字幕净化工具
公告:铁柱资源网为用户提供最新的原创技术教程,还有电脑技巧以及其他日常信息 游戏资讯等 让我们的生活更加精彩有乐趣!铁柱网原先域名:qq8m.com,部分地区打不开,新域名:qq8m.com,qq8m.com,qq8m.com重要的事情说三遍
铁柱资源网网站源码原生HTML的SRT字幕净化工具

原生HTML的SRT字幕净化工具

网站源码傲轩小编2026-03-16 11:45:401.54 KA+A-
原生HTML的SRT字幕净化工具

对于srt字幕文件,可以去除其中的行号、时间、格式、空行,仅保留字幕文本。
代码:

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>SRT字幕净化工具</title>    <style>        * {            box-sizing: border-box;            margin: 0;            padding: 0;            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;        }                 body {            background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);            color: #333;            min-height: 100vh;            padding: 20px;            display: flex;            justify-content: center;            align-items: center;        }                 .container {            width: 100%;            max-width: 900px;            background-color: rgba(255, 255, 255, 0.95);            border-radius: 16px;            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);            overflow: hidden;        }                 header {            background: linear-gradient(90deg, #4b6cb7, #182848);            color: white;            padding: 25px 30px;            text-align: center;            position: relative;        }                 h1 {            font-size: 2.2rem;            margin-bottom: 10px;        }                 .subtitle {            font-size: 1.1rem;            opacity: 0.9;            max-width: 600px;            margin: 0 auto;            line-height: 1.5;        }                 .main-content {            padding: 30px;        }                 .upload-area {            border: 3px dashed #4b6cb7;            border-radius: 12px;            padding: 40px 20px;            text-align: center;            background-color: #f8f9ff;            transition: all 0.3s ease;            margin-bottom: 30px;            position: relative;        }                 .upload-area:hover, .upload-area.dragover {            background-color: #eef2ff;            border-color: #182848;        }                 .upload-icon {            font-size: 60px;            color: #4b6cb7;            margin-bottom: 15px;        }                 .upload-text {            font-size: 1.2rem;            margin-bottom: 20px;            color: #444;        }                 .file-input {            display: none;        }                 .btn {            background: linear-gradient(90deg, #4b6cb7, #182848);            color: white;            border: none;            padding: 12px 30px;            font-size: 1.1rem;            border-radius: 50px;            cursor: pointer;            transition: all 0.3s ease;            display: inline-flex;            align-items: center;            justify-content: center;            gap: 8px;            box-shadow: 0 4px 10px rgba(75, 108, 183, 0.3);        }                 .btn:hover {            transform: translateY(-3px);            box-shadow: 0 6px 15px rgba(75, 108, 183, 0.4);        }                 .btn:active {            transform: translateY(1px);        }                 .options-section {            background-color: #f0f7ff;            border-radius: 12px;            padding: 20px;            margin-bottom: 25px;            border: 1px solid #d0e3ff;        }                 .option-title {            font-size: 1.2rem;            color: #182848;            margin-bottom: 15px;            display: flex;            align-items: center;            gap: 10px;        }                 .option-item {            display: flex;            align-items: center;            margin: 10px 0;        }                 .option-item input[type="checkbox"] {            width: 20px;            height: 20px;            margin-right: 10px;            accent-color: #4b6cb7;        }                 .option-item label {            font-size: 1rem;            color: #444;        }                 .result-container {            display: none;            margin-top: 30px;            animation: fadeIn 0.5s ease;        }                 @keyframes fadeIn {            from { opacity: 0; transform: translateY(20px); }            to { opacity: 1; transform: translateY(0); }        }                 .section-title {            font-size: 1.4rem;            color: #182848;            margin-bottom: 15px;            padding-bottom: 10px;            border-bottom: 2px solid #eaeaea;            display: flex;            align-items: center;            gap: 10px;        }                 .content-box {            background-color: #f8f9ff;            border-radius: 10px;            padding: 20px;            height: 250px;            overflow-y: auto;            margin-bottom: 20px;            border: 1px solid #e0e0e0;            line-height: 1.6;            white-space: pre-wrap;            font-family: monospace;            font-size: 0.95rem;        }                 .stats {            display: flex;            justify-content: space-between;            background-color: #eef7ff;            padding: 12px 15px;            border-radius: 8px;            margin-bottom: 20px;            font-size: 0.9rem;            color: #4b6cb7;        }                 .stat-item {            display: flex;            flex-direction: column;            align-items: center;        }                 .stat-value {            font-weight: bold;            font-size: 1.2rem;            color: #182848;        }                 .action-buttons {            display: flex;            gap: 15px;            flex-wrap: wrap;        }                 .btn-download {            background: linear-gradient(90deg, #11998e, #38ef7d);        }                 .btn-copy {            background: linear-gradient(90deg, #ff416c, #ff4b2b);        }                 .btn-new {            background: linear-gradient(90deg, #4b6cb7, #182848);        }                 .file-info {            margin-top: 15px;            font-size: 0.9rem;            color: #666;            padding: 10px;            background-color: #f0f7ff;            border-radius: 8px;        }                 .example {            background-color: #eef7ff;            border-left: 4px solid #4b6cb7;            padding: 15px;            margin: 20px 0;            border-radius: 0 8px 8px 0;        }                 .example h3 {            color: #182848;            margin-bottom: 10px;            display: flex;            align-items: center;            gap: 10px;        }                 .example-content {            font-family: monospace;            white-space: pre-line;            font-size: 0.9rem;            background-color: white;            padding: 10px;            border-radius: 6px;            margin-top: 10px;        }                 .status {            padding: 12px;            border-radius: 8px;            margin: 15px 0;            text-align: center;            display: none;            font-weight: 500;        }                 .status.success {            background-color: #d4edda;            color: #155724;            display: block;        }                 .status.error {            background-color: #f8d7da;            color: #721c24;            display: block;        }                 .status.info {            background-color: #cce5ff;            color: #004085;            display: block;        }                 footer {            text-align: center;            padding: 20px;            color: #777;            font-size: 0.9rem;            border-top: 1px solid #eee;            background-color: #f8f9ff;        }                 .preview-toggle {            display: flex;            justify-content: center;            margin: 15px 0;        }                 .toggle-btn {            background: #eef2ff;            border: 1px solid #d0e3ff;            padding: 8px 20px;            cursor: pointer;            transition: all 0.3s ease;        }                 .toggle-btn:first-child {            border-radius: 20px 0 0 20px;        }                 .toggle-btn:last-child {            border-radius: 0 20px 20px 0;        }                 .toggle-btn.active {            background: linear-gradient(90deg, #4b6cb7, #182848);            color: white;            border-color: #4b6cb7;        }                 [url=home.php?mod=space&uid=945662]@media[/url] (max-width: 768px) {            .container {                margin: 10px;            }             
            header {                padding: 20px 15px;            }             
            .logo {                position: static;                margin: 0 auto 15px;            }             
            h1 {                font-size: 1.8rem;            }             
            .main-content {                padding: 20px 15px;            }             
            .action-buttons {                flex-direction: column;            }             
            .btn {                width: 100%;            }             
            .stats {                flex-direction: column;                gap: 15px;            }             
            .stat-item {                flex-direction: row;                justify-content: space-between;                width: 100%;            }        }    </style></head><body>    <div class="container">        <header>            <h1>SRT字幕净化工具</h1>            <p class="subtitle">上传SRT字幕文件,自动去除序号、时间码和格式代码,仅保留纯文本内容</p>        </header>                 <div class="main-content">            <div class="upload-area" id="dropArea">                <div class="upload-icon">&#128196;</div>                <p class="upload-text">拖放SRT文件到此处,或点击下方按钮选择文件</p>                <input type="file" id="fileInput" class="file-input" accept=".srt">                <label for="fileInput" class="btn">                    &#128193; 选择SRT文件                </label>                <div class="file-info" id="fileInfo"></div>                <div class="status" id="statusMessage"></div>            </div>                        <div class="options-section">                <h3 class="option-title">&#9881;&#65039; 处理选项</h3>                <div class="option-item">                    <input type="checkbox" id="removeEmptyLines" checked>                    <label for="removeEmptyLines">删除所有空行(包括字幕块之间的空行)</label>                </div>                <div class="option-item">                    <input type="checkbox" id="removeHtmlTags" checked>                    <label for="removeHtmlTags">移除HTML标签(如<b>, <i>, <u>等)</label>                </div>                <div class="option-item">                    <input type="checkbox" id="mergeShortLines">                    <label for="mergeShortLines">合并每段字幕中的短行(少于15个字符的行)</label>                </div>            </div>                        <div class="example">                <h3>&#128161; 格式示例</h3>                <div class="example-content">原始SRT格式:100:00:01,000 --> 00:00:04,000<b>你好,世界!</b>200:00:05,000 --> 00:00:08,000欢迎使用字幕清理工具它可以去除所有格式代码300:00:09,000 --> 00:00:12,000处理完成后,您可以下载或复制结果</div>            </div>                        <div class="result-container" id="resultContainer">                <h2 class="section-title">&#128203; 处理结果</h2>                                 <div class="stats">                    <div class="stat-item">                        <span>原始行数</span>                        <span class="stat-value" id="originalLines">0</span>                    </div>                    <div class="stat-item">                        <span>清理后行数</span>                        <span class="stat-value" id="cleanedLines">0</span>                    </div>                    <div class="stat-item">                        <span>字符数</span>                        <span class="stat-value" id="charCount">0</span>                    </div>                    <div class="stat-item">                        <span>处理时间</span>                        <span class="stat-value" id="processTime">0ms</span>                    </div>                </div>                                 <div class="preview-toggle">                    <div class="toggle-btn active" data-preview="cleaned">清理后内容</div>                    <div class="toggle-btn" data-preview="original">原始内容预览</div>                </div>                                 <h3>清理后的字幕内容</h3>                <div class="content-box" id="cleanedContent"></div>                                 <div class="action-buttons">                    <button class="btn btn-download" id="downloadBtn">                        &#11015;&#65039; 下载清理后的文本                    </button>                    <button class="btn btn-copy" id="copyBtn">                        &#9112; 复制到剪贴板                    </button>                    <button class="btn btn-new" id="newFileBtn">                        &#8635; 处理新文件                    </button>                </div>            </div>        </div>                 <footer>            <p>SRT字幕净化工具 &#169; 2026</p>        </footer>    </div>    <script>        document.addEventListener('DOMContentLoaded', function() {            const fileInput = document.getElementById('fileInput');            const dropArea = document.getElementById('dropArea');            const fileInfo = document.getElementById('fileInfo');            const statusMessage = document.getElementById('statusMessage');            const resultContainer = document.getElementById('resultContainer');            const cleanedContent = document.getElementById('cleanedContent');            const downloadBtn = document.getElementById('downloadBtn');            const copyBtn = document.getElementById('copyBtn');            const newFileBtn = document.getElementById('newFileBtn');            const removeEmptyLines = document.getElementById('removeEmptyLines');            const removeHtmlTags = document.getElementById('removeHtmlTags');            const mergeShortLines = document.getElementById('mergeShortLines');            const toggleButtons = document.querySelectorAll('.toggle-btn');             
            let currentFile = null;            let cleanedText = '';            let originalContent = '';            let startTime = 0;             
            // 文件选择处理            fileInput.addEventListener('change', function(e) {                if (e.target.files.length > 0) {                    handleFile(e.target.files[0]);                }            });             
            // 拖放功能            ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {                dropArea.addEventListener(eventName, preventDefaults, false);            });             
            function preventDefaults(e) {                e.preventDefault();                e.stopPropagation();            }             
            ['dragenter', 'dragover'].forEach(eventName => {                dropArea.addEventListener(eventName, highlight, false);            });             
            ['dragleave', 'drop'].forEach(eventName => {                dropArea.addEventListener(eventName, unhighlight, false);            });             
            function highlight() {                dropArea.classList.add('dragover');            }             
            function unhighlight() {                dropArea.classList.remove('dragover');            }             
            dropArea.addEventListener('drop', function(e) {                const dt = e.dataTransfer;                const file = dt.files[0];                if (file && file.name.endsWith('.srt')) {                    handleFile(file);                } else {                    showStatus('请上传有效的SRT文件', 'error');                }            });             
            // 处理文件            function handleFile(file) {                if (!file.name.endsWith('.srt')) {                    showStatus('请上传SRT格式的文件', 'error');                    return;                }                                 currentFile = file;                fileInfo.textContent = `已选择: ${file.name} (${(file.size / 1024).toFixed(2)} KB)`;                fileInfo.style.color = '#4CAF50';                hideStatus();                                 startTime = performance.now();                                 const reader = new FileReader();                reader.onload = function(e) {                    try {                        originalContent = e.target.result;                        cleanedText = cleanSRT(originalContent);                         
                        const processTime = Math.round(performance.now() - startTime);                        updateStats(originalContent, cleanedText, processTime);                         
                        displayResults(cleanedText);                        showStatus('文件处理成功!', 'success');                    } catch (error) {                        showStatus(`处理文件时出错: ${error.message}`, 'error');                        console.error(error);                    }                };                reader.onerror = function() {                    showStatus('读取文件失败', 'error');                };                reader.readAsText(file);            }             
            // 修复后的SRT清理函数(处理各种格式)            function cleanSRT(srtContent) {                const removeHtml = removeHtmlTags.checked;                const deleteEmpty = removeEmptyLines.checked;                const mergeLines = mergeShortLines.checked;                                 // 分割字幕块(兼容有无空行的情况)                const blocks = [];                let currentBlock = [];                const lines = srtContent.split(/\r?\n/);                                 for (let i = 0; i < lines.length; i++) {                    const line = lines[i].trim();                                         // 检查是否为序号行(只包含数字)                    if (/^\d+$/.test(line)) {                        // 保存前一个块(如果有内容)                        if (currentBlock.length > 0) {                            blocks.push(currentBlock.join('\n'));                            currentBlock = [];                        }                        continue;                    }                                         // 检查是否为时间码行(包含 -->)                    if (line.includes('-->')) {                        continue;                    }                                         // 跳过空行(如果设置了删除空行)                    if (line === '') {                        if (!deleteEmpty && currentBlock.length > 0) {                            blocks.push(currentBlock.join('\n'));                            currentBlock = [];                        }                        continue;                    }                                         // 移除HTML标签(如果设置了移除HTML)                    let cleanLine = line;                    if (removeHtml) {                        cleanLine = line.replace(/<[^>]*>/g, '');                    }                                         // 添加到当前块                    if (cleanLine !== '') {                        currentBlock.push(cleanLine);                    }                }                                 // 添加最后一个块                if (currentBlock.length > 0) {                    blocks.push(currentBlock.join('\n'));                }                                 // 修复合并短行功能                if (mergeLines) {                    for (let i = 0; i < blocks.length; i++) {                        const linesInBlock = blocks[i].split('\n');                        const mergedLines = [];                        let currentMerge = '';                         
                        for (let j = 0; j < linesInBlock.length; j++) {                            const line = linesInBlock[j].trim();                                                         if (line === '') continue;                                                         // 如果当前行是短行(少于15个字符)                            if (line.length < 15) {                                if (currentMerge === '') {                                    currentMerge = line;                                } else {                                    currentMerge += ' ' + line;                                }                            } else {                                // 当前行不是短行                                if (currentMerge !== '') {                                    mergedLines.push(currentMerge);                                    currentMerge = '';                                }                                mergedLines.push(line);                            }                        }                         
                        // 处理最后剩余的合并行                        if (currentMerge !== '') {                            mergedLines.push(currentMerge);                        }                         
                        blocks[i] = mergedLines.join('\n');                    }                }                                 // 根据选项决定是否删除空行                let result;                if (deleteEmpty) {                    result = blocks.join('\n');                } else {                    result = blocks.join('\n\n');                }                                 return result;            }             
            // 更新统计信息            function updateStats(original, cleaned, time) {                const origLines = original.split(/\r?\n/).length;                const cleanedLines = cleaned.split(/\n/).length;                const charCount = cleaned.length;                                 document.getElementById('originalLines').textContent = origLines;                document.getElementById('cleanedLines').textContent = cleanedLines;                document.getElementById('charCount').textContent = charCount;                document.getElementById('processTime').textContent = time + 'ms';            }             
            // 显示结果            function displayResults(text) {                cleanedContent.textContent = text;                resultContainer.style.display = 'block';            }             
            // 下载功能            downloadBtn.addEventListener('click', function() {                if (!cleanedText) return;                                 const blob = new Blob([cleanedText], { type: 'text/plain' });                const url = URL.createObjectURL(blob);                                 const a = document.createElement('a');                a.href = url;                a.download = currentFile ? 
                    currentFile.name.replace('.srt', '_cleaned.txt') : 
                    'cleaned_subtitles.txt';                document.body.appendChild(a);                a.click();                                 setTimeout(() => {                    document.body.removeChild(a);                    window.URL.revokeObjectURL(url);                }, 0);            });             
            // 复制功能            copyBtn.addEventListener('click', function() {                if (!cleanedText) return;                                 navigator.clipboard.writeText(cleanedText)                    .then(() => {                        const originalText = copyBtn.innerHTML;                        copyBtn.innerHTML = '&#10003; 已复制!';                        showStatus('内容已复制到剪贴板', 'success');                        setTimeout(() => {                            copyBtn.innerHTML = originalText;                        }, 2000);                    })                    .catch(err => {                        console.error('复制失败:', err);                        showStatus('复制失败,请手动选择文本复制', 'error');                    });            });             
            // 处理新文件            newFileBtn.addEventListener('click', function() {                fileInput.value = '';                fileInfo.textContent = '';                resultContainer.style.display = 'none';                cleanedText = '';                originalContent = '';                currentFile = null;                hideStatus();            });             
            // 预览切换            toggleButtons.forEach(button => {                button.addEventListener('click', function() {                    toggleButtons.forEach(btn => btn.classList.remove('active'));                    this.classList.add('active');                                         if (this.dataset.preview === 'original') {                        cleanedContent.textContent = originalContent;                    } else {                        cleanedContent.textContent = cleanedText;                    }                });            });             
            // 状态消息显示            function showStatus(message, type) {                statusMessage.textContent = message;                statusMessage.className = 'status ' + type;            }             
            function hideStatus() {                statusMessage.style.display = 'none';            }             
            // 初始示例显示            showStatus('请上传SRT字幕文件进行处理', 'info');        });    </script></body></html>复制代码


点击这里复制本文地址 以上内容由铁柱网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!


扫码关注“铁柱网”微信公众号
更多精彩,等你来撩

有好的文章或资源希望【铁柱网】帮助分享推广,猛戳这里我要投稿

支持Ctrl+Enter提交
qrcode

铁柱资源网 © All Rights Reserved.  

嘿,欢迎咨询
请先 登录 再评论,若不是会员请先 注册