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

108 lines
3.3 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
// 保存视频到本地并清理超过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));