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