[CHANGE] Implementing video fetching and deciphering

This commit is contained in:
max
2025-10-20 13:57:55 +02:00
parent 1555ae9f3d
commit 2b5e93ff8a
10 changed files with 230 additions and 8 deletions

View File

@@ -83,7 +83,7 @@ public sealed class YouTubeClient : IDisposable
if (string.IsNullOrWhiteSpace(State?.WebPlayerContextConfig?.WebPlayerContext?.DatasyncId))
{
var datasyncResult = await GetDatasyncIds();
var datasyncResult = await GetDatasyncIdsAsync();
if (!datasyncResult.IsSuccess)
{
return datasyncResult;
@@ -125,7 +125,24 @@ public sealed class YouTubeClient : IDisposable
return result.Error ?? ResultError.Fail("Request failed!");
}
var clientStateResult = HtmlParser.GetStateJson(result.Value);
var stateResult = SetClientStateFromHtml(result.Value);
if (!stateResult.IsSuccess)
{
return stateResult;
}
var cookieRotationResult = await RotateCookiesPageAsync();
return !cookieRotationResult.IsSuccess ? cookieRotationResult : Result.Success();
}
private Result SetClientStateFromHtml(string html)
{
if (string.IsNullOrWhiteSpace(html))
{
return ResultError.Fail("HTML is empty!!");
}
var clientStateResult = HtmlParser.GetStateJson(html);
if (clientStateResult is { IsSuccess: false, Error: not null })
{
return clientStateResult.Error;
@@ -146,11 +163,10 @@ public sealed class YouTubeClient : IDisposable
}
State.IsPremiumUser = clientStateResult.Value.Item2;
var cookieRotationResult = await RotateCookiesPageAsync();
return !cookieRotationResult.IsSuccess ? cookieRotationResult : Result.Success();
return Result.Success();
}
public async Task<Result<InnertubeChannel>> GetChannelByIdAsync(string channelId)
{
if (State == null)
@@ -262,7 +278,7 @@ public sealed class YouTubeClient : IDisposable
return JsonAccountParser.ParseAccountId(responseResult.Value);
}
private async Task<Result<string[]>> GetDatasyncIds()
private async Task<Result<string[]>> GetDatasyncIdsAsync()
{
if (State is not { LoggedIn: true } || CookieContainer.Count == 0)
{
@@ -291,4 +307,38 @@ public sealed class YouTubeClient : IDisposable
return ResultError.Fail("Failed to get datasyncIds! Client not logged in.");
}
public async Task<Result> GetVideoByIdAsync(string videoId, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(videoId))
{
return ResultError.Fail("Video id is empty!");
}
var request = new HttpRequestMessage(HttpMethod.Get, new Uri($"{NetworkService.Origin}/watch?v={videoId}"));
var response = await NetworkService.MakeRequestAsync(request, this);
if (!response.IsSuccess && !string.IsNullOrWhiteSpace(response.Value))
{
return response.Error ?? ResultError.Fail("Request failed!");
}
var html = response.Value;
var stateResult = SetClientStateFromHtml(html);
if (!stateResult.IsSuccess)
{
//TODO: Log warning: failed to update client state!
}
var htmlParseReult = HtmlParser.GetVideoDataFromHtml(html);
if (!htmlParseReult.IsSuccess)
{
return htmlParseReult;
}
//TODO: Process to YouTubeVideo model && decipher stream urls
return Result.Success();
}
}