115 lines
4.3 KiB
C#
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);
|
|
} |