diff --git a/NetCoreAudio/NetCoreAudio.csproj b/NetCoreAudio/NetCoreAudio.csproj index 907284c..0768b8f 100644 --- a/NetCoreAudio/NetCoreAudio.csproj +++ b/NetCoreAudio/NetCoreAudio.csproj @@ -1,33 +1,36 @@ - - - - netstandard2.1 - true - Fiodar Sazanavets - Scientific Programmer - NetCoreAudio - This NuGet package enables audio playback on .NET. It is compatible with any operating system supported by .NET. The package doesn't require any additional dependencies. - - https://scientificprogrammer.net - https://github.com/mobiletechtracker/NetCoreAudio - GitHub - .NET Core audio - 2.0.0 - - LICENSE - icon.jpg - - - - - True - - - - True - - - - - - + + + + netstandard2.1 + true + Fiodar Sazanavets + Scientific Programmer + NetCoreAudio + This NuGet package enables audio playback on .NET. It is compatible with any operating system supported by .NET. The package doesn't require any additional dependencies. + + https://scientificprogrammer.net + https://github.com/mobiletechtracker/NetCoreAudio + GitHub + .NET Core audio + 2.0.1 + 2.0.1 + 2.0.1.0 + 2.0.1.0 + + LICENSE + icon.jpg + + + + + True + + + + True + + + + + + diff --git a/NetCoreAudio/Players/WindowsPlayer.cs b/NetCoreAudio/Players/WindowsPlayer.cs index 114d94f..05c173d 100644 --- a/NetCoreAudio/Players/WindowsPlayer.cs +++ b/NetCoreAudio/Players/WindowsPlayer.cs @@ -23,6 +23,9 @@ public async Task Play(string fileName) { FileUtil.ClearTempFiles(); _fileName = $"\"{FileUtil.CheckFileToPlay(fileName)}\""; +#if DEBUG + Debug.WriteLine($"Actual file passed to MCI: {_fileName}"); +#endif _playbackTimer = new Timer { AutoReset = false diff --git a/NetCoreAudio/Utils/FileUtil.cs b/NetCoreAudio/Utils/FileUtil.cs index 7ebe2f9..799bdf9 100644 --- a/NetCoreAudio/Utils/FileUtil.cs +++ b/NetCoreAudio/Utils/FileUtil.cs @@ -1,25 +1,48 @@ -using System.IO; +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; namespace NetCoreAudio.Utils { internal static class FileUtil { private const string TempDirName = "temp"; + private const int MaxPathLengthBeforeFallback = 128; public static string CheckFileToPlay(string originalFileName) { var fileNameToReturn = originalFileName; - if (originalFileName.Contains(" ")) + if (originalFileName.Contains(" ") || originalFileName.Length > MaxPathLengthBeforeFallback) { - Directory.CreateDirectory(TempDirName); - fileNameToReturn = TempDirName + Path.DirectorySeparatorChar + - Path.GetFileName(originalFileName).Replace(" ", ""); - File.Copy(originalFileName, fileNameToReturn); + if (!WindowsUtil.TryGetShortPath(originalFileName, out var shortPath)) + { + Directory.CreateDirectory(TempDirName); + fileNameToReturn = Path.Combine(TempDirName, BuildTempFileName(originalFileName)); + File.Copy(originalFileName, fileNameToReturn, true); + } + else + { + fileNameToReturn = shortPath; + } } return fileNameToReturn; } + private static string BuildTempFileName(string originalFileName) + { + var extension = Path.GetExtension(originalFileName); + var baseName = Path.GetFileNameWithoutExtension(originalFileName).Replace(" ", ""); + if (baseName.Length > 80) + baseName = baseName.Substring(0, 80); + + using var sha256 = SHA256.Create(); + var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(Path.GetFullPath(originalFileName))); + var hash = BitConverter.ToString(hashBytes).Replace("-", string.Empty).Substring(0, 10); + return $"{baseName}_{hash}{extension}"; + } + public static void ClearTempFiles() { if (Directory.Exists(TempDirName)) diff --git a/NetCoreAudio/Utils/WindowsUtil.cs b/NetCoreAudio/Utils/WindowsUtil.cs index 6f87e30..4d4cdbd 100644 --- a/NetCoreAudio/Utils/WindowsUtil.cs +++ b/NetCoreAudio/Utils/WindowsUtil.cs @@ -8,6 +8,12 @@ namespace NetCoreAudio.Utils { internal static class WindowsUtil { + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + private static extern uint GetShortPathName( + [MarshalAs(UnmanagedType.LPTStr)] string path, + [MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath, + uint shortPathLength); + [DllImport("winmm.dll")] private static extern int mciSendString( string command, @@ -73,6 +79,29 @@ public static Task SetVolume(byte percent) return Task.CompletedTask; } + + internal static bool TryGetShortPath(string path, out string shortPath) + { + shortPath = string.Empty; + + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return false; + + var initialLength = 260u; + var buffer = new StringBuilder((int)initialLength); + var result = GetShortPathName(path, buffer, initialLength); + if (result > initialLength) + { + buffer = new StringBuilder((int)result); + result = GetShortPathName(path, buffer, result); + } + + if (result == 0) + return false; + + shortPath = buffer.ToString(); + return !string.IsNullOrWhiteSpace(shortPath); + } } public struct WaveFormat diff --git a/Samples/UnoMvvmAudioPlayer/AudioPlayer/MainModel.cs b/Samples/UnoMvvmAudioPlayer/AudioPlayer/MainModel.cs index b859804..2c10242 100644 --- a/Samples/UnoMvvmAudioPlayer/AudioPlayer/MainModel.cs +++ b/Samples/UnoMvvmAudioPlayer/AudioPlayer/MainModel.cs @@ -51,11 +51,6 @@ private async Task Stop() UpdateStatuses(); } - private void OnPlaybackFinished(object? sender, EventArgs? e) - { - UpdateStatuses(); - } - private void UpdateStatuses() { Playing = _player.Playing;