1、永久删除视频时,同时删除原视频所在文件夹
2、图文视频不下载视频,仅下载图片或mp3时,每次都会重新调用下载资源接口bug修复
This commit is contained in:
@@ -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 |
|
||||
|
||||
|
||||
### 构建命令示例
|
||||
|
||||
@@ -645,6 +645,12 @@ namespace dy.net.job
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (exitVideo.OnlyImgOrOnlyMp3)
|
||||
{
|
||||
return true;//说明是图文视频,不需要再下载视频了
|
||||
}
|
||||
else
|
||||
{
|
||||
//记录存在,但本地文件不存在,则继续下载。
|
||||
Log.Debug($"{VideoType}-视频-{exitVideo.AwemeId}记录存在,但本地文件缺失,删除记录,重新下载");
|
||||
@@ -653,6 +659,7 @@ namespace dy.net.job
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace dy.net.service
|
||||
}
|
||||
var cookie = new DouyinCookie
|
||||
{
|
||||
UserName = "douyin2025",
|
||||
UserName = "douyin2026",
|
||||
Cookies = "-",
|
||||
SecUserId = "-",
|
||||
Id = IdGener.GetLong().ToString(),
|
||||
|
||||
@@ -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); // 确保目标目录存在
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user