diff --git a/server/WebApi.cpp b/server/WebApi.cpp index be3db75b..8a81deff 100644 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -940,50 +940,60 @@ void installWebApi() { CHECK_ARGS("url", "timeout_sec", "expire_sec"); GET_CONFIG(string, snap_root, API::kSnapRoot); + bool have_old_snap = false, res_old_snap = false; int expire_sec = allArgs["expire_sec"]; auto scan_path = File::absolutePath(MD5(allArgs["url"]).hexdigest(), snap_root) + "/"; - string snap_path; + string new_snap = StrPrinter << scan_path << time(NULL) << ".jpeg"; + File::scanDir(scan_path, [&](const string &path, bool isDir) { - if (isDir) { - //忽略文件夹 + if (isDir || !end_with(path, ".jpeg")) { + //忽略文件夹或其他类型的文件 return true; } //找到截图 auto tm = FindField(path.data() + scan_path.size(), nullptr, ".jpeg"); if (atoll(tm.data()) + expire_sec < time(NULL)) { - //截图已经过期,删除之,后面重新生成 - File::delete_file(path.data()); + //截图已经过期,改名,以便再次请求时,可以返回老截图 + rename(path.data(), new_snap.data()); + have_old_snap = true; return true; } - //截图未过期,中断遍历,返回上次生成的截图 - snap_path = path; + //截图存在,且未过期,那么返回之 + res_old_snap = true; + responseSnap(path, headerIn, invoker); + //中断遍历 return false; }); - if(!snap_path.empty()){ - responseSnap(snap_path, headerIn, invoker); + if (res_old_snap) { + //已经回复了旧的截图 return; } //无截图或者截图已经过期 - snap_path = StrPrinter << scan_path << time(NULL) << ".jpeg"; - - //生成一个空文件,目的是顺便创建文件夹路径, - //同时防止在FFmpeg生成截图途中不停的尝试调用该api启动FFmpeg生成相同的截图 - auto file = File::create_file(snap_path.data(), "wb"); - if (file) { - fclose(file); + if (!have_old_snap) { + //无过期截图,生成一个空文件,目的是顺便创建文件夹路径 + //同时防止在FFmpeg生成截图途中不停的尝试调用该api多次启动FFmpeg进程 + auto file = File::create_file(new_snap.data(), "wb"); + if (file) { + fclose(file); + } } - //启动FFmpeg进程,开始截图 - FFmpegSnap::makeSnap(allArgs["url"],snap_path,allArgs["timeout_sec"],[invoker,headerIn,snap_path](bool success){ - if(!success){ + //启动FFmpeg进程,开始截图,生成临时文件,截图成功后替换为正式文件 + auto new_snap_tmp = new_snap + ".tmp"; + FFmpegSnap::makeSnap(allArgs["url"], new_snap_tmp, allArgs["timeout_sec"], [invoker, headerIn, new_snap, new_snap_tmp](bool success) { + if (!success) { //生成截图失败,可能残留空文件 - File::delete_file(snap_path.data()); + File::delete_file(new_snap_tmp.data()); + } else { + //临时文件改成正式文件 + File::delete_file(new_snap.data()); + rename(new_snap_tmp.data(), new_snap.data()); } - responseSnap(snap_path, headerIn, invoker); + responseSnap(new_snap, headerIn, invoker); }); });