离线网页,选择文件,批量计算MD5(版本V2)
功能
- 支持拖放或选择多个文件
- 实时显示文件处理进度条
- 生成每个文件的MD5哈希值
- 将所有结果以JSON格式输出
- 提供一键复制功能 工具采用美观的渐变背景设计,支持大文件分块处理,使用SparkMD5库计算MD5值,并显示处理进度。用户可方便地查看和复制文件校验信息。
效果展示
源码
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>视频文件MD5生成工具</title><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"><style>* {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}body {background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);color: #333;min-height: 100vh;padding: 20px;display: flex;justify-content: center;align-items: center;}.container {max-width: 1000px;width: 100%;background: rgba(255, 255, 255, 0.95);border-radius: 15px;box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);overflow: hidden;}header {background: linear-gradient(90deg, #1a2a6c, #b21f1f);color: white;padding: 25px 40px;text-align: center;}.content {padding: 30px;}.upload-area {border: 3px dashed #1a2a6c;border-radius: 10px;padding: 40px 20px;text-align: center;background: #f8f9fa;transition: all 0.3s;margin-bottom: 30px;}.upload-area.active {background: #e9f5ff;border-color: #2196F3;}.file-list {margin-top: 20px;}.file-item {background: #f0f5ff;border-radius: 8px;padding: 15px;margin-bottom: 10px;display: grid;grid-template-columns: 2fr 1fr 2fr 100px;gap: 15px;align-items: center;}.progress-bar {width: 100%;height: 4px;background: #e0e0e0;border-radius: 2px;overflow: hidden;margin-top: 5px;}.progress-bar .progress {width: 0%;height: 100%;background: #1a2a6c;transition: width 0.3s ease;}.status {font-size: 12px;color: #666;margin-top: 3px;}.file-item:hover {background: #e6f0ff;}.copy-btn {background: #1a2a6c;color: white;border: none;padding: 8px 15px;border-radius: 4px;cursor: pointer;transition: background 0.3s;}.copy-btn:hover {background: #b21f1f;}.json-output {margin-top: 20px;background: #1a2a6c;color: #fff;padding: 20px;border-radius: 8px;position: relative;}.json-output pre {white-space: pre-wrap;word-wrap: break-word;margin: 0;font-family: monospace;}.copy-json-btn {position: absolute;top: 10px;right: 10px;background: #fff;color: #1a2a6c;border: none;padding: 8px 15px;border-radius: 4px;cursor: pointer;transition: background 0.3s;}.copy-json-btn:hover {background: #e6e6e6;}.btn {background: linear-gradient(to right, #1a2a6c, #b21f1f);color: white;border: none;padding: 15px 40px;font-size: 1.2rem;border-radius: 50px;cursor: pointer;transition: all 0.3s;margin: 10px;}.btn:hover {transform: translateY(-2px);box-shadow: 0 5px 15px rgba(0,0,0,0.2);}</style>
</head>
<body><div class="container"><header><h1>视频文件MD5生成工具</h1><p>支持多文件处理,自动生成JSON格式</p></header><div class="content"><div class="upload-area" id="uploadArea"><input type="file" id="fileInput" multiple style="display: none;"><button class="btn" onclick="document.getElementById('fileInput').click()"><i class="fas fa-file-upload"></i> 选择文件</button><p>或将文件拖放到此处</p></div><div class="file-list" id="fileList"></div><div class="json-output" id="jsonOutput" style="display: none;"><button class="copy-json-btn" onclick="copyJsonToClipboard()"><i class="fas fa-copy"></i> 复制JSON</button><pre id="jsonContent"></pre></div></div></div><script src="https://cdnjs.cloudflare.com/ajax/libs/spark-md5/3.0.2/spark-md5.min.js"></script><script>let processedFiles = [];let isProcessing = false;let fileQueue = [];function initializeUpload() {const uploadArea = document.getElementById('uploadArea');const fileInput = document.getElementById('fileInput');uploadArea.addEventListener('dragover', (e) => {e.preventDefault();uploadArea.classList.add('active');});uploadArea.addEventListener('dragleave', () => {uploadArea.classList.remove('active');});uploadArea.addEventListener('drop', (e) => {e.preventDefault();uploadArea.classList.remove('active');handleFiles(e.dataTransfer.files);});fileInput.addEventListener('change', () => {handleFiles(fileInput.files);});}function handleFiles(files) {Array.from(files).forEach(file => {fileQueue.push(file);});if (!isProcessing) {processNextFile();}}async function processNextFile() {if (fileQueue.length === 0) {isProcessing = false;return;}isProcessing = true;const file = fileQueue.shift();await processFile(file);processNextFile();}function processFile(file) {return new Promise((resolve) => {const fileItem = createFileItemElement(file);document.getElementById('fileList').appendChild(fileItem);calculateMD5WithProgress(file, fileItem, (md5) => {const fileInfo = {FileName: file.name,Size: file.size,MD5Hash: md5};updateFileItem(fileItem, fileInfo);processedFiles.push(fileInfo);updateJsonOutput();resolve();});});}function createFileItemElement(file) {const div = document.createElement('div');div.className = 'file-item';div.innerHTML = `<div><div class="file-name">${file.name}</div><div class="progress-bar"><div class="progress"></div></div><div class="status">准备计算MD5...</div></div><div class="file-size">${formatFileSize(file.size)}</div><div class="md5">等待中...</div><button class="copy-btn" disabled>复制MD5</button>`;return div;}function updateFileItem(element, fileInfo) {element.querySelector('.md5').textContent = fileInfo.MD5Hash;const copyBtn = element.querySelector('.copy-btn');copyBtn.disabled = false;copyBtn.onclick = () => copyToClipboard(fileInfo.MD5Hash);}function calculateMD5WithProgress(file, element, callback) {const CHUNK_SIZE = 2097152; // 2MBconst chunks = Math.ceil(file.size / CHUNK_SIZE);const spark = new SparkMD5.ArrayBuffer();let currentChunk = 0;const progressBar = element.querySelector('.progress');const statusText = element.querySelector('.status');function loadNext() {const reader = new FileReader();reader.onload = function(e) {spark.append(e.target.result);currentChunk++;const progress = (currentChunk / chunks) * 100;progressBar.style.width = `${progress}%`;statusText.textContent = `正在计算: ${Math.round(progress)}%`;if (currentChunk < chunks) {loadNext();} else {const md5 = spark.end();statusText.textContent = '计算完成';callback(md5);}};const start = currentChunk * CHUNK_SIZE;const end = Math.min(start + CHUNK_SIZE, file.size);const chunk = file.slice(start, end);reader.readAsArrayBuffer(chunk);}loadNext();}function updateJsonOutput() {const jsonOutput = document.getElementById('jsonOutput');const jsonContent = document.getElementById('jsonContent');jsonOutput.style.display = 'block';jsonContent.textContent = JSON.stringify(processedFiles, null, 2);}function copyToClipboard(text) {navigator.clipboard.writeText(text).then(() => {// 可以添加复制成功的提示});}function copyJsonToClipboard() {const json = JSON.stringify(processedFiles, null, 2);navigator.clipboard.writeText(json).then(() => {const btn = document.querySelector('.copy-json-btn');const originalText = btn.innerHTML;btn.innerHTML = '<i class="fas fa-check"></i> 已复制';setTimeout(() => {btn.innerHTML = originalText;}, 2000);});}function formatFileSize(bytes) {const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];if (bytes === 0) return '0 Bytes';const i = Math.floor(Math.log(bytes) / Math.log(1024));return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + ' ' + sizes[i];}// 初始化initializeUpload();</script>
</body>
</html>
一键三联
点赞·留言·收藏
如果可以帮到你,好用的话,记得一键三连。
毕竟博主写文章是靠爱发电,所以爱会消失对不对。