YTExtractor/YTExtractor/YoutubeDataService.cs
2025-04-26 11:52:13 -03:00

115 lines
4.3 KiB
C#

using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using Microsoft.Extensions.Configuration;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace YouTubeAPIClient
{
public class YouTubeDataService
{
private readonly string _apiKey;
private readonly YouTubeService _youtubeService;
public YouTubeDataService(string apiKey)
{
_apiKey = apiKey;
_youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = apiKey,
ApplicationName = "YouTubeAPIClient"
});
}
public static bool IsValidYouTubeUrl(string urlx)
{
return Regex.IsMatch(urlx, @"^(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+$");
}
public static async Task<YtDlpInfo> GetVideoInfo(string url, string workingDir)
{
string videoId = ExtractVideoId(url);
if (string.IsNullOrEmpty(videoId))
{
throw new ArgumentException("URL inválida ou não foi possível extrair o ID do vídeo");
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer
{
ApiKey = Environment.GetEnvironmentVariable("YOUTUBE_API_KEY"),
ApplicationName = "YouTubeAPIClient"
});
var videoRequest = youtubeService.Videos.List("snippet");
videoRequest.Id = videoId;
var response = await videoRequest.ExecuteAsync();
if (response.Items.Count == 0)
throw new Exception("Vídeo não encontrado");
var video = response.Items[0];
var thumbnailUrl = video.Snippet.Thumbnails.High?.Url ??
video.Snippet.Thumbnails.Medium?.Url ??
video.Snippet.Thumbnails.Default__?.Url ?? "";
return new YtDlpInfo(
video.Snippet.Title,
thumbnailUrl
);
}
public static async Task<string> GetSubtitles(string url, string language, string workingDir)
{
string videoId = ExtractVideoId(url);
if (string.IsNullOrEmpty(videoId))
{
throw new ArgumentException("URL inválida ou não foi possível extrair o ID do vídeo");
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer
{
ApiKey = Environment.GetEnvironmentVariable("YOUTUBE_API_KEY"),
ApplicationName = "YouTubeAPIClient"
});
var captionRequest = youtubeService.Captions.List("snippet", videoId);
var captionResponse = await captionRequest.ExecuteAsync();
var caption = captionResponse.Items.FirstOrDefault(c =>
c.Snippet.Language.ToLower() == language.ToLower() ||
(c.Snippet.Language.ToLower().StartsWith(language.ToLower()) && c.Snippet.TrackKind == "asr"));
if (caption == null)
throw new Exception($"Nenhuma legenda encontrada para o idioma {language}");
var captionDownloadRequest = youtubeService.Captions.Download(caption.Id);
captionDownloadRequest.Tfmt = "vtt"; // Fix: Use string "vtt" instead of non-existent TfmtEnum
var captionStream = await captionDownloadRequest.ExecuteAsStreamAsync();
string vttFilePath = Path.Combine(workingDir, $"{videoId}_{language}.vtt");
using (var fileStream = new FileStream(vttFilePath, FileMode.Create, FileAccess.Write))
{
await captionStream.CopyToAsync(fileStream);
}
return await File.ReadAllTextAsync(vttFilePath);
}
private static string ExtractVideoId(string url)
{
var youtubeIdRegex = new Regex(@"(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^""&?\/\s]{11})");
var match = youtubeIdRegex.Match(url);
return match.Success ? match.Groups[1].Value : null;
}
}
// Classe com a mesma assinatura da original
public record YtDlpInfo(string Title, string ThumbnailUrl);
}