初始化版本

This commit is contained in:
LL
2025-11-18 14:18:28 +08:00
commit 3c348195b7
23 changed files with 2837 additions and 0 deletions

107
api/save_video.php Normal file
View File

@@ -0,0 +1,107 @@
<?php
// 保存视频到本地并清理超过2天的旧视频第三天自动清除第一天的视频
header('Content-Type: application/json; charset=utf-8');
function respond($ok, $message = '', $path = '') {
echo json_encode(['success' => $ok, 'message' => $message, 'path' => $path], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
exit;
}
// 递归删除目录及其内容(用于清理旧视频)
function rrmdir($dir) {
if (!is_dir($dir)) return;
$items = @scandir($dir);
if ($items === false) return;
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$full = $dir . DIRECTORY_SEPARATOR . $item;
if (is_dir($full)) {
rrmdir($full);
} else {
@unlink($full);
}
}
@rmdir($dir);
}
// 读取JSON输入
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
$url = $data['url'] ?? '';
$title = $data['title'] ?? '';
if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
respond(false, 'URL无效');
}
// 只允许 http/https
$scheme = parse_url($url, PHP_URL_SCHEME);
if (!in_array(strtolower($scheme), ['http','https'])) {
respond(false, '仅支持http/https视频地址');
}
$videosRoot = __DIR__ . '/../videos';
if (!is_dir($videosRoot)) {
@mkdir($videosRoot, 0777, true);
}
$today = (new DateTime('now'))->format('Y-m-d');
$targetDir = $videosRoot . '/' . $today;
if (!is_dir($targetDir)) {
@mkdir($targetDir, 0777, true);
}
// 生成文件名
$basename = basename(parse_url($url, PHP_URL_PATH) ?: 'video_' . time() . '.mp4');
if (strpos($basename, '.') === false) { $basename .= '.mp4'; }
$safeName = preg_replace('/[^\w\.-]+/u', '_', $basename);
$targetPath = $targetDir . '/' . $safeName;
// 如果文件已存在则跳过下载
$skipDownload = file_exists($targetPath);
$msg = '保存成功';
if ($skipDownload) {
$msg = '文件已存在,跳过下载';
} else {
// 下载保存
try {
$read = @fopen($url, 'rb');
if (!$read) { respond(false, '无法读取远程视频'); }
$write = @fopen($targetPath, 'wb');
if (!$write) { respond(false, '无法写入文件'); }
stream_copy_to_stream($read, $write);
fclose($read);
fclose($write);
} catch (Throwable $e) {
respond(false, '保存失败: ' . $e->getMessage());
}
}
// 恢复清理逻辑:仅保留最近两天的视频目录,删除更早的目录
try {
$dirs = @scandir($videosRoot);
if (is_array($dirs)) {
// 仅筛选形如 YYYY-MM-DD 的目录
$dateDirs = [];
foreach ($dirs as $d) {
if ($d === '.' || $d === '..') continue;
$path = $videosRoot . DIRECTORY_SEPARATOR . $d;
if (is_dir($path) && preg_match('/^\d{4}-\d{2}-\d{2}$/', $d)) {
$dateDirs[] = $d;
}
}
// 按日期升序排序
sort($dateDirs);
// 保留最近两天(末尾两项),其它全部删除
if (count($dateDirs) > 30) {
$toDelete = array_slice($dateDirs, 0, count($dateDirs) - 2);
foreach ($toDelete as $del) {
rrmdir($videosRoot . DIRECTORY_SEPARATOR . $del);
}
}
}
} catch (Throwable $e) {
// 清理失败不影响主流程
}
respond(true, $msg, str_replace($_SERVER['DOCUMENT_ROOT'], '', $targetPath));