Spaces:
Sleeping
Sleeping
<html lang="es"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Extractor de URLs m3u8</title> | |
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> | |
<style> | |
body { | |
padding: 20px; | |
} | |
#results { | |
margin-top: 20px; | |
} | |
.loading { | |
display: none; | |
margin-top: 15px; | |
} | |
.url-item { | |
display: flex; | |
align-items: center; | |
margin-bottom: 10px; | |
} | |
.url-text { | |
flex-grow: 1; | |
overflow-x: auto; | |
padding: 8px; | |
border: 1px solid #dee2e6; | |
border-radius: 4px; | |
margin-right: 10px; | |
} | |
.player-link { | |
margin-left: 10px; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1 class="mt-4 mb-4">Extractor de URLs m3u8</h1> | |
<div class="row"> | |
<div class="col-md-12"> | |
<div class="card"> | |
<div class="card-body"> | |
<form id="extractForm"> | |
<div class="mb-3"> | |
<label for="url" class="form-label">URL de la página</label> | |
<input type="url" class="form-control" id="url" placeholder="https://ejemplo.com" required> | |
</div> | |
<div class="mb-3"> | |
<label for="waitTime" class="form-label">Tiempo de espera (segundos)</label> | |
<input type="number" class="form-control" id="waitTime" value="10" min="1" max="60"> | |
</div> | |
<div class="mb-3"> | |
<label for="headers" class="form-label">Headers personalizados (uno por línea, formato "Key: Value")</label> | |
<textarea class="form-control" id="headers" rows="3" placeholder="User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Referer: https://ejemplo.com"></textarea> | |
</div> | |
<button type="submit" class="btn btn-primary">Extraer URLs</button> | |
</form> | |
<div class="loading text-center" id="loading"> | |
<div class="spinner-border text-primary" role="status"> | |
<span class="visually-hidden">Cargando...</span> | |
</div> | |
<p class="mt-2">Extrayendo URLs, por favor espera...</p> | |
</div> | |
<div id="results" class="mt-4"> | |
<!-- Los resultados se mostrarán aquí --> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
document.getElementById('extractForm').addEventListener('submit', async function(e) { | |
e.preventDefault(); | |
const url = document.getElementById('url').value; | |
const waitTime = document.getElementById('waitTime').value; | |
const headers = document.getElementById('headers').value; | |
document.getElementById('loading').style.display = 'block'; | |
document.getElementById('results').innerHTML = ''; | |
try { | |
const response = await fetch('/extract', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ | |
url: url, | |
wait_time: waitTime, | |
headers: headers | |
}) | |
}); | |
const data = await response.json(); | |
if (data.success) { | |
let resultsHtml = ''; | |
if (data.urls.length > 0) { | |
resultsHtml = ` | |
<h4>URLs encontradas:</h4> | |
<div class="list-group"> | |
`; | |
data.urls.forEach(function(url) { | |
resultsHtml += ` | |
<div class="url-item"> | |
<div class="url-text">${url}</div> | |
<button class="btn btn-sm btn-success copy-btn" data-url="${url}">Copiar</button> | |
<a href="${url}" target="_blank" class="player-link btn btn-sm btn-info">Abrir</a> | |
<a href="vlc://${url}" class="player-link btn btn-sm btn-secondary">VLC</a> | |
</div> | |
`; | |
}); | |
resultsHtml += '</div>'; | |
} else { | |
resultsHtml = '<div class="alert alert-warning">No se encontraron URLs m3u8.</div>'; | |
} | |
document.getElementById('results').innerHTML = resultsHtml; | |
// Agregar funcionalidad a los botones de copiar | |
document.querySelectorAll('.copy-btn').forEach(function(button) { | |
button.addEventListener('click', function() { | |
const url = this.getAttribute('data-url'); | |
navigator.clipboard.writeText(url).then(function() { | |
const originalText = button.textContent; | |
button.textContent = 'Copiado!'; | |
button.classList.replace('btn-success', 'btn-secondary'); | |
setTimeout(function() { | |
button.textContent = originalText; | |
button.classList.replace('btn-secondary', 'btn-success'); | |
}, 2000); | |
}); | |
}); | |
}); | |
} else { | |
document.getElementById('results').innerHTML = ` | |
<div class="alert alert-danger"> | |
Error: ${data.error} | |
</div> | |
`; | |
} | |
} catch (error) { | |
document.getElementById('results').innerHTML = ` | |
<div class="alert alert-danger"> | |
Error al procesar la solicitud: ${error.message} | |
</div> | |
`; | |
} finally { | |
document.getElementById('loading').style.display = 'none'; | |
} | |
}); | |
</script> | |
</body> | |
</html> |