151 lines
4.4 KiB
C#
151 lines
4.4 KiB
C#
using System.Threading.Channels;
|
|
|
|
namespace ACBuildService;
|
|
|
|
public static class VideoDownload
|
|
{
|
|
private static readonly Channel<string> _queue = Channel.CreateUnbounded<string>();
|
|
private static readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
|
private static readonly TimeSpan _interval = TimeSpan.FromSeconds(20);
|
|
|
|
|
|
static VideoDownload()
|
|
{
|
|
Task.Run(ProcessQueueAsync);
|
|
}
|
|
|
|
public static void Add(string shareText)
|
|
{
|
|
_queue.Writer.TryWrite(shareText);
|
|
}
|
|
|
|
private static async Task ProcessQueueAsync()
|
|
{
|
|
var timer = new PeriodicTimer(_interval);
|
|
|
|
try
|
|
{
|
|
while (await _queue.Reader.WaitToReadAsync(_cts.Token) &&
|
|
await timer.WaitForNextTickAsync(_cts.Token))
|
|
{
|
|
if (_queue.Reader.TryRead(out var shareText))
|
|
{
|
|
// 这里开始处理任务,这个处理过程本身的时间不计入间隔
|
|
// PeriodicTimer 会保证两次 WaitForNextTickAsync 之间间隔10秒
|
|
await ProcessVideoDownloadAsync(shareText);
|
|
}
|
|
}
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
// 正常取消
|
|
}
|
|
}
|
|
|
|
private static async Task ProcessVideoDownloadAsync(string shareText)
|
|
{
|
|
try
|
|
{
|
|
var service = GetService(shareText);
|
|
if (service != null)
|
|
{
|
|
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 开始处理: {shareText}");
|
|
await DownloadVideoAsync(service, shareText);
|
|
|
|
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 处理完成: {shareText}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 处理失败: {shareText}, 错误: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
// 模拟下载视频的方法
|
|
private static async Task DownloadVideoAsync(DownloadPlatforms service, string shareText)
|
|
{
|
|
//开始解析数据
|
|
var videoModel = await service.ParseShare(shareText);
|
|
if (videoModel == null) return;
|
|
|
|
var rootPath = $"{HttpService.BaseRootPath}videos/";
|
|
var t = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
|
var fileName = $"{t}.mp4";
|
|
var filePath = Path.Combine(rootPath, fileName);
|
|
if (File.Exists(filePath))
|
|
{
|
|
Log.Error("文件已存在");
|
|
return;
|
|
}
|
|
|
|
var ret = await service.DownloadAsync(videoModel.VideoUrl, rootPath, fileName, null, null);
|
|
if (ret)
|
|
{
|
|
var dbItem = new VideoTable
|
|
{
|
|
SourcePath = shareText,
|
|
FilePath = fileName,
|
|
AuthorName = videoModel.AuthorName,
|
|
Title = videoModel.Title,
|
|
Desc = videoModel.Desc,
|
|
Duration = videoModel.Duration,
|
|
Like = (int)videoModel.DiggCount,
|
|
Collect = (int)videoModel.CollectCount,
|
|
Message = (int)videoModel.CommentCount,
|
|
Share = (int)videoModel.ShareCount,
|
|
CreateTime = DateTime.Now
|
|
};
|
|
DB.Main.Insertable(dbItem).ExecuteCommand();
|
|
}
|
|
|
|
//解析数据后等待一会
|
|
await Task.Delay(3000);
|
|
}
|
|
|
|
#region Service
|
|
|
|
private static Dictionary<ShortVideoPlatformEnum, DownloadPlatforms> _services =
|
|
new Dictionary<ShortVideoPlatformEnum, DownloadPlatforms>();
|
|
|
|
private static DownloadPlatforms GetService(string text)
|
|
{
|
|
var platform = GetPlatform(text);
|
|
if (_services.TryGetValue(platform, out var value))
|
|
{
|
|
return value;
|
|
}
|
|
|
|
if (platform == ShortVideoPlatformEnum.DouYin)
|
|
{
|
|
value = new DouYin();
|
|
}
|
|
else if (platform == ShortVideoPlatformEnum.KuaiShou)
|
|
{
|
|
value = new KuaiShou();
|
|
}
|
|
|
|
if (value != null)
|
|
{
|
|
_services[platform] = value;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
private static ShortVideoPlatformEnum GetPlatform(string text)
|
|
{
|
|
if (text.Contains("douyin"))
|
|
{
|
|
return ShortVideoPlatformEnum.DouYin;
|
|
}
|
|
|
|
if (text.Contains("kuaishou"))
|
|
{
|
|
return ShortVideoPlatformEnum.KuaiShou;
|
|
}
|
|
|
|
return ShortVideoPlatformEnum.None;
|
|
}
|
|
|
|
#endregion
|
|
} |