Last active
April 15, 2025 14:52
-
-
Save samuelloza/df3c0934c7bb55beabb18d0ffae2edb7 to your computer and use it in GitHub Desktop.
Wistia downloader to run execute python3 -m http.server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="es"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Descargar Wistia Videos Manualmente</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
} | |
table { | |
border-collapse: collapse; | |
width: 100%; | |
} | |
th, | |
td { | |
border: 1px solid #999; | |
padding: 6px; | |
vertical-align: top; | |
} | |
input[type="text"] { | |
width: 100%; | |
box-sizing: border-box; | |
} | |
.hidden { | |
display: none; | |
} | |
</style> | |
</head> | |
<body> | |
<h2>Lista de Videos (Wistia)</h2> | |
<table> | |
<thead> | |
<tr> | |
<th>Nombre de archivo</th> | |
<th>HTML Wistia</th> | |
<th>Nombre original</th> | |
</tr> | |
</thead> | |
<tbody id="videoTable"></tbody> | |
</table> | |
<br> | |
<button onclick="processAll()">Descargar Videos Seleccionados</button> | |
<script> | |
function sanitizeFilename(filename) { | |
return filename.replace(/[<>:"\/\\|?*]+/g, ""); | |
} | |
function extractAndPopulateOptions(htmlInput, id) { | |
let parser = new DOMParser(); | |
let decodedHtml = parser.parseFromString(htmlInput, "text/html").body.innerHTML; | |
let match = decodedHtml.match(/wvideo=([a-zA-Z0-9_-]+)/); | |
if (!match) { | |
alert(`Fila ${id + 1}: HTML inválido`); | |
return; | |
} | |
let extractedValue = match[1]; | |
let embedUrl = `https://fast.wistia.net/embed/iframe/${extractedValue}`; | |
fetch(embedUrl) | |
.then(response => { | |
if (!response.ok) throw new Error("No se pudo obtener el video."); | |
return response.text(); | |
}) | |
.then(data => { | |
let titleMatch = data.match(/<title>(.*?)<\/title>/); | |
let extractedVideoTitle = titleMatch ? titleMatch[1] : `Video${id}`; | |
//document.getElementById(`video-name${id}`).value = sanitizeFilename(extractedVideoTitle); | |
let binFiles = data.match(/https?:\/\/[^"\s]+(?:\.bin|\.mp4)/g); | |
if (!binFiles || binFiles.length <= 2) { | |
alert(`Fila ${id + 1}: No se encontraron videos válidos.`); | |
return; | |
} | |
binFiles = binFiles.slice(0, -2).map(url => url.replace(".bin", ".mp4")); | |
// Encontrar el video más pesado | |
let maxSize = 0; | |
let bestUrl = ""; | |
let pending = binFiles.length; | |
binFiles.forEach(url => { | |
fetch(url, { method: "HEAD" }).then(resp => { | |
let size = parseInt(resp.headers.get("content-length") || "0"); | |
if (size > maxSize) { | |
maxSize = size; | |
bestUrl = url; | |
} | |
}).catch(() => { | |
// continuar aunque falle uno | |
}).finally(() => { | |
pending--; | |
if (pending === 0) { | |
document.getElementById(`video-select${id}`).value = bestUrl; | |
} | |
}); | |
}); | |
}) | |
.catch(error => { | |
alert(`Fila ${id + 1}: Error al procesar - ${error.message}`); | |
}); | |
} | |
function downloadViaForm(fileUrl, filename) { | |
fetch(fileUrl) | |
.then(response => { | |
if (!response.ok) throw new Error("No se pudo descargar el archivo."); | |
return response.blob(); | |
}) | |
.then(blob => { | |
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); | |
}) | |
.catch(err => { | |
console.error("Error al descargar el archivo:", err); | |
alert("Hubo un problema al descargar el archivo."); | |
}); | |
} | |
function processAll() { | |
for (let i = 0; i < 20; i++) { | |
const name = document.getElementById(`video-name${i}`).value.trim(); | |
const url = document.getElementById(`video-select${i}`).value.trim(); | |
if (name && url && url.startsWith("http")) { | |
const filename = sanitizeFilename(name) + ".mp4"; | |
downloadViaForm(url, filename); | |
} | |
} | |
alert("Descarga iniciada para todos los videos con URL válida."); | |
} | |
// Crear 20 filas | |
for (let i = 0; i < 20; i++) { | |
const tr = document.createElement("tr"); | |
const tdName = document.createElement("td"); | |
const inputName = document.createElement("input"); | |
inputName.type = "text"; | |
inputName.id = `video-name${i}`; | |
tdName.appendChild(inputName); | |
const tdHtml = document.createElement("td"); | |
const inputHtml = document.createElement("input"); | |
inputHtml.type = "text"; | |
inputHtml.id = `video-html${i}`; | |
tdHtml.appendChild(inputHtml); | |
const tdResult = document.createElement("td"); | |
const inputResult = document.createElement("input"); | |
inputResult.type = "text"; | |
inputResult.id = `video-select${i}`; | |
tdResult.appendChild(inputResult); | |
inputHtml.addEventListener("change", () => { | |
extractAndPopulateOptions(inputHtml.value, i); | |
}); | |
tr.appendChild(tdName); | |
tr.appendChild(tdHtml); | |
tr.appendChild(tdResult); | |
document.getElementById("videoTable").appendChild(tr); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment