From 288a34e9927d2c771c7d2089f798e7948027f38e Mon Sep 17 00:00:00 2001 From: Oleksandr Bezdieniezhnykh Date: Thu, 18 Jul 2024 21:40:15 +0300 Subject: [PATCH] add results pane differentiate already processed videos --- Azaion.Annotator/DTO/AnnotationResult.cs | 4 ++ Azaion.Annotator/DTO/VideoFileInfo.cs | 7 ++-- Azaion.Annotator/MainWindow.xaml | 31 ++++++++------ Azaion.Annotator/MainWindow.xaml.cs | 12 +++++- Azaion.Annotator/PlayerControlHandler.cs | 52 ++++++++++++------------ Azaion.Annotator/config.json | 2 +- 6 files changed, 63 insertions(+), 45 deletions(-) diff --git a/Azaion.Annotator/DTO/AnnotationResult.cs b/Azaion.Annotator/DTO/AnnotationResult.cs index e0fac56..38c0e23 100644 --- a/Azaion.Annotator/DTO/AnnotationResult.cs +++ b/Azaion.Annotator/DTO/AnnotationResult.cs @@ -6,9 +6,13 @@ public class AnnotationResult { [JsonProperty(PropertyName = "f")] public string Image { get; set; } = null!; + [JsonProperty(PropertyName = "t")] public TimeSpan Time { get; set; } + [JsonIgnore] + public string TimeStr => $"{Time:h\\:mm\\:ss}"; + [JsonProperty(PropertyName = "p")] public double Percentage { get; set; } diff --git a/Azaion.Annotator/DTO/VideoFileInfo.cs b/Azaion.Annotator/DTO/VideoFileInfo.cs index da1f934..ea783fe 100644 --- a/Azaion.Annotator/DTO/VideoFileInfo.cs +++ b/Azaion.Annotator/DTO/VideoFileInfo.cs @@ -2,7 +2,8 @@ public class VideoFileInfo { - public string Name { get; set; } = null!; - public string Path { get; set; } = null!; - public TimeSpan Duration { get; set; } + public string Name { get; set; } = null!; + public string Path { get; set; } = null!; + public TimeSpan Duration { get; set; } + public bool HasAnnotations { get; set; } } \ No newline at end of file diff --git a/Azaion.Annotator/MainWindow.xaml b/Azaion.Annotator/MainWindow.xaml index 51f0e58..6496e2b 100644 --- a/Azaion.Annotator/MainWindow.xaml +++ b/Azaion.Annotator/MainWindow.xaml @@ -105,9 +105,18 @@ + + + - - + CanUserSort="False" + Binding="{Binding Path=TimeStr}"> + - - - - - - - + + diff --git a/Azaion.Annotator/MainWindow.xaml.cs b/Azaion.Annotator/MainWindow.xaml.cs index de0d69d..bd1582c 100644 --- a/Azaion.Annotator/MainWindow.xaml.cs +++ b/Azaion.Annotator/MainWindow.xaml.cs @@ -153,6 +153,7 @@ public partial class MainWindow { Annotations = LoadAnnotations(); _formState.AnnotationResults = LoadAnnotationResults(); + DgAnnotations.ItemsSource = _formState.AnnotationResults; } private Dictionary> LoadAnnotations() @@ -205,16 +206,23 @@ public partial class MainWindow var dir = new DirectoryInfo(_config.VideosDirectory); if (!dir.Exists) return; + + var labelNames = new DirectoryInfo(_config.LabelsDirectory).GetFiles() + .Select(x => x.Name[..^11]) + .GroupBy(x => x) + .Select(gr => gr.Key) + .ToDictionary(x => x); var files = dir.GetFiles("mp4", "mov").Select(x => { _mediaPlayer.Media = new Media(_libVLC, x.FullName); - + return new VideoFileInfo { Name = x.Name, Path = x.FullName, - Duration = TimeSpan.FromMilliseconds(_mediaPlayer.Media.Duration) + Duration = TimeSpan.FromMilliseconds(_mediaPlayer.Media.Duration), + HasAnnotations = labelNames.ContainsKey(Path.GetFileNameWithoutExtension(x.Name).Replace(" ", "")) }; }).ToList(); diff --git a/Azaion.Annotator/PlayerControlHandler.cs b/Azaion.Annotator/PlayerControlHandler.cs index 9414fcd..a5e8a54 100644 --- a/Azaion.Annotator/PlayerControlHandler.cs +++ b/Azaion.Annotator/PlayerControlHandler.cs @@ -9,21 +9,21 @@ using Newtonsoft.Json; namespace Azaion.Annotator; public class PlayerControlHandler(LibVLC libVLC, MediaPlayer mediaPlayer, MainWindow mainWindow, FormState formState, Config config) : - INotificationHandler, - INotificationHandler, - INotificationHandler, - INotificationHandler + INotificationHandler, + INotificationHandler, + INotificationHandler, + INotificationHandler { private const int STEP = 20; private const int LARGE_STEP = 5000; private const int RESULT_WIDTH = 1280; - + private static readonly string[] CatchSenders = ["ForegroundWindow", "ScrollViewer", "VideoView"]; private readonly Dictionary KeysControlEnumDict = new() { { Key.Space, PlaybackControlEnum.Pause }, - { Key.Left, PlaybackControlEnum.PreviousFrame }, + { Key.Left, PlaybackControlEnum.PreviousFrame }, { Key.Right, PlaybackControlEnum.NextFrame }, { Key.Enter, PlaybackControlEnum.SaveAnnotations }, { Key.Delete, PlaybackControlEnum.RemoveSelectedAnns }, @@ -34,13 +34,13 @@ public class PlayerControlHandler(LibVLC libVLC, MediaPlayer mediaPlayer, MainWi { SelectClass(notification.AnnotationClass); await Task.CompletedTask; - } - + } + private void SelectClass(AnnotationClass annClass) { mainWindow.Editor.CurrentAnnClass = annClass; - foreach (var ann in mainWindow.Editor.CurrentAnns.Where(x => x.IsSelected)) + foreach (var ann in mainWindow.Editor.CurrentAnns.Where(x => x.IsSelected)) ann.AnnotationClass = annClass; mainWindow.LvClasses.SelectedIndex = annClass.Id; } @@ -49,18 +49,18 @@ public class PlayerControlHandler(LibVLC libVLC, MediaPlayer mediaPlayer, MainWi { if (!CatchSenders.Contains(notification.Sender.GetType().Name)) return; - + var key = notification.Args.Key; var keyNumber = (int?)null; - - if ((int)key >= (int)Key.D1 && (int)key <= (int)Key.D9) + + if ((int)key >= (int)Key.D1 && (int)key <= (int)Key.D9) keyNumber = key - Key.D1; - if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9) + if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9) keyNumber = key - Key.NumPad1; if (keyNumber.HasValue) SelectClass(mainWindow.AnnotationClasses[keyNumber.Value]); - - if (KeysControlEnumDict.TryGetValue(key, out var value)) + + if (KeysControlEnumDict.TryGetValue(key, out var value)) await ControlPlayback(value); await VolumeControl(key); @@ -80,7 +80,7 @@ public class PlayerControlHandler(LibVLC libVLC, MediaPlayer mediaPlayer, MainWi case Key.VolumeUp: var vUp = Math.Min(100, mediaPlayer.Volume + 5); ChangeVolume(vUp); - mainWindow.Volume.Value = vUp; + mainWindow.Volume.Value = vUp; break; case Key.Down: case Key.VolumeDown: @@ -111,7 +111,7 @@ public class PlayerControlHandler(LibVLC libVLC, MediaPlayer mediaPlayer, MainWi break; case PlaybackControlEnum.Pause: mediaPlayer.Pause(); - if (!mediaPlayer.IsPlaying) + if (!mediaPlayer.IsPlaying) mainWindow.BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.AnnotationHelp]); break; case PlaybackControlEnum.Stop: @@ -171,7 +171,7 @@ public class PlayerControlHandler(LibVLC libVLC, MediaPlayer mediaPlayer, MainWi formState.CurrentVolume = volume; mediaPlayer.Volume = volume; } - + private void Play() { if (mainWindow.LvFiles.SelectedItem == null) @@ -180,12 +180,12 @@ public class PlayerControlHandler(LibVLC libVLC, MediaPlayer mediaPlayer, MainWi formState.CurrentFile = fileInfo.Name; mainWindow.LoadExistingAnnotations(); - + mediaPlayer.Stop(); mediaPlayer.Play(new Media(libVLC, fileInfo.Path)); mainWindow.BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.PauseForAnnotations]); } - + private async Task SaveAnnotations() { if (string.IsNullOrEmpty(formState.CurrentFile)) @@ -204,18 +204,18 @@ public class PlayerControlHandler(LibVLC libVLC, MediaPlayer mediaPlayer, MainWi Directory.CreateDirectory(config.ImagesDirectory); if (!Directory.Exists(config.ResultsDirectory)) Directory.CreateDirectory(config.ResultsDirectory); - + await File.WriteAllTextAsync($"{config.LabelsDirectory}/{fName}.txt", labels); formState.AnnotationResults.Add(new AnnotationResult(time, fName, currentAnns)); await File.WriteAllTextAsync($"{config.ResultsDirectory}/{fName}.json", JsonConvert.SerializeObject(formState.AnnotationResults)); - - var resultHeight = (uint)Math.Round(RESULT_WIDTH / formState.CurrentVideoSize.Width * formState.CurrentVideoSize.Height); - + + var resultHeight = (uint)Math.Round(RESULT_WIDTH / formState.CurrentVideoSize.Width * formState.CurrentVideoSize.Height); + mediaPlayer.TakeSnapshot(0, $"{config.ImagesDirectory}/{fName}.jpg", RESULT_WIDTH, resultHeight); - + mainWindow.Annotations[time] = currentAnns; mainWindow.Editor.RemoveAllAnns(); mediaPlayer.Play(); } -} +} \ No newline at end of file diff --git a/Azaion.Annotator/config.json b/Azaion.Annotator/config.json index 193c4be..26fac4e 100644 --- a/Azaion.Annotator/config.json +++ b/Azaion.Annotator/config.json @@ -1,5 +1,5 @@ { - "VideosDirectory": "E:\\Azaion3\\Videos", + "VideosDirectory": "E:\\Azaion3\\VideosDone", "LabelsDirectory": "E:\\labels", "ImagesDirectory": "E:\\images", "ResultsDirectory": "E:\\results",