Compare commits
No commits in common. "242b4596ff637e6d5f1a7fcbd730f20303102836" and "dd7dd54ca29441544560ead8ee73b3b4e84dd375" have entirely different histories.
242b4596ff
...
dd7dd54ca2
@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 17
|
|
||||||
VisualStudioVersion = 17.11.35327.3
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YTExtractor", "YTExtractor\YTExtractor.csproj", "{7DA7D783-153F-42EF-87E4-239DEC80F91A}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{7DA7D783-153F-42EF-87E4-239DEC80F91A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{7DA7D783-153F-42EF-87E4-239DEC80F91A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{7DA7D783-153F-42EF-87E4-239DEC80F91A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{7DA7D783-153F-42EF-87E4-239DEC80F91A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {0A995D46-30D9-42A9-BA92-225340DFC214}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
using MongoDB.Driver;
|
|
||||||
|
|
||||||
namespace YTExtractor.Data
|
|
||||||
{
|
|
||||||
public class MongoDBConnector
|
|
||||||
{
|
|
||||||
private readonly IMongoDatabase _database;
|
|
||||||
private readonly IMongoCollection<VideoData> _collection;
|
|
||||||
|
|
||||||
public MongoDBConnector(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
var connectionString = configuration.GetSection("MongoDbConnaction").Value;
|
|
||||||
var client = new MongoClient(connectionString);
|
|
||||||
_database = client.GetDatabase("YTExtractor");
|
|
||||||
_collection = _database.GetCollection<VideoData>("videos");
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task InsertVideo(VideoData video)
|
|
||||||
{
|
|
||||||
await _collection.InsertOneAsync(video);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<VideoData> GetVideoById(string id)
|
|
||||||
{
|
|
||||||
return await _collection.Find(x => x.Id == id).FirstOrDefaultAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<VideoData>> GetAllVideos()
|
|
||||||
{
|
|
||||||
return await _collection.Find(_ => true).ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateVideo(VideoData video)
|
|
||||||
{
|
|
||||||
await _collection.ReplaceOneAsync(x => x.Id == video.Id, video);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteVideo(string id)
|
|
||||||
{
|
|
||||||
await _collection.DeleteOneAsync(x => x.Id == id);
|
|
||||||
}
|
|
||||||
public async Task<VideoData> GetVideoByUrl(string url)
|
|
||||||
{
|
|
||||||
return await _collection.Find(x => x.Url == url).FirstOrDefaultAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
using MongoDB.Bson;
|
|
||||||
using MongoDB.Bson.Serialization.Attributes;
|
|
||||||
|
|
||||||
namespace YTExtractor.Data
|
|
||||||
{
|
|
||||||
public class VideoData
|
|
||||||
{
|
|
||||||
[BsonId]
|
|
||||||
[BsonRepresentation(BsonType.String)]
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
public string Titulo { get; set; }
|
|
||||||
public string Url { get; set; }
|
|
||||||
public string ThumbnailUrl { get; set; }
|
|
||||||
public string TranscText { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
|
||||||
WORKDIR /src
|
|
||||||
COPY . .
|
|
||||||
RUN dotnet restore
|
|
||||||
RUN dotnet publish -c Release -o /app
|
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
|
||||||
WORKDIR /app
|
|
||||||
COPY --from=build /app .
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y python3-pip && \
|
|
||||||
pip3 install yt-dlp && \
|
|
||||||
mkdir /app/temp && \
|
|
||||||
chmod 777 /app/temp && \
|
|
||||||
which yt-dlp || (echo "yt-dlp not found" && exit 1)
|
|
||||||
|
|
||||||
EXPOSE 80
|
|
||||||
ENTRYPOINT ["dotnet", "YTExtractor.dll"]
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
using YTExtractor;
|
|
||||||
using Serilog;
|
|
||||||
using Serilog.Sinks.InfluxDB;
|
|
||||||
using YTExtractor.Data;
|
|
||||||
|
|
||||||
// App configuration and endpoints
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
|
||||||
|
|
||||||
var environment = builder.Environment.EnvironmentName;
|
|
||||||
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
|
||||||
.WriteTo.InfluxDB(
|
|
||||||
address: "http://192.168.0.76",
|
|
||||||
dbName: "telegraf",
|
|
||||||
source: "YTExtractor-{environment}")
|
|
||||||
.Enrich.WithProperty("Environment", environment)
|
|
||||||
.CreateLogger();
|
|
||||||
|
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
|
||||||
builder.Services.AddSwaggerGen();
|
|
||||||
builder.Services.AddSingleton<MongoDBConnector>();
|
|
||||||
|
|
||||||
var app = builder.Build();
|
|
||||||
app.UseSwagger();
|
|
||||||
app.UseSwaggerUI();
|
|
||||||
|
|
||||||
|
|
||||||
app.MapPost("/api/video-info", async (VideoRequest request, MongoDBConnector mongo) =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!YoutubeService.IsValidYouTubeUrl(request.Url))
|
|
||||||
return Results.BadRequest("Invalid YouTube URL");
|
|
||||||
|
|
||||||
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
|
||||||
Directory.CreateDirectory(tempDir);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Log.Information($"Obtendo dados do video: {request.Url}");
|
|
||||||
|
|
||||||
var videoExists = await mongo.GetVideoByUrl(request.Url);
|
|
||||||
if (videoExists != null)
|
|
||||||
{
|
|
||||||
return Results.Ok(new VideoInfo(
|
|
||||||
videoExists.Url,
|
|
||||||
videoExists.Titulo,
|
|
||||||
videoExists.ThumbnailUrl,
|
|
||||||
videoExists.TranscText
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
var info = await YoutubeService.GetVideoInfo(request.Url, tempDir);
|
|
||||||
var subtitles = await YoutubeService.GetSubtitles(request.Url, request.Language, tempDir);
|
|
||||||
|
|
||||||
await mongo.InsertVideo(new VideoData
|
|
||||||
{
|
|
||||||
Url = request.Url,
|
|
||||||
Titulo = info.Title,
|
|
||||||
ThumbnailUrl = info.ThumbnailUrl,
|
|
||||||
TranscText = subtitles
|
|
||||||
});
|
|
||||||
|
|
||||||
Log.Information($"Dados de video obtidos: {request.Url}");
|
|
||||||
return Results.Ok(new VideoInfo(
|
|
||||||
request.Url,
|
|
||||||
info.Title,
|
|
||||||
info.ThumbnailUrl,
|
|
||||||
subtitles
|
|
||||||
));
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (Directory.Exists(tempDir))
|
|
||||||
Directory.Delete(tempDir, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Failed to get video info");
|
|
||||||
return Results.Problem(ex.Message);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.WithName("GetVideoInfo")
|
|
||||||
.WithOpenApi();
|
|
||||||
|
|
||||||
app.Run();
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:49221",
|
|
||||||
"sslPort": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"http": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "swagger",
|
|
||||||
"applicationUrl": "http://localhost:5102",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"https": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "swagger",
|
|
||||||
"applicationUrl": "https://localhost:7082;http://localhost:5102",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "swagger",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace YTExtractor
|
|
||||||
{
|
|
||||||
public record VideoInfo(string Url, string Title, string ThumbnailUrl, string Subtitles);
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
namespace YTExtractor
|
|
||||||
{
|
|
||||||
public record VideoRequest(string Url, string Language);
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.12" />
|
|
||||||
<PackageReference Include="MongoDB.Bson" Version="3.1.0" />
|
|
||||||
<PackageReference Include="MongoDB.Driver" Version="3.1.0" />
|
|
||||||
<PackageReference Include="Serilog" Version="4.2.1-dev-02337" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.InfluxDB.DotNetCore" Version="1.0.2" />
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="yt-dlp.exe">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ActiveDebugProfile>https</ActiveDebugProfile>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
@YTExtractor_HostAddress = http://localhost:5102
|
|
||||||
|
|
||||||
GET {{YTExtractor_HostAddress}}/weatherforecast/
|
|
||||||
Accept: application/json
|
|
||||||
|
|
||||||
###
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
using Microsoft.Extensions.Hosting.Internal;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace YTExtractor
|
|
||||||
{
|
|
||||||
public class YoutubeService
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
var startInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = "yt-dlp",
|
|
||||||
Arguments = $"--dump-json {url}",
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
WorkingDirectory = workingDir
|
|
||||||
};
|
|
||||||
|
|
||||||
using var process = Process.Start(startInfo);
|
|
||||||
var output = await process.StandardOutput.ReadToEndAsync();
|
|
||||||
await process.WaitForExitAsync();
|
|
||||||
|
|
||||||
if (process.ExitCode != 0)
|
|
||||||
throw new Exception("Failed to get video info");
|
|
||||||
|
|
||||||
var jsonDoc = JsonDocument.Parse(output);
|
|
||||||
var root = jsonDoc.RootElement;
|
|
||||||
|
|
||||||
return new YtDlpInfo(
|
|
||||||
root.GetProperty("title").GetString() ?? "",
|
|
||||||
root.GetProperty("thumbnail").GetString() ?? ""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<string> GetSubtitles(string url, string language, string workingDir)
|
|
||||||
{
|
|
||||||
var pathExe = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
|
||||||
var exePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
|
|
||||||
? Path.Combine(pathExe, "yt-dlp.exe")
|
|
||||||
: "yt-dlp";
|
|
||||||
|
|
||||||
//var wokingExe = Path.Combine(pathExe, "yt-dlp.exe");
|
|
||||||
var startInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = exePath,
|
|
||||||
Arguments = $"--write-sub --write-auto-sub --sub-lang {language} --skip-download {url}",
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
WorkingDirectory = workingDir
|
|
||||||
};
|
|
||||||
|
|
||||||
using var process = Process.Start(startInfo);
|
|
||||||
var output = await process.StandardOutput.ReadToEndAsync();
|
|
||||||
var error = await process.StandardError.ReadToEndAsync();
|
|
||||||
await process.WaitForExitAsync();
|
|
||||||
|
|
||||||
var subtitleFile = Directory.GetFiles(workingDir, "*.vtt").FirstOrDefault();
|
|
||||||
if (subtitleFile == null)
|
|
||||||
throw new Exception("No subtitles found");
|
|
||||||
|
|
||||||
return await File.ReadAllTextAsync(subtitleFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace YTExtractor
|
|
||||||
{
|
|
||||||
public record YtDlpInfo(string Title, string ThumbnailUrl);
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowedHosts": "*",
|
|
||||||
"MongoDbConnaction": "mongodb://admin:c4rn31r0@192.168.0.82:27017,192.168.0.81:27017/?replicaSet=rs0"
|
|
||||||
}
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user