wabbajack/Wabbajack.Lib/Downloaders/UrlDownloaders/YoutubeInferencer.cs

82 lines
2.7 KiB
C#
Raw Normal View History

using System;
using System.Linq;
using System.Threading.Tasks;
using Wabbajack.Common;
using YoutubeExplode;
namespace Wabbajack.Lib.Downloaders.UrlDownloaders
{
public class YoutubeInferencer : IUrlInferencer
{
public async Task<AbstractDownloadState> Infer(Uri uri)
{
var state = (YouTubeDownloader.State)YouTubeDownloader.UriToState(uri);
if (state == null) return null;
var client = new YoutubeClient(Common.Http.ClientFactory.Client);
var video = await client.GetVideoAsync(state.Key);
var desc = video.Description;
var lines = desc.Split('\n', StringSplitOptions.RemoveEmptyEntries)
.Select(line => line.Trim())
.Select(line =>
{
var segments = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (segments.Length == 0) return (TimeSpan.Zero, null);
if (TryParseEx(segments.First(), out var s1))
return (s1, string.Join(" ", segments.Skip(1)));
if (TryParseEx(Enumerable.Last(segments), out var s2))
return (s2, string.Join(" ", Utils.ButLast(segments)));
return (TimeSpan.Zero, null);
})
.Where(t => t.Item2 != null)
.ToList();
var tracks = lines.Select((line, idx) => new YouTubeDownloader.State.Track
{
Name = Sanitize(line.Item2),
Start = line.Item1,
End = idx < lines.Count - 1 ? lines[idx + 1].Item1 : video.Duration,
Format = YouTubeDownloader.State.Track.FormatEnum.XWM
}).ToList();
state.Tracks = tracks;
return state;
}
private string Sanitize(string input)
{
return input.Replace(":", "_").Replace("'", "").Replace("\"", "");
}
private static bool TryParseEx(string s, out TimeSpan span)
{
var ints = s.Split(':').Select(segment => int.TryParse(segment, out int v) ? v : -1).ToArray();
if (ints.Any(i => i == -1))
{
span = TimeSpan.Zero;
return false;
}
switch (ints.Length)
{
case 2:
span = new TimeSpan(0, ints[0], ints[1]);
break;
case 3:
span = new TimeSpan(ints[0], ints[1], ints[2]);
break;
default:
span = TimeSpan.Zero;
return false;
}
return true;
}
}
}