diff --git a/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs b/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs index 7ba3dae3..8e856f81 100644 --- a/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs +++ b/AudioCuesheetEditor.End2EndTests/Tests/Desktop/ExportTest.cs @@ -68,7 +68,7 @@ public async Task DownloadProject_GeneratesProjectFile_WhenCuesheetIsValidAsync( using var stream = await download.CreateReadStreamAsync(); using var reader = new StreamReader(stream); var content = await reader.ReadToEndAsync(TestContext.CancellationToken); - Assert.AreEqual("{\"Tracks\":[{\"Position\":1,\"Artist\":\"Track Artist 1\",\"Title\":\"Track Title 1\",\"Begin\":\"00:00:00\",\"End\":\"00:05:48\",\"Flags\":[],\"IsLinkedToPreviousTrack\":true}],\"Artist\":\"Cuesheet Artist 1\",\"Title\":\"Cuesheet Title 1\",\"Audiofile\":{\"Name\":\"Kalimba.mp3\",\"Duration\":\"00:05:48\",\"AudioCodec\":{\"MimeType\":\"audio/mpeg\",\"FileExtension\":\".mp3\",\"Name\":\"AudioCodec MP3\"}}}", content); + Assert.AreEqual("{\"Tracks\":[{\"Position\":1,\"Artist\":\"Track Artist 1\",\"Title\":\"Track Title 1\",\"Begin\":\"00:00:00\",\"End\":\"00:05:48.0608330\",\"Flags\":[],\"IsLinkedToPreviousTrack\":true}],\"Artist\":\"Cuesheet Artist 1\",\"Title\":\"Cuesheet Title 1\",\"Audiofile\":{\"Name\":\"Kalimba.mp3\",\"Duration\":\"00:05:48.0608330\",\"AudioCodec\":{\"MimeType\":\"audio/mpeg\",\"FileExtension\":\".mp3\",\"Name\":\"AudioCodec MP3\"}}}", content); } [TestMethod] diff --git a/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs b/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs index 1e3d7b5e..22865d9b 100644 --- a/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs +++ b/AudioCuesheetEditor.End2EndTests/Tests/Smartphone/ExportTestSmartphone.cs @@ -68,7 +68,7 @@ public async Task DownloadProject_GeneratesProjectFile_WhenCuesheetIsValidAsync( using var stream = await download.CreateReadStreamAsync(); using var reader = new StreamReader(stream); var content = await reader.ReadToEndAsync(TestContext.CancellationToken); - Assert.AreEqual("{\"Tracks\":[{\"Position\":1,\"Artist\":\"Track Artist 1\",\"Title\":\"Track Title 1\",\"Begin\":\"00:00:00\",\"End\":\"00:05:48\",\"Flags\":[],\"IsLinkedToPreviousTrack\":true}],\"Artist\":\"Cuesheet Artist 1\",\"Title\":\"Cuesheet Title 1\",\"Audiofile\":{\"Name\":\"Kalimba.mp3\",\"Duration\":\"00:05:48\",\"AudioCodec\":{\"MimeType\":\"audio/mpeg\",\"FileExtension\":\".mp3\",\"Name\":\"AudioCodec MP3\"}}}", content); + Assert.AreEqual("{\"Tracks\":[{\"Position\":1,\"Artist\":\"Track Artist 1\",\"Title\":\"Track Title 1\",\"Begin\":\"00:00:00\",\"End\":\"00:05:48.0608330\",\"Flags\":[],\"IsLinkedToPreviousTrack\":true}],\"Artist\":\"Cuesheet Artist 1\",\"Title\":\"Cuesheet Title 1\",\"Audiofile\":{\"Name\":\"Kalimba.mp3\",\"Duration\":\"00:05:48.0608330\",\"AudioCodec\":{\"MimeType\":\"audio/mpeg\",\"FileExtension\":\".mp3\",\"Name\":\"AudioCodec MP3\"}}}", content); } [TestMethod] diff --git a/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj b/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj index dc6ac4ec..0651db7f 100644 --- a/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj +++ b/AudioCuesheetEditor.Tests/AudioCuesheetEditor.Tests.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs b/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs index 07fcdcb7..0db99667 100644 --- a/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs +++ b/AudioCuesheetEditor.Tests/Model/AudioCuesheet/CuesheetTests.cs @@ -673,12 +673,9 @@ public void StartRecording_WithAudiofile_ShouldStartRecording() public void RecalculateLastTrackEnd_SingleTrackWithAudiofile_EndSetToAudiofileDuration() { // Arrange - var audiofileMock = new Mock(); - audiofileMock.SetupGet(a => a.Duration).Returns(TimeSpan.FromMinutes(5)); - var cuesheet = new Cuesheet { - Audiofile = audiofileMock.Object + Audiofile = new("Test.mp3", nameof(RecalculateLastTrackEnd_SingleTrackWithAudiofile_EndSetToAudiofileDuration), new AudioCodec("audio/mpeg", ".mp3", "AudioCodec MP3"), TimeSpan.FromMinutes(5)) }; var track = new Track { Position = 1, Begin = TimeSpan.Zero }; cuesheet.AddTrack(track); @@ -712,12 +709,9 @@ public void RecalculateLastTrackEnd_MultipleTracks_EndSetCorrectly() public void RecalculateLastTrackEnd_MultipleTracksWithAudiofile_LastTrackEndSetToAudiofileDuration() { // Arrange - var audiofileMock = new Mock(); - audiofileMock.SetupGet(a => a.Duration).Returns(TimeSpan.FromMinutes(5)); - var cuesheet = new Cuesheet { - Audiofile = audiofileMock.Object + Audiofile = new("Test.mp3", nameof(RecalculateLastTrackEnd_SingleTrackWithAudiofile_EndSetToAudiofileDuration), new AudioCodec("audio/mpeg", ".mp3", "AudioCodec MP3"), TimeSpan.FromMinutes(5)) }; var track1 = new Track { Position = 1, Begin = TimeSpan.Zero, End = TimeSpan.FromMinutes(2) }; var track2 = new Track { Position = 2, Begin = TimeSpan.FromMinutes(2) }; diff --git a/AudioCuesheetEditor.Tests/Model/IO/Audio/AudiofileTests.cs b/AudioCuesheetEditor.Tests/Model/IO/Audio/AudiofileTests.cs deleted file mode 100644 index 7779ba5a..00000000 --- a/AudioCuesheetEditor.Tests/Model/IO/Audio/AudiofileTests.cs +++ /dev/null @@ -1,48 +0,0 @@ -//This file is part of AudioCuesheetEditor. - -//AudioCuesheetEditor is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//AudioCuesheetEditor is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with Foobar. If not, see -//. -using AudioCuesheetEditor.Model.IO.Audio; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Linq; - -namespace AudioCuesheetEditor.Tests.Model.IO.Audio -{ - [TestClass()] - public class AudiofileTests - { - [TestMethod()] - public void AudioFileTest() - { - var audioFile = new Audiofile("test.mp3"); - Assert.IsNull(audioFile.ContentStream); - Assert.IsFalse(audioFile.IsContentStreamLoaded); - Assert.IsNotNull(audioFile.Name); - Assert.AreEqual("MP3", audioFile.AudioFileType); - audioFile = new Audiofile("Test"); - Assert.AreEqual(audioFile.AudioFileType, string.Empty); - Assert.IsNotNull(audioFile.Name); - var codec = Audiofile.AudioCodecs.Single(x => x.FileExtension == ".ogg"); - audioFile = new Audiofile("test", "TestobjectURL", codec); - Assert.IsNotNull(audioFile.Name); - Assert.AreEqual("test.ogg", audioFile.Name); - Assert.AreEqual("OGG", audioFile.AudioFileType); - Assert.IsNotNull(audioFile.ObjectURL); - Assert.IsTrue(audioFile.PlaybackPossible); - codec = Audiofile.AudioCodecs.Single(x => x.FileExtension == ".mp3"); - var audioFile2 = new Audiofile(audioFile.Name, "TestObjectURL2", codec); - Assert.AreEqual("test.mp3", audioFile2.Name); - } - } -} \ No newline at end of file diff --git a/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs b/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs index 5b6b2ec9..875a900b 100644 --- a/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs +++ b/AudioCuesheetEditor.Tests/Services/IO/ImportManagerTests.cs @@ -288,7 +288,7 @@ public async Task UploadFilesAsync_WithAudiofile_ImportsCorrectly() _fileInputManagerMock.Setup(f => f.CheckFileMimeType(file.ContentType, file.Name, FileMimeTypes.Cuesheet, It.IsAny>())).Returns(false); _fileInputManagerMock.Setup(f => f.IsValidForImportView(file.ContentType, file.Name)).Returns(false); _fileInputManagerMock.Setup(f => f.IsValidAudiofile(file.ContentType, file.Name)).Returns(true); - _fileInputManagerMock.Setup(f => f.CreateAudiofileAsync(It.IsAny(), It.IsAny>?>())).ReturnsAsync(new AudioCuesheetEditor.Model.IO.Audio.Audiofile(file.Name)); + _fileInputManagerMock.Setup(f => f.CreateAudiofileAsync(It.IsAny())).ReturnsAsync(new Audiofile(file.Name)); IImportfile? sessionStateContainerImportfile = null; _sessionStateContainerMock.SetupSet(x => x.Importfile = It.IsAny()).Callback(x => sessionStateContainerImportfile = x); diff --git a/AudioCuesheetEditor/AudioCuesheetEditor.csproj b/AudioCuesheetEditor/AudioCuesheetEditor.csproj index 26315d86..aa58202b 100644 --- a/AudioCuesheetEditor/AudioCuesheetEditor.csproj +++ b/AudioCuesheetEditor/AudioCuesheetEditor.csproj @@ -22,16 +22,15 @@ - - + + - - - + + + - diff --git a/AudioCuesheetEditor/Extensions/InterfaceConverter.cs b/AudioCuesheetEditor/Extensions/InterfaceConverter.cs deleted file mode 100644 index f5ab2bfb..00000000 --- a/AudioCuesheetEditor/Extensions/InterfaceConverter.cs +++ /dev/null @@ -1,40 +0,0 @@ -//This file is part of AudioCuesheetEditor. - -//AudioCuesheetEditor is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//AudioCuesheetEditor is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with Foobar. If not, see -//. -using System.Text.Json.Serialization; -using System.Text.Json; - -namespace AudioCuesheetEditor.Extensions -{ - public class InterfaceConverter : JsonConverter where TImplementation : TInterface - { - public override TInterface? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return JsonSerializer.Deserialize(ref reader, options); - } - - public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options) - { - if (value != null) - { - JsonSerializer.Serialize(writer, (TImplementation)value, options); - } - else - { - writer.WriteNullValue(); - } - } - } -} diff --git a/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs b/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs index d4c73211..65ea5d96 100644 --- a/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs +++ b/AudioCuesheetEditor/Model/AudioCuesheet/Cuesheet.cs @@ -38,7 +38,7 @@ public class Cuesheet() : Validateable, ITraceable, ICuesheet private List tracks = []; private String? artist; private String? title; - private IAudiofile? audiofile; + private Audiofile? audiofile; private CDTextfile? cDTextfile; private String? catalogueNumber; private readonly List> currentlyHandlingLinkedTrackPropertyChange = []; @@ -89,7 +89,7 @@ public String? Title FireEvents(previousValue, propertyName: nameof(Title)); } } - public IAudiofile? Audiofile + public Audiofile? Audiofile { get => audiofile; set @@ -446,7 +446,7 @@ public override ValidationResult Validate(string property) private void RecalculateTrackProperties(Track trackToCalculate) { - if ((Audiofile != null) && (Audiofile.Duration.HasValue) && (trackToCalculate.End.HasValue == false)) + if ((Audiofile?.Duration.HasValue == true) && (trackToCalculate.End.HasValue == false)) { trackToCalculate.End = Audiofile.Duration; } diff --git a/AudioCuesheetEditor/Model/IO/Audio/Audiofile.cs b/AudioCuesheetEditor/Model/IO/Audio/Audiofile.cs index c61e7a63..ebee7f8d 100644 --- a/AudioCuesheetEditor/Model/IO/Audio/Audiofile.cs +++ b/AudioCuesheetEditor/Model/IO/Audio/Audiofile.cs @@ -18,7 +18,7 @@ namespace AudioCuesheetEditor.Model.IO.Audio { [method: JsonConstructor] - public class Audiofile(String name) : IDisposable, IAudiofile + public class Audiofile(String name) { public static readonly AudioCodec AudioCodecWEBM = new("audio/webm", ".webm", "AudioCodec WEBM"); @@ -35,13 +35,9 @@ public class Audiofile(String name) : IDisposable, IAudiofile ]; private AudioCodec? audioCodec; - private Stream? contentStream; private String name = name; - private bool disposedValue; - public event EventHandler? ContentStreamLoaded; - - public Audiofile(String name, String objectURL, AudioCodec? audioCodec) : this(name) + public Audiofile(String name, String objectURL, AudioCodec? audioCodec, TimeSpan? duration = null) : this(name) { if (String.IsNullOrEmpty(objectURL)) { @@ -49,6 +45,7 @@ public Audiofile(String name, String objectURL, AudioCodec? audioCodec) : this(n } ObjectURL = objectURL; AudioCodec = audioCodec; + Duration = duration; } public String Name @@ -71,32 +68,6 @@ public String Name [JsonIgnore] public String? ObjectURL { get; private set; } /// - /// Boolean indicating if the stream has fully been loaded - /// - [JsonIgnore] - public Boolean IsContentStreamLoaded - { - get { return ContentStream != null; } - } - /// - /// File content stream. Be carefully, this stream is loaded asynchronously. Connect to the StreamLoaded for checking if loading has already been done! - /// - [JsonIgnore] - public Stream? ContentStream - { - get => contentStream; - set - { - contentStream = value; - if ((ContentStream != null) && (AudioCodec != null)) - { - var track = new ATL.Track(ContentStream, AudioCodec.MimeType); - Duration = new TimeSpan(0, 0, track.Duration); - ContentStreamLoaded?.Invoke(this, EventArgs.Empty); - } - } - } - /// /// Duration of the audio file /// public TimeSpan? Duration { get; private set; } @@ -144,30 +115,5 @@ public Boolean PlaybackPossible return playbackPossible; } } - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - if (ContentStream != null) - { - ContentStream.Close(); - ContentStream.Dispose(); - ContentStream = null; - } - } - - disposedValue = true; - } - } - - public void Dispose() - { - // Ändern Sie diesen Code nicht. Fügen Sie Bereinigungscode in der Methode "Dispose(bool disposing)" ein. - Dispose(disposing: true); - GC.SuppressFinalize(this); - } } } diff --git a/AudioCuesheetEditor/Model/IO/Audio/IAudiofile.cs b/AudioCuesheetEditor/Model/IO/Audio/IAudiofile.cs deleted file mode 100644 index 456fd475..00000000 --- a/AudioCuesheetEditor/Model/IO/Audio/IAudiofile.cs +++ /dev/null @@ -1,31 +0,0 @@ -//This file is part of AudioCuesheetEditor. - -//AudioCuesheetEditor is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//AudioCuesheetEditor is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with Foobar. If not, see -//. -namespace AudioCuesheetEditor.Model.IO.Audio -{ - public interface IAudiofile - { - AudioCodec? AudioCodec { get; } - string? AudioFileType { get; } - Stream? ContentStream { get; set; } - TimeSpan? Duration { get; } - bool IsContentStreamLoaded { get; } - string Name { get; set; } - string? ObjectURL { get; } - bool PlaybackPossible { get; } - - event EventHandler? ContentStreamLoaded; - } -} \ No newline at end of file diff --git a/AudioCuesheetEditor/Model/IO/Projectfile.cs b/AudioCuesheetEditor/Model/IO/Projectfile.cs index c54dace0..c6d2617e 100644 --- a/AudioCuesheetEditor/Model/IO/Projectfile.cs +++ b/AudioCuesheetEditor/Model/IO/Projectfile.cs @@ -13,9 +13,7 @@ //You should have received a copy of the GNU General Public License //along with Foobar. If not, see //. -using AudioCuesheetEditor.Extensions; using AudioCuesheetEditor.Model.AudioCuesheet; -using AudioCuesheetEditor.Model.IO.Audio; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; @@ -32,8 +30,7 @@ public class Projectfile(Cuesheet cuesheet) ReferenceHandler = ReferenceHandler.IgnoreCycles, Converters = { - new JsonStringEnumConverter(), - new InterfaceConverter() // Add a custom converter for IAudiofile + new JsonStringEnumConverter() } }; diff --git a/AudioCuesheetEditor/Services/Audio/PlaybackService.cs b/AudioCuesheetEditor/Services/Audio/PlaybackService.cs index 89f90592..b451800e 100644 --- a/AudioCuesheetEditor/Services/Audio/PlaybackService.cs +++ b/AudioCuesheetEditor/Services/Audio/PlaybackService.cs @@ -26,7 +26,7 @@ public class PlaybackService : IDisposable private readonly IHowl _howl; private int? soundId; - private IAudiofile? currentlyPlayingAudiofile; + private Audiofile? currentlyPlayingAudiofile; private Timer? updateTimer; private bool disposedValue; private readonly Lock timerLock = new(); @@ -71,7 +71,7 @@ public PlaybackService(ISessionStateContainer sessionStateContainer, IHowl howl) public async Task PlayOrPauseAsync() { //Reset if the last played audiofile is not the current one - if (currentlyPlayingAudiofile !=cuesheet.Audiofile) + if (currentlyPlayingAudiofile != cuesheet.Audiofile) { soundId = null; } diff --git a/AudioCuesheetEditor/Services/IO/FileInputManager.cs b/AudioCuesheetEditor/Services/IO/FileInputManager.cs index 61cef4db..32836dc8 100644 --- a/AudioCuesheetEditor/Services/IO/FileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/FileInputManager.cs @@ -17,7 +17,6 @@ using AudioCuesheetEditor.Model.IO; using AudioCuesheetEditor.Model.IO.Audio; using Microsoft.AspNetCore.Components.Forms; -using Microsoft.AspNetCore.Components.WebAssembly.Http; using Microsoft.JSInterop; namespace AudioCuesheetEditor.Services.IO @@ -83,7 +82,7 @@ public bool CheckFileMimeType(string? fileContentType, string fileName, string m return fileMimeTypeMatches; } - public async Task CreateAudiofileAsync(FileUpload fileUpload, Action>? afterContentStreamLoaded = null) + public async Task CreateAudiofileAsync(FileUpload fileUpload) { Audiofile? audiofile = null; if (fileUpload.ObjectUrl != null) @@ -92,22 +91,13 @@ public bool CheckFileMimeType(string? fileContentType, string fileName, string m var codec = GetAudioCodec(fileUpload.ContentType, fileUpload.Name); if (codec != null) { - audiofile = new Audiofile(fileUpload.Name, fileUpload.ObjectUrl, codec); + TimeSpan? duration = null; if (String.IsNullOrEmpty(fileUpload.ObjectUrl) == false) { - var request = new HttpRequestMessage(HttpMethod.Get, fileUpload.ObjectUrl); - //TODO: Enable when https://github.com/NeoCoderMatrix86/AudioCuesheetEditor/issues/524 gets done - request.SetBrowserRequestStreamingEnabled(false); - - var response = await _httpClient.SendAsync(request); - var loadContentStreamTask = response.Content.ReadAsStreamAsync() - .ContinueWith(x => audiofile.ContentStream = x.Result); - if (afterContentStreamLoaded != null) - { - _ = loadContentStreamTask - .ContinueWith(afterContentStreamLoaded); - } + var durationSeconds = await _jsRuntime.InvokeAsync("getAudioDurationFromFile", fileUpload.ObjectUrl); + duration = TimeSpan.FromSeconds(durationSeconds); } + audiofile = new Audiofile(fileUpload.Name, fileUpload.ObjectUrl, codec, duration); } else { diff --git a/AudioCuesheetEditor/Services/IO/IFileInputManager.cs b/AudioCuesheetEditor/Services/IO/IFileInputManager.cs index 026ed5d4..f79f88a0 100644 --- a/AudioCuesheetEditor/Services/IO/IFileInputManager.cs +++ b/AudioCuesheetEditor/Services/IO/IFileInputManager.cs @@ -34,7 +34,7 @@ public interface IFileInputManager /// /// bool CheckFileMimeType(string? fileContentType, string fileName, string mimeType, IEnumerable fileExtensions); - Task CreateAudiofileAsync(FileUpload fileUpload, Action>? afterContentStreamLoaded = null); + Task CreateAudiofileAsync(FileUpload fileUpload); CDTextfile? CreateCDTextfile(string? fileContentType, string fileName); /// /// Checks if the file can be used for the import view diff --git a/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor b/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor index 61605a5a..cc0cf4eb 100644 --- a/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor +++ b/AudioCuesheetEditor/Shared/Cuesheet/CuesheetData.razor @@ -114,14 +114,11 @@ along with Foobar. If not, see if (browserFile != null) { var fileUpload = await _fileInputManager.CreateFileUploadsAsync([browserFile], fileInputAudiofileId); - Cuesheet.Audiofile = await _fileInputManager.CreateAudiofileAsync(fileUpload.Single(), x => + Cuesheet.Audiofile = await _fileInputManager.CreateAudiofileAsync(fileUpload.Single()); + if (Cuesheet.RecalculateLastTrackEnd()) { - if (Cuesheet.RecalculateLastTrackEnd()) - { - TraceChangeManager.MergeLastEditWithEdit(x => x.Changes.All(y => y.TraceableObject == Cuesheet && y.TraceableChange.PropertyName == nameof(Audiofile))); - } - StateHasChanged(); - }); + TraceChangeManager.MergeLastEditWithEdit(x => x.Changes.All(y => y.TraceableObject == Cuesheet && y.TraceableChange.PropertyName == nameof(Audiofile))); + } } else { diff --git a/AudioCuesheetEditor/wwwroot/scripts/library.js b/AudioCuesheetEditor/wwwroot/scripts/library.js index a3e73692..aa44cab8 100644 --- a/AudioCuesheetEditor/wwwroot/scripts/library.js +++ b/AudioCuesheetEditor/wwwroot/scripts/library.js @@ -39,4 +39,21 @@ function beforeunload(e) { function removeBeforeunload() { window.removeEventListener('beforeunload', beforeunload); +} + +function getAudioDurationFromFile(url) { + return new Promise((resolve, reject) => { + const audio = new Audio(); + + audio.preload = "metadata"; + audio.src = url; + + audio.onloadedmetadata = () => { + resolve(audio.duration); + }; + + audio.onerror = (e) => { + reject(e); + }; + }); } \ No newline at end of file