初始化版本
This commit is contained in:
107
api/save_video.php
Normal file
107
api/save_video.php
Normal 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));
|
||||
Reference in New Issue
Block a user