1、nfo刮削文件优化,修复演员信息(视频作者),建议emby媒体库选影视,或者混合类型-右上角有一个兼容旧数据的按钮一键重置所有刮削文件

2、图文视频 以及动态视频,遇到因版权原因无法下载音频时,需要额外的音频文件,现在放到mp3目录了,docker-compose增加一个映射路径即可 例如: - /vol2/1000/media/dysync/mp3:/app/mp3
3、增加动态视频合成配置(不建议保留原视频,没有额外刮削的,因为有些视频是几十个很短的动图一样的视频拼接成的,保留原视频emby会出现一堆没有封面的视频)
4、容器重启后,手机端会连续跳转登录页很多次的bug修复
5、关注博主保存文件夹路径长度增加,允许_
6、批量永久删除选中的视频(不再下载,慎重)
7、看板页面 隐藏一个功能:双击作者头像,可以删除作者所有视频(永久删除,不再下载,慎重)
8、手机端 视频播放优化
This commit is contained in:
jianzhichu
2026-01-15 00:41:47 +08:00
parent 8da82889d1
commit ff80250012
22 changed files with 795 additions and 543 deletions
+52 -109
View File
@@ -148,7 +148,7 @@ namespace dy.net.Controllers
[AllowAnonymous]
public async Task<IActionResult> IsInit()
{
var init= await dyCookieService.IsInit();
var init = await dyCookieService.IsInit();
return ApiResult.Success(init);
}
@@ -179,7 +179,7 @@ namespace dy.net.Controllers
{
dyUserCookies.Id = IdGener.GetLong().ToString();
if(string.IsNullOrWhiteSpace(dyUserCookies.SavePath))
if (string.IsNullOrWhiteSpace(dyUserCookies.SavePath))
{
return ApiResult.Fail("收藏存储路径不能为空");
}
@@ -221,10 +221,10 @@ namespace dy.net.Controllers
public async Task<IActionResult> GetAppPort()
{
//return ApiResult.Success(10105);
return ApiResult.Success(string.IsNullOrWhiteSpace(Appsettings.Get("appPort"))?10101: Convert.ToInt32(Appsettings.Get("appPort")));
return ApiResult.Success(string.IsNullOrWhiteSpace(Appsettings.Get("appPort")) ? 10101 : Convert.ToInt32(Appsettings.Get("appPort")));
}
/// <summary>
@@ -292,7 +292,7 @@ namespace dy.net.Controllers
var data = commonService.GetConfig();
return ApiResult.Success(data);
}
[HttpPost("UpdateConfig")]
public async Task<IActionResult> UpdateConfig(AppConfig config)
@@ -350,15 +350,15 @@ namespace dy.net.Controllers
{
var deploy = Appsettings.Get("deploy");
if(string.IsNullOrWhiteSpace(deploy))
if (string.IsNullOrWhiteSpace(deploy))
{
return await GetDockerTagVersions();
}
else
{
if(deploy== "fn")//飞牛
if (deploy == "fn")//飞牛
{
return ApiResult.Success(new List<string> { "beta_"+Appsettings.Get("fnVersion") });
return ApiResult.Success(new List<string> { "beta_" + Appsettings.Get("fnVersion") });
}
else
{
@@ -366,7 +366,7 @@ namespace dy.net.Controllers
}
}
}
private static async Task<IActionResult> GetDockerTagVersions()
@@ -387,107 +387,50 @@ namespace dy.net.Controllers
}
}
/// <summary>
/// 查询mp3目录下有没有音频文件
/// </summary>
/// <returns></returns>
[HttpGet("mp3List")]
public async Task<IActionResult> GetExistMps()
{
var path = Path.Combine(AppContext.BaseDirectory, "mp3");
if (Directory.Exists(path))
{
var audioFiles = Directory.GetFiles(path);
///// <summary>
///// 上传音频文件接口
///// </summary>
///// <param name="file">要上传的音频文件</param>
///// <returns>上传结果</returns>
//[HttpPost("UploadAudio")]
//public IActionResult UploadAudio(IFormFile file)
//{
// // 1. 验证文件是否为空
// if (file == null || file.Length == 0)
// {
// return BadRequest(new { success = false, message = "请选择要上传的音频文件" });
// }
// try
// {
// // 2. 验证文件大小
// if (file.Length > _maxFileSize)
// {
// return BadRequest(new { success = false, message = $"文件大小超过限制(最大允许 {_maxFileSize / 1024 / 1024}MB" });
// }
// // 3. 获取文件扩展名并验证
// var fileExtension = Path.GetExtension(file.FileName).ToLower();
// if (!_allowedAudioExtensions.Contains(fileExtension))
// {
// return BadRequest(new
// {
// success = false,
// message = $"不支持的音频格式,仅允许:{string.Join(", ", _allowedAudioExtensions)}"
// });
// }
// // 4. 验证 MIME 类型(可选但推荐,防止扩展名伪造)
// var contentType = file.ContentType.ToLower();
// if (!_allowedAudioMimeTypes.Contains(contentType))
// {
// return BadRequest(new
// {
// success = false,
// message = "文件类型验证失败,请上传合法的音频文件"
// });
// }
// //先删除
// var uploadMp3 = Directory.GetFiles(Path.Combine(AppContext.BaseDirectory, "mp3"))
// .Where(filePath => Path.GetFileNameWithoutExtension(filePath) != "silent_10")
// .FirstOrDefault();
// if (!string.IsNullOrWhiteSpace(uploadMp3) && System.IO.File.Exists(uploadMp3))
// {
// System.IO.File.Delete(uploadMp3);
// }
// // 5. 生成唯一文件名(避免重复)
// var uniqueFileName = $"dysync_default{fileExtension}";
// // 6. 定义文件保存路径(建议配置在 appsettings.json 中,这里简化处理)
// var uploadPath = Path.Combine(AppContext.BaseDirectory, "mp3");
// // 确保目录存在
// if (!Directory.Exists(uploadPath))
// {
// Directory.CreateDirectory(uploadPath);
// }
// // 7. 保存文件
// var filePath = Path.Combine(uploadPath, uniqueFileName);
// if (System.IO.File.Exists(filePath))
// {
// System.IO.File.Delete(filePath);
// }
// using (var stream = new FileStream(filePath, FileMode.Create))
// {
// file.CopyTo(stream);
// }
// // 8. 返回成功结果(可根据需求返回文件路径/URL 等)
// return ApiResult.Success(new { fileName = uniqueFileName, filePath });
// }
// catch (Exception ex)
// {
// // 捕获异常并返回错误信息
// return ApiResult.Fail(ex.Message);
// }
//}
//[AllowAnonymous]
//[HttpGet("defaudio")]
//public async Task<IActionResult> GetDefaultAudioUrl()
//{
// var uploadMp3 = Directory.GetFiles(Path.Combine(AppContext.BaseDirectory, "mp3"))
// .Where(filePath => Path.GetFileNameWithoutExtension(filePath) != "silent_10")
// .FirstOrDefault();
// if (!string.IsNullOrWhiteSpace(uploadMp3) && System.IO.File.Exists(uploadMp3))
// {
// return File(System.IO.File.ReadAllBytes(uploadMp3), "application/octet-stream", Path.GetFileName(uploadMp3));
// }
// return ApiResult.Fail("未上传音频");
//}
var fileNames = audioFiles.Select(f => new {filename= Path.GetFileName(f) }).Where(x=>x.filename!= "silent_10.mp3").ToList();
return ApiResult.Success(fileNames);
}
else
{
return ApiResult.Fail("没有找到默认音频文件");
}
}
/// <summary>
/// 播放音频流
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet("getmp3")]
public async Task<IActionResult> GetMp3([FromQuery] string name)
{
var path = Path.Combine(AppContext.BaseDirectory, "mp3", name);
if (System.IO.File.Exists(path))
{
//返回mp3文件流
var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
return new FileStreamResult(fileStream, "audio/mpeg")
{
FileDownloadName = name
};
}
else
{
return ApiResult.Fail("文件不存在");
}
}
}
}
+55 -24
View File
@@ -5,6 +5,7 @@ using dy.net.utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Security.Cryptography;
namespace dy.net.Controllers
{
@@ -174,7 +175,6 @@ namespace dy.net.Controllers
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("redown")]
public async Task<IActionResult> ReDownload(ReDownViedoDto dto)
{
@@ -195,6 +195,27 @@ namespace dy.net.Controllers
}
}
}
/// <summary>
/// 批量删除
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("vdelete/batch")]
public async Task<IActionResult> BathRealDelete(ReDownViedoDto dto)
{
var result = await douyinVideoService.RealDeleteVideos(dto.Ids);
if (result)
{
return ApiResult.Success(true);
}
else
{
return ApiResult.Fail("错误");
}
}
/// <summary>
/// 删除视频-不再下载
/// </summary>
@@ -209,34 +230,15 @@ namespace dy.net.Controllers
}
else
{
var video = await douyinVideoService.GetById(vid);
if (video == null)
var res = await douyinVideoService.RealDeleteVideos(new List<string> { vid });
if (res)
{
return ApiResult.Fail("请求失败");
return ApiResult.Success("删除成功");
}
else
{
var result = await douyinVideoService.ReDownloadViedoAsync(new ReDownViedoDto { Ids = new List<string> { vid } });
if (result)
{
//加入删除逻辑
await douyinCommonService.AddDeleteVideo(new DouyinVideoDelete
{
ViedoId = video.AwemeId,
VideoTitle = video.VideoTitle,
VideoSavePath = video.VideoSavePath
});
Serilog.Log.Debug($"前面的日志,你错了,这条视频是永久删除..哈哈--{video.VideoTitle}");
return ApiResult.Success();
}
else
{
return ApiResult.Fail();
}
return ApiResult.Fail("删除失败");
}
}
}
@@ -249,6 +251,35 @@ namespace dy.net.Controllers
{
return ApiResult.Success(await douyinCommonService.GetDouyinDeleteVideos());
}
/// <summary>
/// 根据博主id删除博主所有视频
/// </summary>
/// <param name="uperUid"></param>
/// <returns></returns>
[HttpGet("vdelete/byauthor/{uperUid}")]
public async Task<IActionResult> DeleteByAuthor([FromRoute] string uperUid)
{
var videos = await douyinVideoService.GetByAuthorId(uperUid);
if (videos != null && videos.Any())
{
var res = await douyinVideoService.RealDeleteVideos(videos.Select(x => x.Id).ToList());
if (res)
{
return ApiResult.Success("删除成功");
}
else
{
return ApiResult.Fail("删除失败");
}
}
return ApiResult.Fail("未找到该博主视频");
}
//private async Task<(bool flowControl, IActionResult value)> BatchDeleteVideos(List<DouyinVideo> videos)
//{
// return (flowControl: true, value: null);
//}
/// <summary>
/// 查询最新N条数据