ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

HTML视频审核模型

HTML视频审核模型 这是一段HTML代码实现了本地视频上传和审核状态实时追踪方便您快速测试审核流程。html!DOCTYPE htmlhtml langzh-CNheadmeta charsetUTF-8 /meta nameviewport contentwidthdevice-width, initial-scale1 /title视频上传审核/titlestylebody {font-family: -apple-system, PingFang SC, Microsoft YaHei, sans-serif;max-width: 560px;margin: 60px auto;padding: 0 20px;color: #333;}h2 { margin-bottom: 24px; }.box {border: 2px dashed #d0d7de;border-radius: 10px;padding: 28px;text-align: center;transition: border-color .2s;}.box.dragover { border-color: #1f6feb; background: #f0f6ff; }input[typefile] { display: none; }.pick {display: inline-block;padding: 9px 22px;background: #1f6feb;color: #fff;border-radius: 6px;cursor: pointer;font-size: 14px;}.pick:hover { background: #1858c4; }.filename {margin-top: 14px;font-size: 13px;color: #666;word-break: break-all;}progress {width: 100%;height: 10px;margin-top: 20px;border-radius: 5px;display: none;}progress::-webkit-progress-bar { background: #eaeef2; border-radius: 5px; }progress::-webkit-progress-value { background: #1f6feb; border-radius: 5px; transition: width .2s; }#status {margin-top: 18px;font-size: 14px;min-height: 22px;line-height: 1.6;}.tag {display: inline-block;padding: 2px 10px;border-radius: 20px;font-size: 12px;margin-right: 6px;}.s-pending { background: #fff8e5; color: #b7791f; }.s-reviewing { background: #e7f0ff; color: #1f6feb; }.s-approved { background: #e6f7ec; color: #1a7f37; }.s-rejected { background: #ffeceb; color: #cf222e; }.s-failed { background: #f0f0f0; color: #666; }/style/headbodyh2上传视频自动送审/h2div classbox iddropboxlabel classpick forfile选择视频文件/labelinput typefile idfile acceptvideo/mp4,video/quicktime,video/webm /div classfilename idfilename支持 mp4 / mov / webm单文件 ≤ 500MB/divprogress idprogress max100 value0/progress/divdiv idstatus/divscriptconst STATUS_TEXT {pending: 待审核,reviewing: 审核中,approved: 审核通过,rejected: 审核未通过,failed: 处理失败};const fileInput document.getElementById(file);const filenameEl document.getElementById(filename);const progressEl document.getElementById(progress);const statusEl document.getElementById(status);const dropbox document.getElementById(dropbox);let pollTimer null;/* ---------- 文件选择 ---------- */fileInput.addEventListener(change, () {const file fileInput.files[0];if (!file) return;filenameEl.textContent ${file.name} (${(file.size / 1024 / 1024).toFixed(1)} MB);statusEl.innerHTML ;progressEl.style.display none;progressEl.value 0;});/* ---------- 拖拽上传 ---------- */[dragenter, dragover].forEach(ev dropbox.addEventListener(ev, e {e.preventDefault();dropbox.classList.add(dragover);}));[dragleave, drop].forEach(ev dropbox.addEventListener(ev, e {e.preventDefault();dropbox.classList.remove(dragover);}));dropbox.addEventListener(drop, e {const file e.dataTransfer.files[0];if (!file) return;fileInput.files e.dataTransfer.files;fileInput.dispatchEvent(new Event(change));startUpload();});/* ---------- 选择后自动开始上传 ---------- */fileInput.addEventListener(change, () {if (fileInput.files[0]) startUpload();});/* ---------- 上传 ---------- */function startUpload() {const file fileInput.files[0];if (!file) return;// 前端预校验减少无效请求if (!file.type.startsWith(video/)) {statusEl.innerHTML span classtag s-rejected错误/span请选择视频文件;return;}if (file.size 500 * 1024 * 1024) {statusEl.innerHTML span classtag s-rejected错误/span文件超过 500MB;return;}const formData new FormData();formData.append(video, file);const xhr new XMLHttpRequest();xhr.open(POST, /api/videos/upload);progressEl.style.display block;statusEl.innerHTML span classtag s-pending上传中/span正在上传文件…;// 上传进度xhr.upload.onprogress e {if (e.lengthComputable) {const percent Math.round((e.loaded / e.total) * 100);progressEl.value percent;statusEl.innerHTML span classtag s-pending上传中/span${percent}%;}};xhr.onload () {let res;try { res JSON.parse(xhr.responseText); }catch { return (statusEl.innerHTML span classtag s-failed失败/span响应解析错误); }if (xhr.status ! 200 || res.code ! 0) {statusEl.innerHTML span classtag s-failed失败/span${res.msg || 上传失败};return;}progressEl.value 100;statusEl.innerHTML span classtag s-reviewing审核中/span上传成功正在审核…;pollStatus(res.data.id);};xhr.onerror () {statusEl.innerHTML span classtag s-failed失败/span网络错误请重试;};xhr.ontimeout () {statusEl.innerHTML span classtag s-failed失败/span上传超时;};xhr.send(formData);}/* ---------- 轮询审核状态 ---------- */function pollStatus(id) {clearInterval(pollTimer);let retries 0;const MAX_RETRIES 150; // 最多轮询 5 分钟const check async () {if (retries MAX_RETRIES) {clearInterval(pollTimer);statusEl.innerHTML span classtag s-failed超时/span审核结果查询超时请稍后刷新;return;}try {const resp await fetch(/api/videos/${id}/status);const json await resp.json();if (json.code ! 0) return;const { status, reason } json.data;const cls s-${status};const text STATUS_TEXT[status] || status;let html span classtag ${cls}${text}/span;if (reason) html span stylecolor:#cf222e${reason}/span;if (status approved) html 视频已发布;if (status rejected) html 请联系管理员申诉;statusEl.innerHTML html;// 终态则停止轮询if ([approved, rejected, failed].includes(status)) {clearInterval(pollTimer);progressEl.style.display none;}} catch (err) {console.warn(轮询失败, err);}};check();pollTimer setInterval(check, 2000);}/script/body/html上传、审核与反馈流程整个页面围绕“选视频-传视频-看进度-等审核”这条线展开操作反馈很直接。· 选择与拖拽点击“选择视频文件”或直接把视频拖进虚线框都能触发上传选中后立刻显示文件名和大小。· 前端校验上传前会检查文件类型和大小只有视频文件且不超过500MB才会继续避免无效请求。· 上传进度进度条实时展示上传百分比状态标签同步提示“上传中”。· 审核轮询上传成功后自动开始每2秒查询一次审核状态审核通过显示“已发布”未通过会展示原因并提示联系管理员。· 状态可视待审核、审核中、通过、拒绝、失败等状态用不同颜色标签区分一目了然。---优化建议 可将代码中的后端上传接口地址/api/videos/upload替换为实际服务端地址并根据需要调整500MB的文件大小限制。文章仅供参考用。
返回列表