Files
MoYuBan/upload.php
2025-11-18 14:18:28 +08:00

132 lines
4.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// 投稿页面:允许用户上传视频,上传内容进入待审核目录 videos_pending
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>投稿视频</title>
<link rel="stylesheet" href="assets/style.css" />
</head>
<body>
<div class="page">
<header class="menu">
<div class="menu__logo">投稿</div>
<nav aria-label="主菜单">
<ul class="menu__nav">
<li><a class="menu__link" href="index.php">返回首页</a></li>
</ul>
</nav>
</header>
<main class="upload-container" aria-label="投稿表单">
<h1>上传你想分享的视频</h1>
<form class="upload-grid video" action="api/upload_video.php" method="post" enctype="multipart/form-data">
<div class="field">
<label>选择视频文件(支持 mp4 / webm / mov</label>
<div id="dropzone" class="dropzone" role="button" aria-label="拖拽或点击选择文件">
拖拽文件到此处,或点击选择文件
</div>
<input id="videoFile" class="hidden-input" type="file" name="video" accept="video/mp4,video/webm,video/quicktime" required />
</div>
<div class="field">
<label>标题(可选)</label>
<input id="titleInput" type="text" name="title" placeholder="给你的投稿起个标题" />
<div class="actions">
<button class="btn" type="submit">提交投稿</button>
<a href="review.php" style="font-size:12px;color:#666;">管理员审核入口</a>
</div>
</div>
<aside class="card">
<video id="preview" class="video-preview" controls style="display:none"></video>
<div id="meta" class="meta"></div>
<div id="errors" class="errors"></div>
</aside>
<p class="tips">说明投稿后文件会进入“待审核”队列管理员审核通过后才会出现在播放列表中。单个视频大小限制50MB。</p>
</form>
</main>
</div>
<script>
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('videoFile');
const preview = document.getElementById('preview');
const meta = document.getElementById('meta');
const errors = document.getElementById('errors');
const titleInput = document.getElementById('titleInput');
const allowedExt = ['mp4','webm','mov'];
const SIZE_LIMIT = 50 * 1024 * 1024; // 50MB
function formatSize(bytes){
if (bytes >= 1024*1024*1024) return (bytes/1024/1024/1024).toFixed(2) + ' GB';
if (bytes >= 1024*1024) return (bytes/1024/1024).toFixed(2) + ' MB';
if (bytes >= 1024) return (bytes/1024).toFixed(2) + ' KB';
return bytes + ' B';
}
function setFile(file){
if (!file) return;
// 填充到 input
const dt = new DataTransfer();
dt.items.add(file);
fileInput.files = dt.files;
// 校验扩展名
const name = file.name || '';
const ext = name.split('.').pop().toLowerCase();
errors.textContent = '';
if (!allowedExt.includes(ext)) {
errors.textContent = '仅支持 mp4 / webm / mov 格式文件';
fileInput.value = '';
preview.style.display = 'none';
preview.removeAttribute('src');
meta.textContent = '';
return;
}
// 校验大小
if (file.size > SIZE_LIMIT) {
errors.textContent = '文件过大:超过 50MB 限制';
fileInput.value = '';
preview.style.display = 'none';
preview.removeAttribute('src');
meta.textContent = '';
return;
}
// 自动填充标题
if (!titleInput.value) {
const base = name.replace(/\.[^.]+$/, '');
titleInput.value = base;
}
// 预览视频
const url = URL.createObjectURL(file);
preview.src = url;
preview.style.display = 'block';
preview.load();
meta.textContent = '文件:' + name + ',大小:' + formatSize(file.size) + (file.type ? ',类型:' + file.type : '');
preview.onloadedmetadata = () => {
const d = preview.duration;
if (isFinite(d) && d > 0) {
meta.textContent += ',时长:' + Math.round(d) + ' 秒';
}
};
}
dropzone.addEventListener('click', () => fileInput.click());
dropzone.addEventListener('dragover', (e) => { e.preventDefault(); dropzone.classList.add('dragging'); });
dropzone.addEventListener('dragleave', () => dropzone.classList.remove('dragging'));
dropzone.addEventListener('drop', (e) => {
e.preventDefault(); dropzone.classList.remove('dragging');
const file = e.dataTransfer.files?.[0];
setFile(file);
});
fileInput.addEventListener('change', () => {
const file = fileInput.files?.[0];
setFile(file);
});
</script>
</body>
</html>