First commit
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class Album {
|
||||
public long Id {get;set;} = 0;
|
||||
|
||||
public string AlbumId {get;set;}="";
|
||||
|
||||
public string AlbumName {get;set;}="";
|
||||
|
||||
public string AlbumReleaseDate {get;set;}="";
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
|
||||
public class AlbumQuery {
|
||||
[JsonPropertyName("releases")]
|
||||
public List<AlbumQueryItem> Albums {get;set;}=new List<AlbumQueryItem>();
|
||||
|
||||
public class AlbumQueryItem
|
||||
{
|
||||
[JsonPropertyName("id")]
|
||||
public Guid Id {get;set;}
|
||||
|
||||
[JsonPropertyName("title")]
|
||||
public string Name {get;set;}="";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class AlbumSongQuery {
|
||||
[JsonPropertyName("artist-credit")]
|
||||
public List<AlbumSongQueryMedia.AlbumSongQueryMediaTrack.AlbumSongQueryMediaTrackRecording.AlbumSongQueryMediaTrackRecordingArtists> Artists {get;set;}=new List<AlbumSongQueryMedia.AlbumSongQueryMediaTrack.AlbumSongQueryMediaTrackRecording.AlbumSongQueryMediaTrackRecordingArtists>();
|
||||
[JsonPropertyName("title")]
|
||||
public string Title {get;set;}="";
|
||||
|
||||
[JsonPropertyName("date")]
|
||||
public string Date {get;set;}="";
|
||||
|
||||
[JsonPropertyName("media")]
|
||||
public List<AlbumSongQueryMedia> Media {get;set;}=new List<AlbumSongQueryMedia>();
|
||||
|
||||
public class AlbumSongQueryMedia {
|
||||
[JsonPropertyName("tracks")]
|
||||
public List<AlbumSongQueryMediaTrack> Tracks {get;set;}=new List<AlbumSongQueryMediaTrack>();
|
||||
|
||||
public class AlbumSongQueryMediaTrack
|
||||
{
|
||||
[JsonPropertyName("position")]
|
||||
public int Track {get;set;} = 1;
|
||||
|
||||
[JsonPropertyName("recording")]
|
||||
public AlbumSongQueryMediaTrackRecording Recording {get;set;}=new AlbumSongQueryMediaTrackRecording();
|
||||
|
||||
[JsonPropertyName("length")]
|
||||
public long Length {get;set;} = 0;
|
||||
|
||||
public class AlbumSongQueryMediaTrackRecording
|
||||
{
|
||||
[JsonPropertyName("title")]
|
||||
public string Name {get;set;}="";
|
||||
|
||||
[JsonPropertyName("id")]
|
||||
public Guid Id {get;set;}
|
||||
|
||||
[JsonPropertyName("artist-credit")]
|
||||
public List<AlbumSongQueryMediaTrackRecordingArtists> ContributingArtists {get;set;}=new List<AlbumSongQueryMediaTrackRecordingArtists>();
|
||||
|
||||
|
||||
|
||||
public class AlbumSongQueryMediaTrackRecordingArtists
|
||||
{
|
||||
[JsonPropertyName("joinphrase")]
|
||||
public string JoinPhrase {get;set;}="";
|
||||
[JsonPropertyName("artist")]
|
||||
public AlbumSongQueryMediaTrackRecordingArtistsArtist Artist {get;set;}=new AlbumSongQueryMediaTrackRecordingArtistsArtist();
|
||||
|
||||
public class AlbumSongQueryMediaTrackRecordingArtistsArtist
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string Name {get;set;}="";
|
||||
[JsonPropertyName("id")]
|
||||
public Guid Id {get;set;}
|
||||
|
||||
[JsonPropertyName("disambiguation")]
|
||||
public string Disambiguation {get;set;}="";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class AlbumTrack {
|
||||
public long Id {get;set;} = 0;
|
||||
|
||||
public string AlbumId {get;set;}="";
|
||||
|
||||
public string SongId {get;set;}="";
|
||||
|
||||
public int Track {get;set;}=0;
|
||||
|
||||
public long Length {get;set;}=0;
|
||||
}
|
||||
|
||||
public class AlbumSongTrack {
|
||||
public string AlbumId {get;set;}="";
|
||||
public string SongId {get;set;} = "";
|
||||
|
||||
public int Track {get;set;}
|
||||
|
||||
public string SongName {get;set;}="";
|
||||
|
||||
public long Length {get;set;}=0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class Artist {
|
||||
public long Id {get;set;}=0;
|
||||
|
||||
public string ArtistId {get;set;}="";
|
||||
|
||||
public string ArtistDisambiguation {get;set;}="";
|
||||
|
||||
public string ArtistName {get;set;}="";
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
|
||||
public class ArtistQuery {
|
||||
[JsonPropertyName("artists")]
|
||||
public List<ArtistQueryItem> Artists {get;set;}=new List<ArtistQueryItem>();
|
||||
|
||||
public class ArtistQueryItem
|
||||
{
|
||||
[JsonPropertyName("id")]
|
||||
public Guid Id {get;set;}
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name {get;set;}="";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class AudioDBArtistJsonResponse {
|
||||
[JsonPropertyName("artists")]
|
||||
public List<AudioDBArtistJsonResponseArtist> Artists {get;set;}=new List<AudioDBArtistJsonResponseArtist>();
|
||||
|
||||
public class AudioDBArtistJsonResponseArtist
|
||||
{
|
||||
[JsonPropertyName("strArtistThumb")]
|
||||
public string Thumbnail {get;set;}="";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json.Serialization;
|
||||
using Tesses.WebServer;
|
||||
using YoutubeExplode.Videos;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class MediaEntry {
|
||||
public string AlbumArtist {get;set;}="";
|
||||
|
||||
public string AlbumName {get;set;}="";
|
||||
|
||||
|
||||
public string SongName {get;set;} = "";
|
||||
|
||||
public string AlbumId {get;set;}="";
|
||||
|
||||
public List<string> ContributingArtists {get;set;}=new List<string>();
|
||||
|
||||
public string ContributingArtistsString => string.Join("; ", ContributingArtists.Select(e=>e.Replace(";","")));
|
||||
|
||||
public int TrackIndex {get;set;}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var trackIndex = TrackIndex.ToString("D2");
|
||||
return Path.Combine("data","Music",ServerContext.FixFileName(AlbumArtist),ServerContext.FixFileName(AlbumName),$"{trackIndex} {ServerContext.FixFileName(SongName)}.mp3");
|
||||
}
|
||||
|
||||
public async Task<bool> ImportAsync(string srcPath)
|
||||
{
|
||||
string dest = ToString();
|
||||
if(File.Exists(dest)) return true;
|
||||
using Process p = new Process();
|
||||
p.StartInfo.FileName = "ffmpeg";
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.CreateNoWindow=true;
|
||||
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
p.StartInfo.ArgumentList.Add("-y");
|
||||
p.StartInfo.ArgumentList.Add("-i");
|
||||
p.StartInfo.ArgumentList.Add(srcPath);
|
||||
p.StartInfo.ArgumentList.Add("-i");
|
||||
p.StartInfo.ArgumentList.Add($"data/Thumbnails/Albums/{AlbumId}.jpg");
|
||||
p.StartInfo.ArgumentList.Add("-metadata");
|
||||
p.StartInfo.ArgumentList.Add($"artist={ContributingArtistsString}");
|
||||
p.StartInfo.ArgumentList.Add("-metadata");
|
||||
p.StartInfo.ArgumentList.Add($"album={AlbumName}");
|
||||
p.StartInfo.ArgumentList.Add("-metadata");
|
||||
p.StartInfo.ArgumentList.Add($"album_artist={AlbumArtist}");
|
||||
p.StartInfo.ArgumentList.Add("-metadata");
|
||||
p.StartInfo.ArgumentList.Add($"title={SongName}");
|
||||
p.StartInfo.ArgumentList.Add("-metadata");
|
||||
p.StartInfo.ArgumentList.Add($"track={TrackIndex}");
|
||||
p.StartInfo.ArgumentList.Add("-c:v");
|
||||
p.StartInfo.ArgumentList.Add("copy");
|
||||
p.StartInfo.ArgumentList.Add("-map");
|
||||
p.StartInfo.ArgumentList.Add("0:a");
|
||||
p.StartInfo.ArgumentList.Add("-map");
|
||||
p.StartInfo.ArgumentList.Add("1:v");
|
||||
p.StartInfo.ArgumentList.Add("-id3v2_version");
|
||||
p.StartInfo.ArgumentList.Add("3");
|
||||
p.StartInfo.ArgumentList.Add("-metadata:s:v");
|
||||
p.StartInfo.ArgumentList.Add("title=Album cover");
|
||||
p.StartInfo.ArgumentList.Add("-metadata:s:v");
|
||||
p.StartInfo.ArgumentList.Add("comment=Cover (Front)");
|
||||
|
||||
p.StartInfo.ArgumentList.Add("data/Temp/conv.mp3");
|
||||
if(p.Start())
|
||||
{
|
||||
await p.WaitForExitAsync();
|
||||
if(p.ExitCode == 0)
|
||||
{
|
||||
string? dir=Path.GetDirectoryName(dest);
|
||||
if(!string.IsNullOrWhiteSpace(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
File.Move("data/Temp/conv.mp3",dest);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class Song {
|
||||
public long Id {get;set;}=0;
|
||||
|
||||
public string SongId {get;set;}="";
|
||||
|
||||
|
||||
public string SongName {get;set;}="";
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class SongVideo {
|
||||
public long Id {get;set;}=0;
|
||||
|
||||
public string SongId {get;set;}="";
|
||||
|
||||
public string VideoId {get;set;}="";
|
||||
|
||||
public string VideoTitle {get;set;}="";
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
public enum LogEntryType {
|
||||
VideoStarted,
|
||||
VideoFinished,
|
||||
Bell,
|
||||
Started,
|
||||
Unknown
|
||||
}
|
||||
|
||||
public class LogEntry {
|
||||
public long Time {get;set;}
|
||||
[JsonIgnore]
|
||||
public DateTimeOffset DateTime => DateTimeOffset.FromUnixTimeSeconds(Time);
|
||||
|
||||
|
||||
|
||||
public string Type {get;set;}="";
|
||||
|
||||
[JsonIgnore]
|
||||
public LogEntryType EventType {
|
||||
get {
|
||||
if(Enum.TryParse<LogEntryType>(Type,out var type))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
return LogEntryType.Unknown;
|
||||
}
|
||||
set => Type = value.ToString();
|
||||
}
|
||||
|
||||
|
||||
public string? VideoTitle {get;set;}
|
||||
|
||||
public string? VideoId {get;set;}
|
||||
|
||||
public string? ChannelTitle {get;set;}
|
||||
|
||||
public string? ChannelId {get;set;}
|
||||
[JsonIgnore]
|
||||
[MemberNotNullWhen(true,nameof(VideoTitle),nameof(VideoId),nameof(ChannelTitle),nameof(ChannelId))]
|
||||
public bool HasStrings => !string.IsNullOrEmpty(VideoTitle) && !string.IsNullOrEmpty(VideoId) && !string.IsNullOrEmpty(ChannelTitle) && !string.IsNullOrEmpty(ChannelId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Tesses.YouTubeDownloader2025Companion;
|
||||
|
||||
public class Webhook {
|
||||
public string Type {get;set;}="";
|
||||
|
||||
public WebhookVideo Video {get;set;}=new WebhookVideo();
|
||||
|
||||
public class WebhookVideo
|
||||
{
|
||||
public string Channel {get;set;}="";
|
||||
|
||||
public string ChannelId {get;set;}="";
|
||||
|
||||
public string Title {get;set;}="";
|
||||
|
||||
public string VideoId {get;set;}="";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user