diff --git a/windows/Audio/AudioPlay.cs b/windows/Audio/AudioPlay.cs index 5ce4a09..ce387f0 100644 --- a/windows/Audio/AudioPlay.cs +++ b/windows/Audio/AudioPlay.cs @@ -7,16 +7,37 @@ namespace Musiche.Audio public delegate void PlatStateChangedEventHandler(object sender, PlaybackState state); public class AudioPlay { - MediaFoundationReader mediaFoundationReader = null; + AudioFileReader mediaFoundationReader = null; WaveOut wasapiOut = null; public event PlatStateChangedEventHandler PlatStateChanged; public Dispatcher Dispatcher; + readonly DispatcherTimer fadeInTimer; + float fadeInVolume = 0; + bool fadeIn = false; public AudioPlay() { Dispatcher = Dispatcher.CurrentDispatcher; + fadeInTimer = new DispatcherTimer(); + fadeInTimer.Interval = TimeSpan.FromMilliseconds(100); + fadeInTimer.Tick += OnFadeInTimerTick; wasapiOut = new WaveOut(); } + private void OnFadeInTimerTick(object sender, EventArgs e) + { + if (fadeInVolume > 0 && fadeInVolume > wasapiOut.Volume && fadeInVolume <= 1) + { + wasapiOut.Volume = (float)Math.Min(fadeInVolume, wasapiOut.Volume + 0.1); + Logger.Logger.Debug("设置淡入声音", wasapiOut.Volume); + } + else + { + fadeInVolume = 0; + (sender as DispatcherTimer).Stop(); + Logger.Logger.Debug("结束淡入声音", fadeInVolume); + } + } + private void WasapiOut_PlaybackStopped(object sender, StoppedEventArgs e) { PlatStateChanged?.Invoke(this, PlaybackState.Stopped); @@ -38,11 +59,11 @@ public void Play(string url) wasapiOut?.Dispose(); try { - mediaFoundationReader = new MediaFoundationReader(url); + mediaFoundationReader = new AudioFileReader(url); wasapiOut = new WaveOut(); - Volume = _volume; wasapiOut.PlaybackStopped += WasapiOut_PlaybackStopped; wasapiOut.Init(mediaFoundationReader); + RunFadeIn(); wasapiOut?.Play(); if (_progress > 0) { @@ -55,15 +76,36 @@ public void Play(string url) PlatStateChanged?.Invoke(this, wasapiOut?.PlaybackState ?? PlaybackState.Stopped); } + private void RunFadeIn() + { + if (fadeIn) + { + fadeInVolume = _volume * 1.0f / 100; + wasapiOut.Volume = 0; + fadeInTimer.Start(); + Logger.Logger.Debug("开始淡入声音", fadeInVolume); + } + else + { + Volume = _volume; + } + } + public void Play() { if (mediaFoundationReader != null) { + RunFadeIn(); wasapiOut?.Play(); PlatStateChanged?.Invoke(this, wasapiOut?.PlaybackState ?? PlaybackState.Stopped); } } + public void SetFadeIn(bool fadeIn) + { + this.fadeIn = fadeIn; + } + public void Pause() { if (mediaFoundationReader == null) return; @@ -108,6 +150,7 @@ public int Volume { get { + if (fadeInVolume > 0) return (int)(fadeInVolume * 100); return _volume; } set diff --git a/windows/Hotkey/Hotkey.cs b/windows/Hotkey/Hotkey.cs index b838f11..394a6a9 100644 --- a/windows/Hotkey/Hotkey.cs +++ b/windows/Hotkey/Hotkey.cs @@ -3,10 +3,7 @@ using NHotkey.Wpf; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Text.RegularExpressions; -using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Interop; @@ -33,7 +30,7 @@ public string Register(ShortcutKey shortcutKey) return registerMedia(); } ShortcutType shortcutType = shortcutKey.ParseType(); - if(shortcutType == ShortcutType.None) return "热键注册类型不能为空"; + if (shortcutType == ShortcutType.None) return "热键注册类型不能为空"; ModifierKeys modifierKeys = shortcutKey.ParseModifierKeys(); Key key = shortcutKey.ParseKey(); if (modifierKeys == ModifierKeys.None) return "修饰键不能为空"; diff --git a/windows/Hotkey/ShortcutKey.cs b/windows/Hotkey/ShortcutKey.cs index 7c1bd3f..366548c 100644 --- a/windows/Hotkey/ShortcutKey.cs +++ b/windows/Hotkey/ShortcutKey.cs @@ -1,5 +1,4 @@ using NHotkey; -using NHotkey.Wpf; using System; using System.Linq; using System.Windows.Input; @@ -22,7 +21,7 @@ public ShortcutType ParseType() public static ShortcutType ParseType(string typeString) { - if(string.IsNullOrEmpty(typeString)) return ShortcutType.None; + if (string.IsNullOrEmpty(typeString)) return ShortcutType.None; typeString = typeString.First().ToString().ToUpper() + typeString.Substring(1); if (Enum.TryParse(typeString, out ShortcutType shortcutType)) { diff --git a/windows/Hotkey/ShortcutType.cs b/windows/Hotkey/ShortcutType.cs index b52cbb4..139468e 100644 --- a/windows/Hotkey/ShortcutType.cs +++ b/windows/Hotkey/ShortcutType.cs @@ -1,9 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Musiche.Hotkey +namespace Musiche.Hotkey { } diff --git a/windows/Logger/Logger.cs b/windows/Logger/Logger.cs index b211486..41f0290 100644 --- a/windows/Logger/Logger.cs +++ b/windows/Logger/Logger.cs @@ -3,8 +3,6 @@ using System.Diagnostics; using System.IO; using System.Text; -using System.Windows.Documents; -using System.Windows.Input; using System.Windows.Threading; namespace Musiche.Logger @@ -16,8 +14,8 @@ enum LoggerType Error, Warning, Info, Debug } - private static HashSet streams = new HashSet(); - private static Dispatcher dispatcher = Dispatcher.CurrentDispatcher; + private static readonly HashSet streams = new HashSet(); + private static readonly Dispatcher dispatcher = Dispatcher.CurrentDispatcher; public static void Error(params object[] message) { diff --git a/windows/MainWindow.xaml b/windows/MainWindow.xaml index e9d0e2c..3ff5034 100644 --- a/windows/MainWindow.xaml +++ b/windows/MainWindow.xaml @@ -3,10 +3,11 @@ 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" - xmlns:local="clr-namespace:Musiche" + xmlns:local="clr-namespace:Musiche" xmlns:webview2="clr-namespace:Musiche.Webview2" mc:Ignorable="d" WindowStartupLocation="CenterScreen" Title="" Height="750" Width="1055" MinHeight="750" MinWidth="1055"> + diff --git a/windows/MainWindow.xaml.cs b/windows/MainWindow.xaml.cs index 09da031..0a0cb33 100644 --- a/windows/MainWindow.xaml.cs +++ b/windows/MainWindow.xaml.cs @@ -3,9 +3,12 @@ using Musiche.Server; using Musiche.Webview2; using System; +using System.Diagnostics; using System.IO; using System.Net; using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; using System.Windows; namespace Musiche @@ -15,7 +18,7 @@ namespace Musiche /// public partial class MainWindow : Window { - readonly Webview2Control webview2; + //readonly Webview2Control webview2; readonly AudioPlay audioPlay; readonly WebServer webServer; readonly WebSocketHandler webSocketHandler; @@ -27,12 +30,13 @@ public MainWindow() { InitializeComponent(); audioPlay = new AudioPlay(); - webview2 = new Webview2Control(); + InitWebview2(); + WindowState = WindowState.Minimized; #if DEBUG webServer = new WebServer(54621); - webview2.Control.Source = new Uri("http://127.0.0.1:54621"); + webview2.Control.Source = new Uri("http://127.0.0.1:5173"); string exeDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location); - logStream = File.Open(Path.Combine(exeDirectory, "log."+DateTime.Now.ToString("yyyy-MM-dd")+".log"), FileMode.Append); + logStream = System.IO.File.Open(Path.Combine(exeDirectory, "log." + DateTime.Now.ToString("yyyy-MM-dd") + ".log"), FileMode.Append); #else int port = GetAvailablePort(); webServer = new WebServer(port); @@ -40,7 +44,6 @@ public MainWindow() #endif webSocketHandler = new WebSocketHandler(this, audioPlay); httpHandler = new HttpHandler(this, audioPlay); - InitWebview2(); StateChanged += MainWindow_StateChanged; Closing += MainWindow_Closing; SourceInitialized += MainWindow_SourceInitialized; @@ -101,7 +104,9 @@ private void InitWebview2() { if (Webview2Control.Available) { - Content = webview2; + //Content = webview2; + //Hide(); + webview2.CoreWebView2DOMContentLoaded += Webview2_CoreWebView2DOMContentLoaded; } else { @@ -110,6 +115,46 @@ private void InitWebview2() } } + private void Webview2_CoreWebView2DOMContentLoaded(object sender, Microsoft.Web.WebView2.Core.CoreWebView2DOMContentLoadedEventArgs e) + { + webview2.CoreWebView2DOMContentLoaded -= Webview2_CoreWebView2DOMContentLoaded; + Left = (SystemParameters.PrimaryScreenWidth / 2) - (ActualWidth / 2); + Top = (SystemParameters.PrimaryScreenHeight / 2) - (ActualHeight / 2); + WindowState = WindowState.Normal; + } + + private CancellationTokenSource deleyExitTaskCancel = null; + private bool delayExitShutdown = false; + public void DelayExit(int minute, bool shutdown) + { + delayExitShutdown = shutdown; + deleyExitTaskCancel?.Cancel(); + deleyExitTaskCancel?.Dispose(); + deleyExitTaskCancel = null; + if (minute > 0) + { + deleyExitTaskCancel = new CancellationTokenSource(); + Task.Delay(minute * 60 * 1000, deleyExitTaskCancel.Token).ContinueWith(ExitOnDelay); + } + } + + private void ExitOnDelay(Task sender) + { + if (sender.IsCanceled) return; + Dispatcher.Invoke(() => + { + try + { + if (delayExitShutdown) Process.Start(new ProcessStartInfo("shutdown", "/s /t 30") { UseShellExecute = true }); + } + catch (Exception ex) + { + Logger.Logger.Error("Shutdown Error: ", ex); + } + ExitApp(null, null); + }); + } + private static int GetAvailablePort() { TcpListener listener = new TcpListener(IPAddress.Loopback, 0); diff --git a/windows/NotifyIcon/ModernToolStripRenderer.cs b/windows/NotifyIcon/ModernToolStripRenderer.cs index a2b27d9..dc50b61 100644 --- a/windows/NotifyIcon/ModernToolStripRenderer.cs +++ b/windows/NotifyIcon/ModernToolStripRenderer.cs @@ -1,15 +1,15 @@ -using System.Drawing.Drawing2D; +using System; using System.Drawing; -using System.Windows.Forms; +using System.Drawing.Drawing2D; using System.Runtime.InteropServices; -using System; +using System.Windows.Forms; namespace Musiche.NotifyIcon { public class ModernToolStripRenderer : ToolStripProfessionalRenderer { - private Font iconFont; - private System.Drawing.Text.PrivateFontCollection privateFonts; + private readonly Font iconFont; + private readonly System.Drawing.Text.PrivateFontCollection privateFonts; public ModernToolStripRenderer() { int length = Properties.Resources.iconfont.Length; @@ -125,7 +125,7 @@ protected override void OnRenderImageMargin(ToolStripRenderEventArgs e) protected override void OnRenderItemImage(ToolStripItemImageRenderEventArgs e) { - if(e.Item.Tag != null) + if (e.Item.Tag != null) { e.Graphics.DrawString(e.Item.Tag.ToString(), iconFont, new SolidBrush(e.Item.ForeColor), e.ImageRectangle.X + 5, e.ImageRectangle.Y + 5); } diff --git a/windows/NotifyIcon/NotifyIcon.cs b/windows/NotifyIcon/NotifyIcon.cs index b681d32..6ace80f 100644 --- a/windows/NotifyIcon/NotifyIcon.cs +++ b/windows/NotifyIcon/NotifyIcon.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; diff --git a/windows/NotifyIcon/NotifyIconInfo.cs b/windows/NotifyIcon/NotifyIconInfo.cs index dad6856..28f2a28 100644 --- a/windows/NotifyIcon/NotifyIconInfo.cs +++ b/windows/NotifyIcon/NotifyIconInfo.cs @@ -1,5 +1,4 @@ -using Musiche.Audio; -using Musiche.Server; +using Musiche.Server; using NAudio.Wave; using System; using System.Drawing; @@ -104,7 +103,7 @@ private void LoopTypeChange(object sender, EventArgs e) case "顺": loopType = "order"; break; } if (menuItem == null) return; - webSocketHandler.SendMessage("{\"type\": \"loop\",\"data\":\""+ loopType + "\"}"); + webSocketHandler.SendMessage("{\"type\": \"loop\",\"data\":\"" + loopType + "\"}"); } public void Dispose() @@ -119,7 +118,7 @@ public void SetMusicLoopType(string loopType) case "single": loopType = "单"; break; case "random": loopType = "随"; break; case "order": loopType = "顺"; break; - default : loopType = "环"; break; + default: loopType = "环"; break; } loopTypeMenu.Tag = loopType; loopTypeMenu.Image = new Bitmap(1, 1); diff --git a/windows/Server/FileHandler.cs b/windows/Server/FileHandler.cs index 60cd37a..9470793 100644 --- a/windows/Server/FileHandler.cs +++ b/windows/Server/FileHandler.cs @@ -1,11 +1,7 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO.Compression; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.IO.Compression; namespace Musiche.Server { @@ -59,7 +55,7 @@ public byte[] GetFile(string filePath) public string GetMimeType(string filePath) { - switch(Path.GetExtension(filePath)) + switch (Path.GetExtension(filePath)) { case ".html": return "text/html"; diff --git a/windows/Server/Handler.cs b/windows/Server/Handler.cs index 8e8fab3..627926b 100644 --- a/windows/Server/Handler.cs +++ b/windows/Server/Handler.cs @@ -1,7 +1,6 @@ using Musiche.Audio; using System.Collections.Generic; using System.Threading.Tasks; -using System.Windows; namespace Musiche.Server { diff --git a/windows/Server/HttpHandler.cs b/windows/Server/HttpHandler.cs index 27e60a2..d87da87 100644 --- a/windows/Server/HttpHandler.cs +++ b/windows/Server/HttpHandler.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Net; -using System.Net.Mime; using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -49,7 +48,7 @@ static HttpHandler() public async Task ClipboardIndex(HttpListenerContext ctx) { byte[] data = fileHandler.GetFile(ctx.Request.Url.AbsolutePath); - if(data != null) + if (data != null) { string mimeType = fileHandler.GetMimeType(ctx.Request.Url.AbsolutePath); ctx.Response.StatusCode = (int)HttpStatusCode.OK; @@ -58,7 +57,7 @@ public async Task ClipboardIndex(HttpListenerContext ctx) } else { - ctx.Response.Headers.Set("Location", "/?redirect="+ctx.Request.Url.PathAndQuery); + ctx.Response.Headers.Set("Location", "/?redirect=" + ctx.Request.Url.PathAndQuery); ctx.Response.StatusCode = (int)HttpStatusCode.Redirect; } } @@ -74,6 +73,49 @@ public async Task SetTitle(HttpListenerContext ctx) await SendString(ctx, ""); } + [Router("/fadein")] + public async Task SetFadeIn(HttpListenerContext ctx) + { + string fadeIn = ctx.Request.DataAsString(); + audioPlay.Dispatcher.Invoke(() => + { + audioPlay.SetFadeIn(!string.IsNullOrWhiteSpace(fadeIn)); + }); + await SendString(ctx, ""); + } + + [Router("/delayExit")] + public async Task SetDelayExit(HttpListenerContext ctx) + { + string queryShutdown = ctx.Request.QueryString.Get("shutdown"); + bool shutdown = queryShutdown == "true" || queryShutdown == "1"; + int.TryParse(ctx.Request.DataAsString(), out int delayMinute); + window.Dispatcher.Invoke(() => + { + window.DelayExit(delayMinute, shutdown); + }); + await SendString(ctx, ""); + } + + [Router("/gpu")] + public async Task SetGPU(HttpListenerContext ctx) + { + string disableGPU = ctx.Request.DataAsString(); + window.Dispatcher.Invoke(() => + { + string disableGPUPath = Path.Combine(Musiche.Utils.File.Webview2Path, Musiche.Utils.File.DisableGPUName); + if (!string.IsNullOrWhiteSpace(disableGPU)) + { + File.WriteAllText(disableGPUPath, ""); + } + else if (File.Exists(disableGPUPath)) + { + File.Delete(disableGPUPath); + } + }); + await SendString(ctx, ""); + } + [Router("/play")] public async Task Play(HttpListenerContext ctx) { @@ -257,7 +299,7 @@ public static async Task Proxy(HttpListenerContext ctx) Logger.Logger.Debug("HttpProxy", proxyData.Method, proxyData.Url); proxyResData = await HttpProxy.Request(proxyData); Logger.Logger.Debug("HttpProxy", proxyData.Url, proxyResData.Data.Length, proxyResData.ContentLength); - if(proxyResData.StatusCode > 300 && proxyResData.StatusCode < 310) + if (proxyResData.StatusCode > 300 && proxyResData.StatusCode < 310) { ctx.Response.StatusCode = 200; ctx.Response.ContentType = "application/json"; @@ -360,7 +402,7 @@ public async Task Handle(HttpListenerContext context) } HttpListenerResponse response = context.Response; string router = context.Request.Url?.LocalPath.TrimEnd('/') ?? "*"; - routers.TryGetValue(router, out MethodInfo methodInfo); + routers.TryGetValue(router.ToUpper(), out MethodInfo methodInfo); if (methodInfo == null) { methodInfo = routers["*"]; diff --git a/windows/Server/HttpProxy.cs b/windows/Server/HttpProxy.cs index e6f35b9..346001c 100644 --- a/windows/Server/HttpProxy.cs +++ b/windows/Server/HttpProxy.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Net; -using System.Text; using System.Threading.Tasks; namespace Musiche.Server @@ -41,7 +39,7 @@ public static async Task Request(ProxyRequestData data) { resHeaders.Add(item, response.Headers.Get(item) ?? string.Empty); } - if(data.SetCookieRename && resHeaders.ContainsKey("Set-Cookie")) + if (data.SetCookieRename && resHeaders.ContainsKey("Set-Cookie")) { resHeaders.Add("Set-Cookie-Renamed", resHeaders["Set-Cookie"]); } diff --git a/windows/Server/ProxyRequestData.cs b/windows/Server/ProxyRequestData.cs index 3bb5d71..f6d17b5 100644 --- a/windows/Server/ProxyRequestData.cs +++ b/windows/Server/ProxyRequestData.cs @@ -1,5 +1,4 @@ using Newtonsoft.Json; -using System; using System.Collections.Generic; using System.Text; diff --git a/windows/Server/Utils.cs b/windows/Server/Utils.cs index 58f9e5e..81cc7dd 100644 --- a/windows/Server/Utils.cs +++ b/windows/Server/Utils.cs @@ -18,7 +18,7 @@ public static Dictionary ReadRouter(object obj) foreach (RouterAttribute attribute in attributes) { - routers.Add(attribute.Router, method); + routers.Add(attribute.Router.ToUpper(), method); } } return routers; diff --git a/windows/Server/WebSocketHandler.cs b/windows/Server/WebSocketHandler.cs index d3051c8..f4fb0a9 100644 --- a/windows/Server/WebSocketHandler.cs +++ b/windows/Server/WebSocketHandler.cs @@ -70,7 +70,7 @@ public async Task Handle(HttpListenerContext context) foreach (var message in messageList) { var commands = message.Split(','); - routers.TryGetValue(commands[0], out MethodInfo methodInfo); + routers.TryGetValue(commands[0].ToUpper(), out MethodInfo methodInfo); if (methodInfo != null) { var task = methodInfo.Invoke(this, new object[] { webSocket, commands }) as Task; diff --git a/windows/TaskbarInfo.cs b/windows/TaskbarInfo.cs index a9a5c31..c9f290d 100644 --- a/windows/TaskbarInfo.cs +++ b/windows/TaskbarInfo.cs @@ -1,10 +1,7 @@ -using Musiche.Audio; -using Musiche.Server; +using Musiche.Server; +using Musiche.Utils; using System; -using System.Drawing; -using System.IO; using System.Windows.Media; -using System.Windows.Media.Imaging; using System.Windows.Shell; namespace Musiche @@ -12,8 +9,8 @@ namespace Musiche public class TaskbarInfo { readonly ThumbButtonInfo ToolBarPlayPauseButton; - readonly ImageSource iconPlay = GetBitmapSource(Properties.Resources.tool_play); - readonly ImageSource iconPause = GetBitmapSource(Properties.Resources.tool_pause); + readonly ImageSource iconPlay = Properties.Resources.tool_play.ToBitmapSource(); + readonly ImageSource iconPause = Properties.Resources.tool_pause.ToBitmapSource(); readonly WebSocketHandler webSocketHandler; readonly TaskbarItemInfo _taskbarInfo; @@ -30,12 +27,12 @@ public TaskbarInfo(WebSocketHandler webSocketHandler) }; ThumbButtonInfo toolBarLastButton = new ThumbButtonInfo() { - ImageSource = GetBitmapSource(Properties.Resources.tool_last), + ImageSource = Properties.Resources.tool_last.ToBitmapSource(), Description = "上一首", }; ThumbButtonInfo toolBarNextButton = new ThumbButtonInfo() { - ImageSource = GetBitmapSource(Properties.Resources.tool_next), + ImageSource = Properties.Resources.tool_next.ToBitmapSource(), Description = "下一首", }; ToolBarPlayPauseButton.Click += AudioPlayPause; @@ -58,7 +55,7 @@ private void AudioPlayStateChanged(object sender, NAudio.Wave.PlaybackState stat ToolBarPlayPauseButton.ImageSource = iconPlay; ToolBarPlayPauseButton.Description = "播放"; } - if(state == NAudio.Wave.PlaybackState.Stopped) + if (state == NAudio.Wave.PlaybackState.Stopped) { webSocketHandler.SendMessage("{\"type\": \"next\",\"data\": true}"); } @@ -78,17 +75,5 @@ private void AudioLast(object sender, EventArgs e) { webSocketHandler.SendMessage("{\"type\": \"last\"}"); } - - public static BitmapSource GetBitmapSource(Bitmap bmp) - { - BitmapFrame bf; - - using (MemoryStream ms = new MemoryStream()) - { - bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); - bf = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); - } - return bf; - } } } diff --git a/windows/Utils/File.cs b/windows/Utils/File.cs index edb7ce7..5ea8ed0 100644 --- a/windows/Utils/File.cs +++ b/windows/Utils/File.cs @@ -10,6 +10,7 @@ public class File public static readonly string DataPath; public static readonly string StoragePath; public static readonly string Webview2Path; + public static readonly string DisableGPUName = "--disable-gpu"; static File() { diff --git a/windows/Utils/Image.cs b/windows/Utils/Image.cs new file mode 100644 index 0000000..3979075 --- /dev/null +++ b/windows/Utils/Image.cs @@ -0,0 +1,34 @@ +using System.Drawing; +using System.IO; +using System.Windows; +using System.Windows.Interop; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace Musiche.Utils +{ + public static class Image + { + public static BitmapSource ToBitmapSource(this Bitmap bmp) + { + BitmapFrame bf; + + using (MemoryStream ms = new MemoryStream()) + { + bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); + bf = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); + } + return bf; + } + + public static ImageSource ToImageSource(this Icon icon) + { + ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon( + icon.Handle, + Int32Rect.Empty, + BitmapSizeOptions.FromEmptyOptions()); + + return imageSource; + } + } +} diff --git a/windows/Utils/Processor.cs b/windows/Utils/Processor.cs index b04d207..44124ee 100644 --- a/windows/Utils/Processor.cs +++ b/windows/Utils/Processor.cs @@ -1,10 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Reflection; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; namespace Musiche.Utils { @@ -22,25 +18,25 @@ private struct SYSTEM_INFO { internal ushort wProcessorArchitecture; - private ushort wReserved; + private readonly ushort wReserved; - private int dwPageSize; + private readonly int dwPageSize; - private IntPtr lpMinimumApplicationAddress; + private readonly IntPtr lpMinimumApplicationAddress; - private IntPtr lpMaximumApplicationAddress; + private readonly IntPtr lpMaximumApplicationAddress; - private IntPtr dwActiveProcessorMask; + private readonly IntPtr dwActiveProcessorMask; - private int dwNumberOfProcessors; + private readonly int dwNumberOfProcessors; - private int dwProcessorType; + private readonly int dwProcessorType; - private int dwAllocationGranularity; + private readonly int dwAllocationGranularity; - private short wProcessorLevel; + private readonly short wProcessorLevel; - private short wProcessorRevision; + private readonly short wProcessorRevision; } [DllImport("kernel32.dll", SetLastError = true)] diff --git a/windows/Webview2/FileAccessor.cs b/windows/Webview2/FileAccessor.cs index 8e1be75..768eb6c 100644 --- a/windows/Webview2/FileAccessor.cs +++ b/windows/Webview2/FileAccessor.cs @@ -1,5 +1,8 @@ -using System; +using Microsoft.WindowsAPICodePack.Dialogs; +using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading.Tasks; namespace Musiche.Webview2 @@ -8,7 +11,7 @@ public class FileAccessor { public FileAccessor() { - Utils.File.CreateDirectoryIFNotExists(Utils.File.StoragePath); + //Utils.File.CreateDirectoryIFNotExists(Utils.File.StoragePath); } #pragma warning disable CS1998 @@ -28,6 +31,65 @@ public async Task ReadFile(string filePath) } } +#pragma warning disable CS1998 + public async Task ShowSelectedDirectory() + { + CommonOpenFileDialog dialog = new CommonOpenFileDialog(); + dialog.IsFolderPicker = true; + dialog.Multiselect = true; + if (dialog.ShowDialog() == CommonFileDialogResult.Ok) + { + return dialog.FileNames.ToArray(); + } + return Array.Empty(); + } + + public async Task ListAllFiles(string filePath, bool recursive, bool onlyAudio = false) + { + return ListFilesRecursively(filePath, recursive, onlyAudio).ToArray(); + } + + public async Task GetMyMusicDirectory() + { + return Environment.GetFolderPath(Environment.SpecialFolder.MyMusic); + } + + private static readonly string[] AudioExtensions = new string[] { ".mp3", ".aiff", ".avi", ".mpg", ".mov", ".wav", ".flac", ".wma", ".ape", ".m4a" }; + private List ListFilesRecursively(string filePath, bool recursive, bool onlyAudio) + { + List pathList = new List(); + if (!Directory.Exists(filePath)) return pathList; + try + { + foreach (string fileName in Directory.GetFiles(filePath)) + { + if (!onlyAudio || AudioExtensions.Contains(Path.GetExtension(fileName))) + { + pathList.Add(fileName); + } + } + } + catch (Exception ex) + { + Logger.Logger.Error("ListFilesRecursively GetFiles Error: ", ex); + } + if (recursive) + { + try + { + foreach (string directoryName in Directory.GetDirectories(filePath)) + { + pathList.AddRange(ListFilesRecursively(directoryName, recursive, onlyAudio)); + } + } + catch (Exception ex) + { + Logger.Logger.Error("ListFilesRecursively GetDirectories Error: ", ex); + } + } + return pathList; + } + public async Task WriteFile(string filePath, string text) { try @@ -55,6 +117,18 @@ public Task DeleteFile(string filePath) return Task.CompletedTask; } + + public async Task FileExists(string filePath) + { + try + { + return File.Exists(filePath); + } + catch (Exception) + { + } + return false; + } #pragma warning restore CS1998 } } diff --git a/windows/Webview2/Webview2Control.xaml.cs b/windows/Webview2/Webview2Control.xaml.cs index 2950a89..d001bb2 100644 --- a/windows/Webview2/Webview2Control.xaml.cs +++ b/windows/Webview2/Webview2Control.xaml.cs @@ -29,6 +29,7 @@ public Webview2Control() Unloaded += WebView2_Unloaded; Loaded += Webview2Control_Loaded; InitWebViewCore(); + Logger.Logger.Info("webview2创建================================"); } private async void InitWebViewCore() @@ -37,6 +38,7 @@ private async void InitWebViewCore() webview2.CoreWebView2InitializationCompleted += OnCoreWebView2InitializationCompleted; webview2.WebMessageReceived += OnWebMessageReceived; await webview2.EnsureCoreWebView2Async(_coreEnvironment); + Logger.Logger.Info("webview2初始化================================"); } static Webview2Control() @@ -44,7 +46,12 @@ static Webview2Control() try { SetLoaderDll(); - _coreEnvironment = CoreWebView2Environment.CreateAsync(userDataFolder: Utils.File.Webview2Path).Result; + CoreWebView2EnvironmentOptions environmentOptions = new CoreWebView2EnvironmentOptions(); + if (File.Exists(Path.Combine(Utils.File.Webview2Path, Utils.File.DisableGPUName))) + { + environmentOptions.AdditionalBrowserArguments = "--disable-gpu"; + } + _coreEnvironment = CoreWebView2Environment.CreateAsync(userDataFolder: Utils.File.Webview2Path, options: environmentOptions).Result; } catch (Exception ex) { @@ -93,11 +100,13 @@ private void OnCoreWebView2InitializationCompleted(object sender, CoreWebView2In webview2.CoreWebView2.ContainsFullScreenElementChanged += CoreWebView2_ContainsFullScreenElementChanged; webview2.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded; CoreWebView2InitializationCompleted?.Invoke(sender, e); + Logger.Logger.Info("webview2 核心初始化================================"); } private void CoreWebView2_DOMContentLoaded(object sender, CoreWebView2DOMContentLoadedEventArgs e) { CoreWebView2DOMContentLoaded?.Invoke(sender, e); + Logger.Logger.Info("webview2 文档加载================================"); } private WindowState normalWindowState = WindowState.Normal;