Add project files.
This commit is contained in:
31
YoutubeMP3.sln
Normal file
31
YoutubeMP3.sln
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.9.34728.123
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YoutubeMP3", "YoutubeMP3\YoutubeMP3.csproj", "{81D4D628-0F48-45AB-B876-78A7C82A0BAA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{81D4D628-0F48-45AB-B876-78A7C82A0BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{81D4D628-0F48-45AB-B876-78A7C82A0BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{81D4D628-0F48-45AB-B876-78A7C82A0BAA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{81D4D628-0F48-45AB-B876-78A7C82A0BAA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{81D4D628-0F48-45AB-B876-78A7C82A0BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{81D4D628-0F48-45AB-B876-78A7C82A0BAA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{81D4D628-0F48-45AB-B876-78A7C82A0BAA}.Release|x86.ActiveCfg = Release|x86
|
||||
{81D4D628-0F48-45AB-B876-78A7C82A0BAA}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {152E27E1-FB89-4830-B61A-358F2F47D0CB}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
10
YoutubeMP3/App.axaml
Normal file
10
YoutubeMP3/App.axaml
Normal file
@@ -0,0 +1,10 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="YoutubeMP3.App"
|
||||
RequestedThemeVariant="Default">
|
||||
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
24
YoutubeMP3/App.axaml.cs
Normal file
24
YoutubeMP3/App.axaml.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace YoutubeMP3
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
desktop.MainWindow = new MainWindow();
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
239
YoutubeMP3/Handler.cs
Normal file
239
YoutubeMP3/Handler.cs
Normal file
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using SpotifyAPI.Web;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
namespace YoutubeMP3
|
||||
{
|
||||
public struct MediaInfo
|
||||
{
|
||||
public string Id;
|
||||
public string Spotify_URI;
|
||||
public string Title;
|
||||
public string Artist;
|
||||
public string Genre;
|
||||
public string Album;
|
||||
public string Albumart_loc;
|
||||
public string ReleaseDate;
|
||||
}
|
||||
|
||||
public class Handler
|
||||
{
|
||||
|
||||
public async static Task<string> HandleAll(string link)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
checkedForChange();
|
||||
}
|
||||
|
||||
DownloadSongViaYoutube(link);
|
||||
Debug.WriteLine("Song Downloaded");
|
||||
var difference = checkedForChange();
|
||||
Debug.WriteLine("Difference " + difference);
|
||||
if (difference != null && difference != "")
|
||||
{
|
||||
Debug.WriteLine("Saving metadata");
|
||||
EmbedInfo(difference,await ConnectToSpotify(difference));
|
||||
|
||||
return System.IO.Path.GetFileNameWithoutExtension(difference);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static List<string> items;
|
||||
|
||||
private static string? checkedForChange()
|
||||
{
|
||||
var saveLocation = Pref.GetInstance().Options.SaveLocation;
|
||||
if (items == null)
|
||||
{
|
||||
items = [.. GetMP3Files(saveLocation)];
|
||||
return null;
|
||||
}
|
||||
var temp = GetMP3Files(saveLocation);
|
||||
Debug.WriteLine("temp " + string.Join(" ", temp));
|
||||
var difference = temp.Except(items).ToList();
|
||||
Debug.WriteLine("Full difference " + string.Join(" ", difference));
|
||||
items = temp.ToList();
|
||||
return difference.FirstOrDefault("");
|
||||
|
||||
}
|
||||
|
||||
public static string[] GetMP3Files(string folderPath)
|
||||
{
|
||||
// Check if the folder exists
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
throw new ArgumentException("The specified folder path does not exist.");
|
||||
}
|
||||
|
||||
// Get all files in the folder
|
||||
string[] files = Directory.GetFiles(folderPath);
|
||||
|
||||
// Filter files with the .mp3 extension
|
||||
return files.Where(f => System.IO.Path.GetExtension(f).ToLower() == ".mp3").ToArray();
|
||||
}
|
||||
|
||||
public async static Task<MediaInfo> ConnectToSpotify(String path)
|
||||
{
|
||||
var config = SpotifyClientConfig.CreateDefault();
|
||||
var spotify = new SpotifyClient(config.WithToken(await GetSpotifyAccessToken()));
|
||||
|
||||
var fileName = System.IO.Path.GetFileNameWithoutExtension(path);
|
||||
Debug.WriteLine("Connecting to spotify for: " + fileName);
|
||||
|
||||
string pattern = @"\s*[\(\[]\s*(Official Video|Official Music Video|Official 4k Video|Official Music video|Official Video|Lyrics|lyrics)\s*[\)\]]";
|
||||
fileName = Regex.Replace(fileName, pattern, "", RegexOptions.IgnoreCase);
|
||||
Debug.WriteLine("After Regex?: " + fileName);
|
||||
|
||||
var result = await spotify.Search.Item(new SearchRequest(SearchRequest.Types.Track, fileName));
|
||||
if (result == null)
|
||||
{
|
||||
Debug.WriteLine($"Error - {System.IO.Path.GetFileNameWithoutExtension(path)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
MediaInfo info = new MediaInfo();
|
||||
info.Artist = result.Tracks.Items[0].Artists[0].Name;
|
||||
info.Title = result.Tracks.Items[0].Name;
|
||||
|
||||
info.ReleaseDate = result.Tracks.Items[0].Album.ReleaseDate;
|
||||
info.Album = result.Tracks.Items[0].Album.Name;
|
||||
info.Id = result.Tracks.Items[0].Id;
|
||||
info.Spotify_URI = result.Tracks.Items[0].Uri;
|
||||
var artist = await spotify.Search.Item(new SearchRequest(SearchRequest.Types.Artist, result.Tracks.Items.First().Artists.First().Name));
|
||||
var artist2 = artist.Artists.Items.First();
|
||||
info.Genre =string.Join(", ",(artist2.Genres));
|
||||
return info;
|
||||
|
||||
}
|
||||
//HttpClient client = new HttpClient();
|
||||
//Debug.WriteLine(fileName);
|
||||
|
||||
//fileName = Uri.EscapeDataString(fileName);
|
||||
|
||||
//string url = "https://api.spotify.com/v1/search?" + fileName + "&type=track";
|
||||
//client.DefaultRequestHeaders.Add("Authorization", "Bearer " + await GetSpotifyAccessToken());
|
||||
//HttpResponseMessage response = await client.GetAsync(url);
|
||||
//Debug.WriteLine(await GetSpotifyAccessToken());
|
||||
//if (response.IsSuccessStatusCode)
|
||||
//{
|
||||
// // Handle successful response
|
||||
// string content = await response.Content.ReadAsStringAsync();
|
||||
// dynamic data = JsonConvert.DeserializeObject<dynamic>(content);
|
||||
// var album = data.items[0].album.name;
|
||||
// var artist = data.items[0].artist[0].name;
|
||||
// var title = data.items[0].name;
|
||||
// var id = data.items[0].id;
|
||||
// var genre = data.items[0].artist[0].genre;
|
||||
// var release = data.items[0].album[0].release_date;
|
||||
// MediaInfo info = new MediaInfo();
|
||||
// info.Artist = artist;
|
||||
// info.Title = title;
|
||||
// info.Genre = genre;
|
||||
// info.ReleaseDate = release;
|
||||
// info.Album = album;
|
||||
// info.Id = id;
|
||||
// Debug.WriteLine(info);
|
||||
// Debug.WriteLine(info.ReleaseDate);
|
||||
// return info;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Debug.WriteLine($"Error - {Path.GetFileNameWithoutExtension(path)}");
|
||||
// Debug.WriteLine(await response.Content.ReadAsStringAsync());
|
||||
// // Handle error response
|
||||
//}
|
||||
//@TODO Finish
|
||||
return new MediaInfo();
|
||||
}
|
||||
|
||||
public static bool DownloadSongViaYoutube(string link)
|
||||
{
|
||||
string ytDlpPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"asset\helpers\yt-dlp.exe");
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = ytDlpPath,
|
||||
Arguments = "-P \""+ Pref.GetInstance().Options.SaveLocation + "\" -x --audio-format mp3 --audio-quality 0 -o \"%(title)s.%(ext)s\" " + link,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
Process process = Process.Start(startInfo);
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
Debug.WriteLine(startInfo.Arguments);
|
||||
process.WaitForExit();
|
||||
Debug.WriteLine(output);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool EmbedInfo(String path, MediaInfo info) {
|
||||
string ffmpegPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"asset\helpers\ffmpeg.exe");
|
||||
var filename = System.IO.Path.GetFileNameWithoutExtension(path);
|
||||
var result = Pref.GetInstance().Options.SaveLocation + "\\" + filename+"tmp.mp3";
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = ffmpegPath,
|
||||
Arguments = $"-i \"{path}\" -y -c:v copy -metadata artist=\"{info.Artist}\" -metadata title=\"{info.Artist}\" -metadata album=\"{info.Album}\"" +
|
||||
$" -metadata genre=\"{info.Genre}\" -metadata year=\"{info.ReleaseDate}\" \"{result}\"",
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
Process process = Process.Start(startInfo);
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
Debug.WriteLine(output);
|
||||
if(System.IO.File.Exists(result))System.IO.File.Move(result, path, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void UpdateYoutube()
|
||||
{
|
||||
string ytDlpPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"asset\helpers\yt-dlp.exe");
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = ytDlpPath,
|
||||
Arguments = "--update",
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
Process process = Process.Start(startInfo);
|
||||
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
|
||||
Console.WriteLine(output);
|
||||
}
|
||||
|
||||
public async static Task<string> GetSpotifyAccessToken()
|
||||
{
|
||||
|
||||
var options = Pref.GetInstance().Options;
|
||||
if(options.AccessToken != "" && options.AccessTokenDate != null && (DateTime.Now - options.AccessTokenDate).Value.TotalHours <= 1)
|
||||
{
|
||||
return options.AccessToken;
|
||||
}
|
||||
Debug.WriteLine("Getting Access Token");
|
||||
string clientId = options.ClientID;
|
||||
string clientSecret = options.ClientSecret;
|
||||
|
||||
var config = SpotifyClientConfig.CreateDefault();
|
||||
|
||||
var request = new ClientCredentialsRequest(clientId, clientSecret);
|
||||
var response = await new OAuthClient(config).RequestToken(request);
|
||||
options.AccessToken = response.AccessToken;
|
||||
options.AccessTokenDate = DateTime.Now;
|
||||
Pref.GetInstance().SaveOptions();
|
||||
return response.AccessToken;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
117
YoutubeMP3/MainWindow.axaml
Normal file
117
YoutubeMP3/MainWindow.axaml
Normal file
@@ -0,0 +1,117 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
Icon="/asset/icon/websitelogo.png"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="YoutubeMP3.MainWindow"
|
||||
Title="Youtube To MP3">
|
||||
<Window.Styles>
|
||||
<Style Selector="TextBlock.h1">
|
||||
<Setter Property="FontSize" Value="24"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
</Style>
|
||||
</Window.Styles>
|
||||
<StackPanel Margin="5">
|
||||
<Grid>
|
||||
<Label HorizontalAlignment="Center" Margin="10" FontWeight="Heavy" FontSize="24">Youtube To MP3</Label>
|
||||
</Grid>
|
||||
<TabControl Margin="">
|
||||
<!-- MAIN DOWNLOAD-->
|
||||
<TabItem Header="Download">
|
||||
<DockPanel>
|
||||
<StackPanel Margin="5" DockPanel.Dock="Top">
|
||||
<Label>Items to download:</Label>
|
||||
<TextBox Height="100" AcceptsReturn="True" TextWrapping="WrapWithOverflow" ToolTip.Tip="Seperate each item with a new line" Name="Download_List"/>
|
||||
<Button Click="HandleDownload">Download</Button>
|
||||
<!--<ProgressBar ShowProgressText="True" Minimum="0" Maximum="100" Name="Progress_Bar"></ProgressBar>-->
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Margin="5" DockPanel.Dock="Bottom">
|
||||
<Label>Finished:</Label>
|
||||
<ProgressBar Margin="0 10" Height="20" Minimum="0" Maximum="100" ShowProgressText="True" Name="progress_download"/>
|
||||
<TextBlock xml:space="preserve" Name="Finish_box"/>
|
||||
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
|
||||
<!-- LOCAL TABS-->
|
||||
<TabItem Header="Local">
|
||||
<StackPanel>
|
||||
<Button Click="HandleLocal">Process Folder</Button>
|
||||
<ProgressBar Margin="0 10" Height="20" Minimum="0" Maximum="100" ShowProgressText="True" Name="progress_local"/>
|
||||
</StackPanel>
|
||||
|
||||
</TabItem>
|
||||
|
||||
<!-- LOGS @TODO-->
|
||||
<TabItem Header="Logs">
|
||||
<TextBlock>Hello. Work in progress. Good luck if the program doesn't work</TextBlock>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<!--Setting Tabs-->
|
||||
<TabItem Header="Others">
|
||||
<StackPanel>
|
||||
<Grid ColumnDefinitions="Auto,6*,1*" Margin="4" ShowGridLines="False">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Label Grid.Column="0" Grid.Row="0" VerticalAlignment="Center">
|
||||
Client ID:
|
||||
</Label>
|
||||
<TextBox Margin="4" VerticalAlignment="Center" Grid.Column="1" Grid.Row="0" ToolTip.Tip="Ask kareem for how to do this" Name="API_Key"/>
|
||||
<Label Grid.Column="0" Grid.Row="1" VerticalAlignment="Center">
|
||||
Client Secrete:
|
||||
</Label>
|
||||
<TextBox Margin="4" PasswordChar="*" VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" ToolTip.Tip="Ask kareem for how to do this" Name="Secret"/>
|
||||
<Label Grid.Column="0" Grid.Row="2" VerticalAlignment="Center">
|
||||
Save Location:
|
||||
</Label>
|
||||
<TextBox Margin="4" Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" Name="Save_Location"/>
|
||||
<Button Grid.Column="2" Grid.Row="2" Click="HandleOpen">Open Folder</Button>
|
||||
<Label Grid.Column="0" Grid.Row="3" VerticalAlignment="Center">
|
||||
Log Location:
|
||||
</Label>
|
||||
<TextBox IsReadOnly="true" Margin="4" Grid.Column="1" Grid.Row="3" VerticalAlignment="Center" Name="Log_Location"/>
|
||||
|
||||
</Grid>
|
||||
<Button Click="HandleSave">Save Setting</Button>
|
||||
<Button Click="HandleUpdate">Update Program</Button>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
<!--Info Tab-->
|
||||
<TabItem Header="Info">
|
||||
<StackPanel Margin="5">
|
||||
<Label> Hello. </Label>
|
||||
<Label>
|
||||
<TextBlock TextWrapping="Wrap" xml:space="preserve">
|
||||
To update or change settings, use "others" tab.
|
||||
Update buttons updates the youtube downloaded, not this program. Haven't built that in yet
|
||||
|
||||
Limitation:
|
||||
You can't delete or add things to output folder when it processing youtube links
|
||||
Some youtube titles don't have enough info or random info that messes up the search
|
||||
It uses spotify search and just takes the first result (most likely what you want) so if may match the wrong thing or doesn't find anything at all, blame spotify. Maybe change the file name and hope the search will get the right thing.
|
||||
It doesn't check what it already checked btw so I suggest moving things so it doesn't just the same thing over over again.
|
||||
Logs don't work so if something goes wrong, good luck.
|
||||
</TextBlock>
|
||||
</Label>
|
||||
<Panel>
|
||||
<Label HorizontalAlignment="Left"> Songs Downloaded: </Label>
|
||||
<TextBlock Name="Song_DW" HorizontalAlignment="Center"> 0 </TextBlock>
|
||||
</Panel>
|
||||
<Label VerticalAlignment="Bottom" HorizontalAlignment="Right">Version: Alpha 0.1.1 - 23.04.24</Label>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
</TabControl >
|
||||
</StackPanel>
|
||||
|
||||
|
||||
</Window>
|
||||
132
YoutubeMP3/MainWindow.axaml.cs
Normal file
132
YoutubeMP3/MainWindow.axaml.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text.RegularExpressions;
|
||||
using Avalonia;
|
||||
using Avalonia.Platform.Storage;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using System.Collections.Immutable;
|
||||
using System;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace YoutubeMP3
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
Regex youtubeRegex = new Regex(@"^(https?:\/\/)?(www\.)?((youtube\.com\/watch\?v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})$");
|
||||
private Pref pref = Pref.GetInstance();
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Save_Location.Text = pref.Options.SaveLocation;
|
||||
API_Key.Text = pref.Options.ClientID;
|
||||
Secret.Text = pref.Options.ClientSecret;
|
||||
Log_Location.Text = pref.log_Location;
|
||||
UpdateSongCount();
|
||||
}
|
||||
|
||||
public void UpdateSongCount()
|
||||
{
|
||||
Song_DW.Text = pref.Options.Count + "";
|
||||
|
||||
}
|
||||
|
||||
public async void HandleLocal(object source, RoutedEventArgs args)
|
||||
{
|
||||
Debug.WriteLine("Local Click Starting");
|
||||
var files = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions());
|
||||
List<string> listofPaths = new List<string>();
|
||||
|
||||
foreach (var file in files.ToImmutableList()) {
|
||||
listofPaths.Add(file.TryGetLocalPath());
|
||||
}
|
||||
|
||||
List<string> mp3 = new List<string>();
|
||||
|
||||
foreach (var path in listofPaths)
|
||||
{
|
||||
mp3.AddRange(GetMP3Files(path));
|
||||
}
|
||||
progress_local.Maximum = mp3.Count;
|
||||
for (int i = 0; i < mp3.Count; i++)
|
||||
{
|
||||
string? song = mp3[i];
|
||||
progress_local.Value = i;
|
||||
var mediaInfo = await Handler.ConnectToSpotify(song);
|
||||
Handler.EmbedInfo(song, mediaInfo);
|
||||
}
|
||||
progress_local.Value = progress_local.Maximum;
|
||||
|
||||
}
|
||||
|
||||
public async void HandleDownload(object source, RoutedEventArgs args)
|
||||
{
|
||||
Debug.WriteLine("Download Click Starting");
|
||||
string text = Download_List.Text;
|
||||
if(text == null || text.Length == 0) { return; }
|
||||
string[] raw_links = text.Split();
|
||||
List<string> links = new List<string>();
|
||||
for(int i = 0; i < raw_links.Length; i++)
|
||||
{
|
||||
var link = raw_links[i];
|
||||
//Debug.WriteLine(link + ' ' + youtubeRegex.IsMatch(link));
|
||||
//if (youtubeRegex.IsMatch(link))
|
||||
//{
|
||||
links.Add(link);
|
||||
//}
|
||||
//}
|
||||
}
|
||||
progress_download.Maximum = links.Count;
|
||||
for (int i = 0;i < links.Count; i++)
|
||||
{
|
||||
progress_download.Value = i;
|
||||
var link = links[i];
|
||||
var result = await Handler.HandleAll(link);
|
||||
Finish_box.Text += '\n' + result;
|
||||
pref.Options.Count++;
|
||||
UpdateSongCount();
|
||||
//Progress_Bar.Value = i/links.Count*100;
|
||||
Debug.WriteLine("Finished Downloading");
|
||||
}
|
||||
progress_download.Value = progress_download.Maximum;
|
||||
pref.SaveOptions();
|
||||
}
|
||||
|
||||
public void HandleUpdate(object source, RoutedEventArgs args)
|
||||
{
|
||||
Handler.UpdateYoutube();
|
||||
}
|
||||
|
||||
public void HandleSave(object source, RoutedEventArgs args)
|
||||
{
|
||||
pref.Options.SaveLocation = Save_Location.Text != null ? Save_Location.Text : null;
|
||||
pref.Options.ClientID = API_Key.Text != null ? API_Key.Text : null;
|
||||
pref.Options.ClientSecret = Secret.Text != null ? Secret.Text : null;
|
||||
pref.log_Location = Log_Location.Text != null ? Log_Location.Text : null;
|
||||
pref.SaveOptions();
|
||||
}
|
||||
|
||||
public void HandleOpen(object source, RoutedEventArgs args)
|
||||
{
|
||||
Process.Start("explorer.exe", pref.Options.SaveLocation);
|
||||
}
|
||||
public static string[] GetMP3Files(string folderPath)
|
||||
{
|
||||
// Check if the folder exists
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
throw new ArgumentException("The specified folder path does not exist.");
|
||||
}
|
||||
|
||||
// Get all files in the folder
|
||||
string[] files = Directory.GetFiles(folderPath);
|
||||
|
||||
// Filter files with the .mp3 extension
|
||||
return files.Where(f => Path.GetExtension(f).ToLower() == ".mp3").ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
82
YoutubeMP3/Pref.cs
Normal file
82
YoutubeMP3/Pref.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace YoutubeMP3
|
||||
{
|
||||
public class Pref
|
||||
{
|
||||
private static readonly Pref instance = new Pref();
|
||||
private string OptionsFilePath = "program_options.txt";//place holder
|
||||
private ProgramOptions options;
|
||||
|
||||
public ProgramOptions Options { get => options;}
|
||||
|
||||
public class ProgramOptions
|
||||
{
|
||||
public string SaveLocation { get; set; }
|
||||
public int Count { get; set; }
|
||||
public string AccessToken { get; set; }
|
||||
public string ClientID { get; set; }
|
||||
public string ClientSecret { get; set; }
|
||||
public DateTime? AccessTokenDate { get; set; }
|
||||
|
||||
public ProgramOptions(string saveLocation, int count, string clientID, string clientSecret, string accessToken, DateTime? accessTokenDate)
|
||||
{
|
||||
SaveLocation = saveLocation;
|
||||
Count = count;
|
||||
ClientSecret = clientSecret;
|
||||
AccessToken = accessToken;
|
||||
ClientID = clientID;
|
||||
AccessTokenDate = accessTokenDate;
|
||||
}
|
||||
}
|
||||
|
||||
public string tempLocation;
|
||||
public string log_Location;
|
||||
|
||||
|
||||
private Pref()
|
||||
{
|
||||
OptionsFilePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)+"\\KareemSoft\\Youtube To MP3";
|
||||
options = LoadOptions();
|
||||
tempLocation = OptionsFilePath + "\\Temp";
|
||||
log_Location = OptionsFilePath + "\\logs";
|
||||
}
|
||||
|
||||
public void SaveOptions()
|
||||
{
|
||||
SaveOptions(Options);
|
||||
}
|
||||
|
||||
public void SaveOptions(ProgramOptions options)
|
||||
{
|
||||
string optionsJson = JsonConvert.SerializeObject(options);
|
||||
string directoryPath = Path.GetDirectoryName(OptionsFilePath + "\\Pref.json");
|
||||
if (!Directory.Exists(directoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
File.WriteAllText(OptionsFilePath + "\\Pref.txt", optionsJson);
|
||||
}
|
||||
|
||||
public ProgramOptions LoadOptions()
|
||||
{
|
||||
if (!File.Exists(OptionsFilePath + "\\Pref.txt"))
|
||||
{
|
||||
ProgramOptions options = new ProgramOptions(OptionsFilePath + "\\Save", 0, "8e11101265aa4f64be2714df213dd66e", "2910807a1441420dac44cd494b3d6b96","", null);
|
||||
SaveOptions(options);
|
||||
return options;
|
||||
}
|
||||
|
||||
string optionsJson = File.ReadAllText(OptionsFilePath + "\\Pref.txt");
|
||||
return JsonConvert.DeserializeObject<ProgramOptions>(optionsJson);
|
||||
}
|
||||
|
||||
public static Pref GetInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
YoutubeMP3/Program.cs
Normal file
22
YoutubeMP3/Program.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Avalonia;
|
||||
using System;
|
||||
|
||||
namespace YoutubeMP3
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
[STAThread]
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.WithInterFont()
|
||||
.LogToTrace();
|
||||
}
|
||||
}
|
||||
10
YoutubeMP3/Styles1.axaml
Normal file
10
YoutubeMP3/Styles1.axaml
Normal file
@@ -0,0 +1,10 @@
|
||||
<Styles xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Design.PreviewWith>
|
||||
<Border Padding="20">
|
||||
<!-- Add Controls for Previewer Here -->
|
||||
</Border>
|
||||
</Design.PreviewWith>
|
||||
|
||||
<!-- Add Styles Here -->
|
||||
</Styles>
|
||||
55
YoutubeMP3/YoutubeMP3.csproj
Normal file
55
YoutubeMP3/YoutubeMP3.csproj
Normal file
@@ -0,0 +1,55 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
<StartupObject>YoutubeMP3.Program</StartupObject>
|
||||
<ApplicationIcon>asset\icon\websitelogo.ico</ApplicationIcon>
|
||||
<SignAssembly>False</SignAssembly>
|
||||
<Platforms>AnyCPU;x86</Platforms>
|
||||
<AnalysisLevel>latest-recommended</AnalysisLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.10" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.10" />
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.10" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.10" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SpotifyAPI.Web" Version="7.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<UpToDateCheckInput Remove="Styles1.axaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="asset\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Remove="asset\helpers\ffmpeg.exe" />
|
||||
<AvaloniaResource Remove="asset\helpers\yt-dlp.exe" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AvaloniaXaml Remove="asset\Styles1.axaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="asset\icon\websitelogo.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="asset\helpers\ffmpeg.exe">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="asset\helpers\yt-dlp.exe">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Update="asset\Styles1.axaml">
|
||||
<SubType>Designer</SubType>
|
||||
</AvaloniaResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
18
YoutubeMP3/app.manifest
Normal file
18
YoutubeMP3/app.manifest
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<!-- This manifest is used on Windows only.
|
||||
Don't remove it as it might cause problems with window transparency and embedded controls.
|
||||
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
|
||||
<assemblyIdentity version="1.0.0.0" name="YoutubeMP3.Desktop"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
11
YoutubeMP3/asset/Styles1.axaml
Normal file
11
YoutubeMP3/asset/Styles1.axaml
Normal file
@@ -0,0 +1,11 @@
|
||||
<Styles xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Design.PreviewWith>
|
||||
<Border Padding="20">
|
||||
<!-- Add Controls for Previewer Here -->
|
||||
</Border>
|
||||
</Design.PreviewWith>
|
||||
|
||||
<!-- Add Styles Here -->
|
||||
|
||||
</Styles>
|
||||
BIN
YoutubeMP3/asset/helpers/ffmpeg.exe
Normal file
BIN
YoutubeMP3/asset/helpers/ffmpeg.exe
Normal file
Binary file not shown.
BIN
YoutubeMP3/asset/helpers/yt-dlp.exe
Normal file
BIN
YoutubeMP3/asset/helpers/yt-dlp.exe
Normal file
Binary file not shown.
BIN
YoutubeMP3/asset/icon/websitelogo.ico
Normal file
BIN
YoutubeMP3/asset/icon/websitelogo.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
BIN
YoutubeMP3/asset/icon/websitelogo.png
Normal file
BIN
YoutubeMP3/asset/icon/websitelogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
Reference in New Issue
Block a user