diff --git a/Azaion.Annotator/Annotator.xaml.cs b/Azaion.Annotator/Annotator.xaml.cs index d3ee97e..3fcf801 100644 --- a/Azaion.Annotator/Annotator.xaml.cs +++ b/Azaion.Annotator/Annotator.xaml.cs @@ -14,7 +14,6 @@ using Azaion.Common.DTO.Config; using Azaion.Common.Events; using Azaion.Common.Extensions; using Azaion.Common.Services; -using Azaion.CommonSecurity.Services; using LibVLCSharp.Shared; using MediatR; using Microsoft.WindowsAPICodePack.Dialogs; @@ -520,7 +519,7 @@ public partial class Annotator var files = new List(); await Dispatcher.Invoke(async () => { - //Take not annotated medias + //Take not annotataed medias files = (LvFiles.ItemsSource as IEnumerable)?.Skip(LvFiles.SelectedIndex) .Take(Constants.DETECTION_BATCH_SIZE) .Where(x => !x.HasAnnotations) @@ -532,16 +531,16 @@ public partial class Annotator await ReloadAnnotations(); } }); - if (files.Count == 0) break; - await _inferenceService.RunInference(files, async annotationImage => await ProcessDetection(annotationImage), ct); + await _inferenceService.RunInference(files, async annotationImage => await ProcessDetection(annotationImage, ct), ct); Dispatcher.Invoke(() => { + if (LvFiles.SelectedIndex + files.Count >= LvFiles.Items.Count) + DetectionCancellationSource.Cancel(); LvFiles.SelectedIndex += files.Count; - LvFiles.Items.Refresh(); }); } Dispatcher.Invoke(() => @@ -553,15 +552,28 @@ public partial class Annotator }); } - private async Task ProcessDetection(AnnotationImage annotationImage) + private async Task ProcessDetection(AnnotationImage annotationImage, CancellationToken ct = default) { await Dispatcher.Invoke(async () => { try { - var annotation = await _annotationService.SaveAnnotation(annotationImage); + var annotation = await _annotationService.SaveAnnotation(annotationImage, ct); if (annotation.OriginalMediaName != _formState.CurrentMedia?.FName) - return; + { + var nextFile = (LvFiles.ItemsSource as IEnumerable)? + .Select((info, i) => new + { + MediaInfo = info, + Index = i + }) + .FirstOrDefault(x => x.MediaInfo.FName == annotation.OriginalMediaName); + if (nextFile != null) + { + LvFiles.SelectedIndex = nextFile.Index; + await _mediator.Publish(new AnnotatorControlEvent(PlaybackControlEnum.Play), ct); + } + } AddAnnotation(annotation); if (FollowAI) @@ -573,7 +585,13 @@ public partial class Annotator $"size=({det.Width:F2}, {det.Height:F2}), " + $"prob: {det.Probability*100:F0}%")); - Dispatcher.Invoke(() => StatusHelp.Text = log); + Dispatcher.Invoke(() => + { + if (_formState.CurrentMedia != null) + _formState.CurrentMedia.HasAnnotations = true; + LvFiles.Items.Refresh(); + StatusHelp.Text = log; + }); } catch (Exception e) { diff --git a/Azaion.Annotator/AnnotatorEventHandler.cs b/Azaion.Annotator/AnnotatorEventHandler.cs index addb741..4bfefce 100644 --- a/Azaion.Annotator/AnnotatorEventHandler.cs +++ b/Azaion.Annotator/AnnotatorEventHandler.cs @@ -123,7 +123,7 @@ public class AnnotatorEventHandler( switch (controlEnum) { case PlaybackControlEnum.Play: - Play(); + await Play(cancellationToken); break; case PlaybackControlEnum.Pause: mediaPlayer.Pause(); @@ -170,10 +170,10 @@ public class AnnotatorEventHandler( mediaPlayer.Volume = 0; break; case PlaybackControlEnum.Previous: - NextMedia(isPrevious: true); + await NextMedia(isPrevious: true, ct: cancellationToken); break; case PlaybackControlEnum.Next: - NextMedia(); + await NextMedia(ct: cancellationToken); break; case PlaybackControlEnum.None: break; @@ -188,7 +188,7 @@ public class AnnotatorEventHandler( } } - private void NextMedia(bool isPrevious = false) + private async Task NextMedia(bool isPrevious = false, CancellationToken ct = default) { var increment = isPrevious ? -1 : 1; var check = isPrevious ? -1 : mainWindow.LvFiles.Items.Count; @@ -196,7 +196,7 @@ public class AnnotatorEventHandler( return; mainWindow.LvFiles.SelectedIndex += increment; - Play(); + await Play(ct); } public async Task Handle(VolumeChangedEvent notification, CancellationToken cancellationToken) @@ -211,7 +211,7 @@ public class AnnotatorEventHandler( mediaPlayer.Volume = volume; } - private void Play() + private async Task Play(CancellationToken ct = default) { if (mainWindow.LvFiles.SelectedItem == null) return; @@ -219,6 +219,8 @@ public class AnnotatorEventHandler( mainWindow.Editor.ResetBackground(); formState.CurrentMedia = mediaInfo; + //need to wait a bit for correct VLC playback event handling + await Task.Delay(100, ct); mediaPlayer.Stop(); mainWindow.Title = $"Azaion Annotator - {mediaInfo.Name}"; mainWindow.BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.PauseForAnnotations]); @@ -269,7 +271,7 @@ public class AnnotatorEventHandler( else { File.Copy(formState.CurrentMedia.Path, imgPath, overwrite: true); - NextMedia(); + await NextMedia(ct: cancellationToken); } var annotation = await annotationService.SaveAnnotation(formState.VideoName, time, imageExtension, currentDetections, SourceEnum.Manual, token: cancellationToken); mainWindow.AddAnnotation(annotation); diff --git a/Azaion.CommonSecurity/Services/PythonResourceLoader.cs b/Azaion.CommonSecurity/Services/PythonResourceLoader.cs index 1af161f..c2dff3e 100644 --- a/Azaion.CommonSecurity/Services/PythonResourceLoader.cs +++ b/Azaion.CommonSecurity/Services/PythonResourceLoader.cs @@ -36,20 +36,28 @@ public class PythonResourceLoader : IResourceLoader, IAuthProvider private void StartPython() { - using var process = new Process(); - process.StartInfo = new ProcessStartInfo + try { - FileName = SecurityConstants.AZAION_INFERENCE_PATH, - //Arguments = $"-e {credentials.Email} -p {credentials.Password} -f {apiConfig.ResourcesFolder}", - //UseShellExecute = false, - //RedirectStandardOutput = true, - // RedirectStandardError = true, - //CreateNoWindow = true - }; + using var process = new Process(); + process.StartInfo = new ProcessStartInfo + { + FileName = SecurityConstants.AZAION_INFERENCE_PATH, + //Arguments = $"-e {credentials.Email} -p {credentials.Password} -f {apiConfig.ResourcesFolder}", + //UseShellExecute = false, + //RedirectStandardOutput = true, + // RedirectStandardError = true, + //CreateNoWindow = true + }; - process.OutputDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); }; - process.ErrorDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); }; - process.Start(); + process.OutputDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); }; + process.ErrorDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); }; + process.Start(); + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } } public void Login(ApiCredentials credentials) diff --git a/Azaion.Dataset/BitmapExtensions.cs b/Azaion.Dataset/BitmapExtensions.cs index cb54e6a..618cd51 100644 --- a/Azaion.Dataset/BitmapExtensions.cs +++ b/Azaion.Dataset/BitmapExtensions.cs @@ -16,4 +16,4 @@ public static class BitmapExtensions image.Freeze(); return image; } -} \ No newline at end of file +} diff --git a/Azaion.Dataset/DatasetExplorer.xaml.cs b/Azaion.Dataset/DatasetExplorer.xaml.cs index d5c1561..3f610ac 100644 --- a/Azaion.Dataset/DatasetExplorer.xaml.cs +++ b/Azaion.Dataset/DatasetExplorer.xaml.cs @@ -199,7 +199,7 @@ public partial class DatasetExplorer RefreshThumbnailsButtonItem.Visibility = Visibility.Hidden; RefreshProgressBarItem.Visibility = Visibility.Visible; - var result = MessageBox.Show($"Видалити всі іконки і згенерувати нову базу іконок в {_directoriesConfig.ThumbnailsDirectory}?", + var result = MessageBox.Show($"Видалити всі іконки та згенерувати нову базу іконок в {_directoriesConfig.ThumbnailsDirectory}?", "Підтвердження оновлення іконок", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result != MessageBoxResult.Yes) return; diff --git a/Azaion.Suite.sln b/Azaion.Suite.sln index 097bb7c..eb541b0 100644 --- a/Azaion.Suite.sln +++ b/Azaion.Suite.sln @@ -22,6 +22,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azaion.Dataset", "Dummy\Aza EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Azaion.CommonSecurity", "Azaion.CommonSecurity\Azaion.CommonSecurity.csproj", "{E0C7176D-2E91-4928-B3C1-55CC91C8F77D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{CF141A48-8002-4006-81CF-6B85AE5B0B5F}" + ProjectSection(SolutionItems) = preProject + build\publish.cmd = build\publish.cmd + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Azaion.Suite/Azaion.Suite.csproj b/Azaion.Suite/Azaion.Suite.csproj index 477a879..b15d7b3 100644 --- a/Azaion.Suite/Azaion.Suite.csproj +++ b/Azaion.Suite/Azaion.Suite.csproj @@ -57,7 +57,7 @@ - + diff --git a/Azaion.Suite/Login.xaml b/Azaion.Suite/Login.xaml index 64b3bce..0978c07 100644 --- a/Azaion.Suite/Login.xaml +++ b/Azaion.Suite/Login.xaml @@ -74,7 +74,6 @@ BorderBrush="DimGray" BorderThickness="0,0,0,1" HorizontalAlignment="Left" - Text="admin@azaion.com" /> + HorizontalAlignment="Left"/>