| <!DOCTYPE html> |
| <html lang="pt-BR"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Conversor Avançado de Texto para SRT com Terminação em Pontos</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| @keyframes fadeIn { |
| from { opacity: 0; transform: translateY(10px); } |
| to { opacity: 1; transform: translateY(0); } |
| } |
| @keyframes slideIn { |
| from { transform: translateX(100%); } |
| to { transform: translateX(0); } |
| } |
| @keyframes pulse { |
| 0%, 100% { opacity: 1; } |
| 50% { opacity: 0.5; } |
| } |
| @keyframes rotate { |
| from { transform: rotate(0deg); } |
| to { transform: rotate(360deg); } |
| } |
| .fade-in { |
| animation: fadeIn 0.5s ease-out forwards; |
| } |
| .slide-in { |
| animation: slideIn 0.3s ease-out forwards; |
| } |
| .pulse { |
| animation: pulse 2s infinite; |
| } |
| .rotate { |
| animation: rotate 2s linear infinite; |
| } |
| .text-area-container { |
| position: relative; |
| } |
| .char-count { |
| position: absolute; |
| right: 10px; |
| bottom: 10px; |
| background: rgba(255, 255, 255, 0.8); |
| padding: 2px 8px; |
| border-radius: 10px; |
| font-size: 0.8rem; |
| } |
| .dark .char-count { |
| background: rgba(31, 41, 55, 0.8); |
| color: white; |
| } |
| .progress-bar { |
| height: 4px; |
| background: #e2e8f0; |
| border-radius: 2px; |
| overflow: hidden; |
| } |
| .dark .progress-bar { |
| background: #374151; |
| } |
| .progress-fill { |
| height: 100%; |
| background: #3b82f6; |
| transition: width 0.3s ease; |
| } |
| .srt-block { |
| border-left: 4px solid #3b82f6; |
| transition: all 0.3s ease; |
| } |
| .dark .srt-block { |
| background-color: #1f2937; |
| border-left-color: #60a5fa; |
| } |
| .srt-block:hover { |
| transform: translateX(5px); |
| background-color: #f8fafc; |
| } |
| .dark .srt-block:hover { |
| background-color: #374151; |
| } |
| .copy-btn { |
| opacity: 0; |
| transition: opacity 0.3s ease; |
| } |
| .srt-block:hover .copy-btn { |
| opacity: 1; |
| } |
| .tooltip { |
| position: relative; |
| } |
| .tooltip-text { |
| visibility: hidden; |
| width: 120px; |
| background-color: #333; |
| color: #fff; |
| text-align: center; |
| border-radius: 6px; |
| padding: 5px; |
| position: absolute; |
| z-index: 1; |
| bottom: 125%; |
| left: 50%; |
| margin-left: -60px; |
| opacity: 0; |
| transition: opacity 0.3s; |
| } |
| .dark .tooltip-text { |
| background-color: #111827; |
| } |
| .tooltip:hover .tooltip-text { |
| visibility: visible; |
| opacity: 1; |
| } |
| .tab-content { |
| display: none; |
| } |
| .tab-content.active { |
| display: block; |
| animation: fadeIn 0.5s ease-out; |
| } |
| .image-block { |
| transition: all 0.3s ease; |
| } |
| .image-block:hover { |
| transform: scale(1.02); |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); |
| } |
| .dark .image-block:hover { |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2); |
| } |
| .clock { |
| font-family: 'Courier New', monospace; |
| letter-spacing: 2px; |
| } |
| .dark { |
| background-color: #111827; |
| color: #f3f4f6; |
| } |
| .dark .bg-white { |
| background-color: #1f2937; |
| } |
| .dark .text-gray-800 { |
| color: #f3f4f6; |
| } |
| .dark .text-gray-600 { |
| color: #d1d5db; |
| } |
| .dark .border-gray-300 { |
| border-color: #4b5563; |
| } |
| .dark .bg-gray-200 { |
| background-color: #374151; |
| color: #f3f4f6; |
| } |
| .dark .bg-gray-50 { |
| background-color: #1f2937; |
| } |
| .dark .border-gray-200 { |
| border-color: #374151; |
| } |
| .dark .shadow-md { |
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2); |
| } |
| .dark .shadow-inner { |
| box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.3); |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50 min-h-screen flex flex-col dark:bg-gray-900 transition-colors duration-300"> |
| <div class="container mx-auto px-4 py-8 flex-grow"> |
| <div class="max-w-5xl mx-auto"> |
| |
| <header class="text-center mb-8 fade-in relative"> |
| <div class="absolute top-0 right-0 flex items-center space-x-4"> |
| <div class="clock bg-gray-200 dark:bg-gray-700 px-3 py-1 rounded-md text-sm font-mono"> |
| <span id="hours">00</span>:<span id="minutes">00</span>:<span id="seconds">00</span> |
| </div> |
| <button id="darkModeToggle" class="p-2 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200"> |
| <i class="fas fa-moon dark:hidden"></i> |
| <i class="fas fa-sun hidden dark:inline"></i> |
| </button> |
| </div> |
| <h1 class="text-3xl md:text-4xl font-bold text-gray-800 dark:text-white mb-2"> |
| <i class="fas fa-closed-captioning text-blue-500 mr-2"></i> |
| Conversor de Texto para SRT com Terminação em Pontos |
| </h1> |
| <p class="text-gray-600 dark:text-gray-300">Transforme texto em legendas SRT respeitando a pontuação</p> |
| </header> |
|
|
| |
| <div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden mb-8"> |
| <div class="p-6"> |
| <div class="flex justify-between items-center mb-4"> |
| <h2 class="text-xl font-semibold text-gray-800 dark:text-white"> |
| <i class="fas fa-edit text-blue-500 mr-2"></i> |
| Insira seu texto |
| </h2> |
| <div class="flex space-x-2"> |
| <button id="sampleBtn" type="button" class="px-3 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-md text-sm hover:bg-gray-300 dark:hover:bg-gray-600 transition"> |
| <i class="fas fa-lightbulb mr-1"></i> Exemplo |
| </button> |
| <button id="clearInputBtn" type="button" class="px-3 py-1 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200 rounded-md text-sm hover:bg-gray-300 dark:hover:bg-gray-600 transition"> |
| <i class="fas fa-trash-alt mr-1"></i> Limpar |
| </button> |
| </div> |
| </div> |
|
|
| <div class="text-area-container mb-2"> |
| <textarea id="textoInput" class="w-full h-64 p-4 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 resize-none dark:bg-gray-700 dark:text-white" placeholder="Cole ou digite o texto que deseja converter para formato SRT..."></textarea> |
| <div class="char-count dark:bg-gray-700 dark:text-gray-300"> |
| <span id="charCount">0</span> caracteres | |
| <span id="wordCount">0</span> palavras |
| </div> |
| </div> |
|
|
| <div class="progress-bar mb-4"> |
| <div id="progressFill" class="progress-fill" style="width: 0%"></div> |
| </div> |
|
|
| <div class="flex flex-wrap justify-between items-center"> |
| <div class="mb-4 md:mb-0"> |
| <div class="flex items-center space-x-4"> |
| <div class="flex items-center"> |
| <label for="charsPerBlock" class="mr-2 text-sm text-gray-600 dark:text-gray-300">Caracteres/bloco:</label> |
| <input type="number" id="charsPerBlock" value="490" min="50" max="1000" class="w-20 p-1 border border-gray-300 dark:border-gray-600 rounded text-sm dark:bg-gray-700 dark:text-white"> |
| </div> |
| <div class="flex items-center"> |
| <label for="blockDuration" class="mr-2 text-sm text-gray-600 dark:text-gray-300">Duração (s):</label> |
| <input type="number" id="blockDuration" value="50" min="1" max="120" class="w-16 p-1 border border-gray-300 dark:border-gray-600 rounded text-sm dark:bg-gray-700 dark:text-white"> |
| </div> |
| <div class="flex items-center"> |
| <input type="checkbox" id="endOnPeriod" checked class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"> |
| <label for="endOnPeriod" class="ml-2 text-sm text-gray-600 dark:text-gray-300">Terminar em pontos</label> |
| </div> |
| </div> |
| </div> |
| <button id="convertBtn" type="button" class="px-6 py-3 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition flex items-center"> |
| <i class="fas fa-exchange-alt mr-2"></i> Converter para SRT |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="resultsSection" class="hidden"> |
| <div class="flex justify-between items-center mb-4"> |
| <h2 class="text-xl font-semibold text-gray-800 dark:text-white"> |
| <i class="fas fa-file-alt text-green-500 mr-2"></i> |
| Legendas SRT Geradas |
| </h2> |
| <div class="flex space-x-2"> |
| <button id="downloadBtn" class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition flex items-center"> |
| <i class="fas fa-download mr-2"></i> Baixar SRT |
| </button> |
| <button id="copyAllBtn" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition flex items-center"> |
| <i class="fas fa-copy mr-2"></i> Copiar Tudo |
| </button> |
| </div> |
| </div> |
|
|
| <div class="bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg p-4 mb-4"> |
| <div class="flex justify-between items-center mb-3"> |
| <div class="text-sm text-gray-600 dark:text-gray-300"> |
| <span id="blockCount">0</span> blocos gerados | |
| <span id="totalDuration">00:00:00</span> de duração total | |
| <span id="totalWords">0</span> palavras |
| </div> |
| <div class="flex items-center"> |
| <label for="fontSize" class="mr-2 text-sm text-gray-600 dark:text-gray-300">Tamanho:</label> |
| <select id="fontSize" class="p-1 border border-gray-300 dark:border-gray-600 rounded text-sm bg-white dark:bg-gray-700 dark:text-white"> |
| <option value="text-sm">Pequeno</option> |
| <option value="text-base" selected>Normal</option> |
| <option value="text-lg">Grande</option> |
| </select> |
| </div> |
| </div> |
|
|
| <div id="resultado" class="space-y-4"></div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <footer class="bg-white dark:bg-gray-800 py-4 shadow-inner"> |
| <div class="container mx-auto px-4 text-center text-gray-600 dark:text-gray-300 text-sm"> |
| <p>© 2023 Conversor SRT Avançado | Desenvolvido por <a href="#" class="text-blue-600 dark:text-blue-400 hover:underline">Renatim Dark</a></p> |
| <div class="flex justify-center space-x-4 mt-2"> |
| <a href="#" class="hover:text-blue-600 dark:hover:text-blue-400"><i class="fab fa-github"></i></a> |
| <a href="#" class="hover:text-blue-600 dark:hover:text-blue-400"><i class="fab fa-twitter"></i></a> |
| <a href="#" class="hover:text-blue-600 dark:hover:text-blue-400"><i class="fab fa-linkedin"></i></a> |
| </div> |
| </div> |
| </footer> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', function() { |
| |
| const textoInput = document.getElementById('textoInput'); |
| const convertBtn = document.getElementById('convertBtn'); |
| const resultado = document.getElementById('resultado'); |
| const downloadBtn = document.getElementById('downloadBtn'); |
| const clearInputBtn = document.getElementById('clearInputBtn'); |
| const sampleBtn = document.getElementById('sampleBtn'); |
| const copyAllBtn = document.getElementById('copyAllBtn'); |
| const resultsSection = document.getElementById('resultsSection'); |
| const charCount = document.getElementById('charCount'); |
| const wordCount = document.getElementById('wordCount'); |
| const blockCount = document.getElementById('blockCount'); |
| const totalDuration = document.getElementById('totalDuration'); |
| const totalWords = document.getElementById('totalWords'); |
| const progressFill = document.getElementById('progressFill'); |
| const charsPerBlock = document.getElementById('charsPerBlock'); |
| const blockDuration = document.getElementById('blockDuration'); |
| const fontSize = document.getElementById('fontSize'); |
| const darkModeToggle = document.getElementById('darkModeToggle'); |
| const endOnPeriod = document.getElementById('endOnPeriod'); |
| const hoursElement = document.getElementById('hours'); |
| const minutesElement = document.getElementById('minutes'); |
| const secondsElement = document.getElementById('seconds'); |
| |
| |
| const sampleText = `Este é um exemplo de texto que será convertido para o formato SRT. O formato SRT é usado para legendas em vídeos e cada bloco contém: |
| |
| 1. Um número sequencial |
| 2. O tempo de início e fim no formato HH:MM:SS,mmm |
| 3. O texto da legenda |
| 4. Uma linha em branco para separar os blocos |
| |
| Você pode editar este texto ou apagá-lo para inserir o seu próprio conteúdo. O conversor irá dividir automaticamente o texto em blocos de acordo com as configurações de caracteres por bloco e duração. Cada bloco será terminado no ponto final mais próximo do limite de caracteres, garantindo que as frases não sejam cortadas no meio.`; |
| |
| |
| updateCounts(); |
| updateClock(); |
| setInterval(updateClock, 1000); |
| checkDarkModePreference(); |
| |
| |
| textoInput.addEventListener('input', updateCounts); |
| sampleBtn.addEventListener('click', insertSampleText); |
| clearInputBtn.addEventListener('click', clearInput); |
| convertBtn.addEventListener('click', convertToSRT); |
| downloadBtn.addEventListener('click', downloadSRT); |
| copyAllBtn.addEventListener('click', copyAllSRT); |
| fontSize.addEventListener('change', changeFontSize); |
| darkModeToggle.addEventListener('click', toggleDarkMode); |
| |
| |
| function updateClock() { |
| const now = new Date(); |
| hoursElement.textContent = now.getHours().toString().padStart(2, '0'); |
| minutesElement.textContent = now.getMinutes().toString().padStart(2, '0'); |
| secondsElement.textContent = now.getSeconds().toString().padStart(2, '0'); |
| } |
| |
| function checkDarkModePreference() { |
| if (localStorage.getItem('darkMode') === 'enabled' || |
| (!localStorage.getItem('darkMode') && window.matchMedia('(prefers-color-scheme: dark)').matches)) { |
| document.body.classList.add('dark'); |
| } |
| } |
| |
| function toggleDarkMode() { |
| document.body.classList.toggle('dark'); |
| |
| if (document.body.classList.contains('dark')) { |
| localStorage.setItem('darkMode', 'enabled'); |
| } else { |
| localStorage.setItem('darkMode', 'disabled'); |
| } |
| } |
| |
| function countWords(text) { |
| if (!text.trim()) return 0; |
| return text.trim().split(/\s+/).length; |
| } |
| |
| function updateCounts() { |
| const text = textoInput.value; |
| const charCountValue = text.length; |
| const wordCountValue = countWords(text); |
| |
| charCount.textContent = charCountValue.toLocaleString(); |
| wordCount.textContent = wordCountValue.toLocaleString(); |
| |
| |
| const maxChars = 1000000; |
| const percentage = Math.min((charCountValue / maxChars) * 100, 100); |
| progressFill.style.width = `${percentage}%`; |
| |
| |
| if (percentage > 90) { |
| progressFill.style.backgroundColor = '#ef4444'; |
| } else if (percentage > 70) { |
| progressFill.style.backgroundColor = '#f59e0b'; |
| } else { |
| progressFill.style.backgroundColor = '#3b82f6'; |
| } |
| } |
| |
| function insertSampleText() { |
| textoInput.value = sampleText; |
| updateCounts(); |
| animateButton(sampleBtn); |
| } |
| |
| function clearInput() { |
| textoInput.value = ''; |
| updateCounts(); |
| resultsSection.classList.add('hidden'); |
| animateButton(clearInputBtn); |
| } |
| |
| function formatTime(seconds) { |
| const date = new Date(seconds * 1000); |
| const hours = date.getUTCHours().toString().padStart(2, '0'); |
| const minutes = date.getUTCMinutes().toString().padStart(2, '0'); |
| const secs = date.getUTCSeconds().toString().padStart(2, '0'); |
| const ms = date.getUTCMilliseconds().toString().padStart(3, '0').substring(0, 3); |
| return `${hours}:${minutes}:${secs},${ms}`; |
| } |
| |
| function formatBlockSRT(counter, start, text) { |
| return `${counter}\n${formatTime(start)} --> ${formatTime(start + parseInt(blockDuration.value))}\n${text.trim()}\n\n`; |
| } |
| |
| function convertToSRT() { |
| const text = textoInput.value.trim(); |
| if (!text) { |
| showAlert('Por favor, insira algum texto para converter.', 'error'); |
| return; |
| } |
| |
| animateButton(convertBtn); |
| |
| |
| convertBtn.disabled = true; |
| convertBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Processando...'; |
| |
| setTimeout(() => { |
| try { |
| const srtBlocks = []; |
| let counter = 1; |
| let startTime = 0; |
| const intervalBetweenBlocks = 5; |
| const maxChars = parseInt(charsPerBlock.value) || 490; |
| const duration = parseInt(blockDuration.value) || 50; |
| const shouldEndOnPeriod = endOnPeriod.checked; |
| |
| if (shouldEndOnPeriod) { |
| |
| const sentences = splitIntoSentences(text); |
| |
| |
| let currentBlock = ''; |
| let currentBlockLength = 0; |
| |
| for (const sentence of sentences) { |
| if (currentBlockLength + sentence.length <= maxChars) { |
| currentBlock += sentence + ' '; |
| currentBlockLength += sentence.length + 1; |
| } else { |
| if (currentBlock.trim()) { |
| srtBlocks.push({ |
| counter, |
| startTime, |
| text: currentBlock.trim(), |
| html: formatBlockSRT(counter, startTime, currentBlock.trim()) |
| }); |
| counter++; |
| startTime += duration + intervalBetweenBlocks; |
| } |
| |
| currentBlock = sentence + ' '; |
| currentBlockLength = sentence.length + 1; |
| } |
| } |
| |
| |
| if (currentBlock.trim()) { |
| srtBlocks.push({ |
| counter, |
| startTime, |
| text: currentBlock.trim(), |
| html: formatBlockSRT(counter, startTime, currentBlock.trim()) |
| }); |
| } |
| } else { |
| |
| const words = text.split(/\s+/); |
| let block = ''; |
| let blockLength = 0; |
| |
| for (const word of words) { |
| if (blockLength + word.length <= maxChars) { |
| block += word + ' '; |
| blockLength += word.length + 1; |
| } else { |
| if (block.trim()) { |
| srtBlocks.push({ |
| counter, |
| startTime, |
| text: block.trim(), |
| html: formatBlockSRT(counter, startTime, block.trim()) |
| }); |
| counter++; |
| startTime += duration + intervalBetweenBlocks; |
| } |
| |
| block = word + ' '; |
| blockLength = word.length + 1; |
| } |
| } |
| |
| |
| if (block.trim()) { |
| srtBlocks.push({ |
| counter, |
| startTime, |
| text: block.trim(), |
| html: formatBlockSRT(counter, startTime, block.trim()) |
| }); |
| } |
| } |
| |
| displaySRTResults(srtBlocks, countWords(text)); |
| } catch (error) { |
| console.error('Error during conversion:', error); |
| showAlert('Ocorreu um erro durante a conversão.', 'error'); |
| } finally { |
| convertBtn.disabled = false; |
| convertBtn.innerHTML = '<i class="fas fa-exchange-alt mr-2"></i> Converter para SRT'; |
| } |
| }, 500); |
| } |
| |
| function splitIntoSentences(text) { |
| |
| const sentenceRegex = /[^.!?]*[.!?](?:\s|$)/g; |
| const sentences = []; |
| let match; |
| |
| while ((match = sentenceRegex.exec(text)) !== null) { |
| sentences.push(match[0].trim()); |
| } |
| |
| |
| const remainingText = text.substring(sentenceRegex.lastIndex).trim(); |
| if (remainingText) { |
| sentences.push(remainingText); |
| } |
| |
| return sentences; |
| } |
| |
| function displaySRTResults(blocks, totalWordCount) { |
| resultado.innerHTML = ''; |
| blockCount.textContent = blocks.length; |
| totalWords.textContent = totalWordCount.toLocaleString(); |
| |
| |
| const lastBlock = blocks[blocks.length - 1]; |
| const totalSecs = lastBlock.startTime + parseInt(blockDuration.value); |
| totalDuration.textContent = formatTime(totalSecs).split(',')[0]; |
| |
| blocks.forEach(block => { |
| const blockElement = document.createElement('div'); |
| blockElement.className = `srt-block bg-white dark:bg-gray-700 p-4 rounded-lg shadow-sm ${fontSize.value}`; |
| blockElement.innerHTML = ` |
| <div class="flex justify-between items-start mb-2"> |
| <span class="font-mono text-sm text-gray-500 dark:text-gray-400">Bloco ${block.counter} | ${formatTime(block.startTime)} → ${formatTime(block.startTime + parseInt(blockDuration.value))} | ${countWords(block.text)} palavras</span> |
| <button class="copy-btn px-2 py-1 bg-gray-100 dark:bg-gray-600 text-gray-600 dark:text-gray-300 rounded text-sm hover:bg-gray-200 dark:hover:bg-gray-500 tooltip" data-text="${escapeHtml(block.text)}"> |
| <i class="fas fa-copy"></i> |
| <span class="tooltip-text">Copiar bloco</span> |
| </button> |
| </div> |
| <div class="whitespace-pre-wrap dark:text-gray-300">${block.text}</div> |
| `; |
| resultado.appendChild(blockElement); |
| }); |
| |
| |
| document.querySelectorAll('.copy-btn').forEach(btn => { |
| btn.addEventListener('click', function() { |
| const text = this.getAttribute('data-text'); |
| copyToClipboard(text); |
| showAlert('Bloco copiado!', 'success'); |
| animateButton(this); |
| }); |
| }); |
| |
| resultsSection.classList.remove('hidden'); |
| window.scrollTo({ |
| top: resultsSection.offsetTop - 20, |
| behavior: 'smooth' |
| }); |
| } |
| |
| function downloadSRT() { |
| const allBlocks = Array.from(document.querySelectorAll('.srt-block')); |
| let srtContent = ''; |
| |
| allBlocks.forEach((block, index) => { |
| const timeInfo = block.querySelector('span').textContent; |
| const text = block.querySelector('div:last-child').textContent; |
| srtContent += `${index + 1}\n${timeInfo.split(' | ')[1].replace(' → ', ' --> ')}\n${text}\n\n`; |
| }); |
| |
| const blob = new Blob([srtContent], { type: 'text/plain' }); |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = 'legendas.srt'; |
| document.body.appendChild(a); |
| a.click(); |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| |
| showAlert('Arquivo SRT baixado!', 'success'); |
| animateButton(downloadBtn); |
| } |
| |
| function copyAllSRT() { |
| const allBlocks = Array.from(document.querySelectorAll('.srt-block')); |
| let srtContent = ''; |
| |
| allBlocks.forEach((block, index) => { |
| const timeInfo = block.querySelector('span').textContent; |
| const text = block.querySelector('div:last-child').textContent; |
| srtContent += `${index + 1}\n${timeInfo.split(' | ')[1].replace(' → ', ' --> ')}\n${text}\n\n`; |
| }); |
| |
| copyToClipboard(srtContent); |
| showAlert('Todo o conteúdo SRT copiado!', 'success'); |
| animateButton(copyAllBtn); |
| } |
| |
| function changeFontSize() { |
| const blocks = document.querySelectorAll('.srt-block'); |
| blocks.forEach(block => { |
| block.classList.remove('text-sm', 'text-base', 'text-lg'); |
| block.classList.add(fontSize.value); |
| }); |
| } |
| |
| |
| function escapeHtml(unsafe) { |
| return unsafe |
| .replace(/&/g, "&") |
| .replace(/</g, "<") |
| .replace(/>/g, ">") |
| .replace(/"/g, """) |
| .replace(/'/g, "'"); |
| } |
| |
| function copyToClipboard(text) { |
| const textarea = document.createElement('textarea'); |
| textarea.value = text; |
| document.body.appendChild(textarea); |
| textarea.select(); |
| document.execCommand('copy'); |
| document.body.removeChild(textarea); |
| } |
| |
| function showAlert(message, type) { |
| const alert = document.createElement('div'); |
| alert.className = `fixed top-4 right-4 px-4 py-2 rounded-md shadow-lg text-white ${ |
| type === 'error' ? 'bg-red-500' : 'bg-green-500' |
| } animate-bounce`; |
| alert.textContent = message; |
| document.body.appendChild(alert); |
| |
| setTimeout(() => { |
| alert.style.opacity = '0'; |
| setTimeout(() => { |
| document.body.removeChild(alert); |
| }, 300); |
| }, 3000); |
| } |
| |
| function animateButton(button) { |
| button.classList.add('animate-pulse'); |
| setTimeout(() => { |
| button.classList.remove('animate-pulse'); |
| }, 300); |
| } |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=hiojo/srt" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |