1、永久删除视频时,同时删除原视频所在文件夹

2、图文视频不下载视频,仅下载图片或mp3时,每次都会重新调用下载资源接口bug修复
This commit is contained in:
jianzhichu
2026-01-01 21:09:19 +08:00
parent b9b3731bbe
commit 87f154a8b7
7 changed files with 51 additions and 25 deletions
+3 -3
View File
@@ -84,7 +84,7 @@ Cookie 及 `sec_user_id` 是同步功能的核心,需严格按步骤获取,
## 3. 默认账号密码(首次登录用)
首次访问后台管理页面时,使用以下默认账号密码:
- **用户名**`douyin`
- **密码**`douyin2025`
- **密码**`douyin2026`
> ⚠️ **安全建议**:登录后修改密码。
@@ -96,8 +96,8 @@ Cookie 及 `sec_user_id` 是同步功能的核心,需严格按步骤获取,
| 镜像标签 | 架构 |
| ----------------- | -------------- |
| `beta_1.9.4` | x86_64 (amd64) |
| `arm_1.9.4` | ARM64 |
| `beta_1.9.5` | x86_64 (amd64) |
| `arm_1.9.5` | ARM64 |
### 构建命令示例
+20 -11
View File
@@ -646,10 +646,17 @@ namespace dy.net.job
}
else
{
//记录存在,但本地文件不存在,则继续下载。
Log.Debug($"{VideoType}-视频-{exitVideo.AwemeId}记录存在,但本地文件缺失,删除记录,重新下载");
//删除原来的记录
await douyinVideoService.DeleteById(exitVideo.Id);
if (exitVideo.OnlyImgOrOnlyMp3)
{
return true;//说明是图文视频,不需要再下载视频了
}
else
{
//记录存在,但本地文件不存在,则继续下载。
Log.Debug($"{VideoType}-视频-{exitVideo.AwemeId}记录存在,但本地文件缺失,删除记录,重新下载");
//删除原来的记录
await douyinVideoService.DeleteById(exitVideo.Id);
}
}
}
}
@@ -768,7 +775,7 @@ namespace dy.net.job
// 生成NFO文件
await GenerateNfoFile(saveFolder, item, avatarUrl, cookie, config);
// 创建视频实体
return CreateVideoEntity(cookie, item, v, savePath, saveFolder, tag1, tag2, tag3, avatarSavePath, avatarUrl, data);
return CreateVideoEntity(config,cookie, item, v, savePath, saveFolder, tag1, tag2, tag3, avatarSavePath, avatarUrl, data);
}
@@ -837,7 +844,7 @@ namespace dy.net.job
DataSize = DouyinFileUtils.GetTotalFileSize(dynamicSavePaths) // 合成视频的文件大小
}
};
return CreateVideoEntity(cookie, item, virtualBitRate, dynamicSavePaths.FirstOrDefault(), saveFolder, tag1, tag2, tag3,"", "", data,dynamicSavePaths);
return CreateVideoEntity(config,cookie, item, virtualBitRate, dynamicSavePaths.FirstOrDefault(), saveFolder, tag1, tag2, tag3,"", "", data,dynamicSavePaths);
}
@@ -978,7 +985,7 @@ namespace dy.net.job
// 获取不带扩展名的完整路径
string fullPathWithoutExtension = Path.Combine(Path.GetDirectoryName(savePath),Path.GetFileNameWithoutExtension(savePath) );
//string fullPathWithoutExtension = Path.Combine(Path.GetDirectoryName(savePath),Path.GetFileNameWithoutExtension(savePath) );
if (config.DownImageVideo)
{
// 检查合成后的视频文件是否有效
@@ -1021,7 +1028,7 @@ namespace dy.net.job
};
// 创建视频实体
var videoEntity = CreateVideoEntity(
var videoEntity = CreateVideoEntity(config,
cookie, item, virtualBitRate, savePath, fileNamefolder,
tag1, tag2, tag3, avatarSavePath, avatarUrl, data);
@@ -1240,6 +1247,7 @@ namespace dy.net.job
/// 创建视频实体
/// 根据视频信息、下载路径等创建DouyinVideo实体对象
/// </summary>
/// <param name="config">配置</param>
/// <param name="cookie">用户Cookie</param>
/// <param name="item">视频信息</param>
/// <param name="bitRate">视频码率信息</param>
@@ -1253,13 +1261,13 @@ namespace dy.net.job
/// <param name="data">视频信息对象</param>
/// <param name="dynamicVideos">动态视频</param>
/// <returns>创建的视频实体对象</returns>
private DouyinVideo CreateVideoEntity(
private DouyinVideo CreateVideoEntity(AppConfig config,
DouyinCookie cookie, Aweme item, VideoBitRate bitRate, string savePath, string saveFolder,
string tag1, string tag2, string tag3, string avatarSavePath, string avatarUrl, DouyinVideoInfo data,List<string> dynamicVideos=null)
{
var diffs = GetVideoEntityDifferences(cookie, item);
var video= new DouyinVideo
var video = new DouyinVideo
{
ViedoType = VideoType,
AwemeId = item.AwemeId,
@@ -1283,7 +1291,8 @@ namespace dy.net.job
VideoCoverSavePath = Path.Combine(saveFolder, "poster.jpg"),
SyncTime = DateTime.Now,
DyUserId = item.AuthorUserId == 0 ? item.Author?.Uid : item.AuthorUserId.ToString(),
CookieId = cookie.Id
CookieId = cookie.Id,
OnlyImgOrOnlyMp3 = string.IsNullOrWhiteSpace(savePath) && !config.DownImageVideo && (config.DownImage || config.DownMp3)
};
if (dynamicVideos != null && dynamicVideos.Count > 0)
{
+5
View File
@@ -154,5 +154,10 @@ namespace dy.net.model
// 普通字符串字段,显式标记为 SQLite TEXT 类型
[SugarColumn(ColumnDataType = "TEXT", Length = -1,IsNullable =true)]
public string DynamicVideos { get; set; }
/// <summary>
/// 是否仅下载图片或仅下载音频
/// </summary>
public bool OnlyImgOrOnlyMp3 { get; set; }
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ namespace dy.net.service
AdminUserInfo userInfo = new AdminUserInfo
{
UserName = "douyin",
Password = "douyin2025",
Password = "douyin2026",
CreateTime = DateTime.Now
};
return _userRepository.InitUser(userInfo);
+1 -1
View File
@@ -52,7 +52,7 @@ namespace dy.net.service
}
var cookie = new DouyinCookie
{
UserName = "douyin2025",
UserName = "douyin2026",
Cookies = "-",
SecUserId = "-",
Id = IdGener.GetLong().ToString(),
+1 -1
View File
@@ -301,7 +301,7 @@ namespace dy.net.service
/// <summary>
/// 保存下载的文件(图片/音频)到目标目录
/// </summary>
private async Task SaveDownloadedFilesAsync(string[] sourcePaths, string targetFolder, string defaultExt,string videoFileName)
private static async Task SaveDownloadedFilesAsync(string[] sourcePaths, string targetFolder, string defaultExt,string videoFileName)
{
if (sourcePaths == null || sourcePaths.Length == 0) return;
Directory.CreateDirectory(targetFolder); // 确保目标目录存在
+20 -8
View File
@@ -199,7 +199,7 @@ namespace dy.net.service
// 3. 构建重新下载记录(提前准备数据,避免事务内耗时操作)
var reDownList = new List<DouyinReDownload>();
var filePathsToDelete = new List<string>(); // 收集待删除文件路径,统一处理
var filePathsToDelete = new List<(string path,bool onlyImgOrMp3)>(); // 收集待删除文件路径,统一处理
foreach (var video in videos)
{
@@ -221,7 +221,7 @@ namespace dy.net.service
CookieId = video.CookieId
});
filePathsToDelete.Add(video.VideoSavePath);
filePathsToDelete.Add((video.VideoSavePath,video.OnlyImgOrOnlyMp3));
}
// 无有效重新下载记录时直接返回
@@ -248,23 +248,35 @@ namespace dy.net.service
// 5. 文件删除(非事务操作,失败不回滚数据库,可根据业务调整)
// 采用异步文件操作,避免同步IO阻塞线程(需.NET 5+支持)
foreach (var path in filePathsToDelete)
foreach (var video in filePathsToDelete)
{
try
{
if (File.Exists(path))
if (File.Exists(video.path))
{
File.Delete(path); // 异步删除,提升并发性能
Serilog.Log.Debug("视频文件删除成功:Path={0}", path);
File.Delete(video.path); // 异步删除,提升并发性能
Serilog.Log.Debug("视频文件删除成功:Path={0}", video);
if (!video.onlyImgOrMp3)//如果是纯图片或纯音频文件,则不删除所在文件夹
{
//检查这个路径所在文件夹是否还有其他视频文件,如果没有则删除这个文件夹
var dir = Path.GetDirectoryName(video.Item1);
bool hasMp4File = Directory.EnumerateFiles(dir, "*.mp4", SearchOption.TopDirectoryOnly).Any(); // 只要存在一个MP4文件就返回true;
if (!hasMp4File)
{
Directory.Delete(dir, true);
}
}
}
else
{
Serilog.Log.Error("视频文件不存在,跳过删除:Path={0}", path);
Serilog.Log.Error("视频文件不存在,跳过删除:Path={0}", video);
}
}
catch (IOException ex)
{
Serilog.Log.Error(ex, "视频文件删除失败:Path={0}", path);
Serilog.Log.Error(ex, "视频文件删除失败:Path={0}", video);
}
}