diff --git a/.gitignore b/.gitignore index 170a2ca..40f9c31 100644 --- a/.gitignore +++ b/.gitignore @@ -353,3 +353,4 @@ healthchecksdb MigrationBackup/ # End of https://www.gitignore.io/api/visualstudio +.idea/ \ No newline at end of file diff --git a/ClipChopper.sln b/ClipChopper.sln deleted file mode 100644 index ccbf842..0000000 --- a/ClipChopper.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29709.97 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClipChopper", "ClipChopper\ClipChopper.csproj", "{956CD016-BDC9-4F7A-9D42-3647DBE46A64}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {956CD016-BDC9-4F7A-9D42-3647DBE46A64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {956CD016-BDC9-4F7A-9D42-3647DBE46A64}.Debug|Any CPU.Build.0 = Debug|Any CPU - {956CD016-BDC9-4F7A-9D42-3647DBE46A64}.Debug|x64.ActiveCfg = Debug|x64 - {956CD016-BDC9-4F7A-9D42-3647DBE46A64}.Debug|x64.Build.0 = Debug|x64 - {956CD016-BDC9-4F7A-9D42-3647DBE46A64}.Release|Any CPU.ActiveCfg = Release|Any CPU - {956CD016-BDC9-4F7A-9D42-3647DBE46A64}.Release|Any CPU.Build.0 = Release|Any CPU - {956CD016-BDC9-4F7A-9D42-3647DBE46A64}.Release|x64.ActiveCfg = Release|x64 - {956CD016-BDC9-4F7A-9D42-3647DBE46A64}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {D5421CE1-B974-4F27-83D9-6EACD36B29A4} - EndGlobalSection -EndGlobal diff --git a/ClipChopper/App.config b/ClipChopper/App.config deleted file mode 100644 index 56efbc7..0000000 --- a/ClipChopper/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/ClipChopper/App.xaml b/ClipChopper/Applications/ClipChopper.DesktopApp/App.xaml similarity index 100% rename from ClipChopper/App.xaml rename to ClipChopper/Applications/ClipChopper.DesktopApp/App.xaml diff --git a/ClipChopper/App.xaml.cs b/ClipChopper/Applications/ClipChopper.DesktopApp/App.xaml.cs similarity index 100% rename from ClipChopper/App.xaml.cs rename to ClipChopper/Applications/ClipChopper.DesktopApp/App.xaml.cs diff --git a/ClipChopper/Applications/ClipChopper.DesktopApp/AudioTrack.cs b/ClipChopper/Applications/ClipChopper.DesktopApp/AudioTrack.cs new file mode 100644 index 0000000..738012a --- /dev/null +++ b/ClipChopper/Applications/ClipChopper.DesktopApp/AudioTrack.cs @@ -0,0 +1,8 @@ +namespace ClipChopper.DesktopApp +{ + public sealed class AudioTrack + { + public string Name { get; set; } = string.Empty; + public int StreamIndex { get; set; } + } +} \ No newline at end of file diff --git a/ClipChopper/Applications/ClipChopper.DesktopApp/ClipChopper.DesktopApp.csproj b/ClipChopper/Applications/ClipChopper.DesktopApp/ClipChopper.DesktopApp.csproj new file mode 100644 index 0000000..138c277 --- /dev/null +++ b/ClipChopper/Applications/ClipChopper.DesktopApp/ClipChopper.DesktopApp.csproj @@ -0,0 +1,67 @@ + + + x64 + 1.1.0 + Kirichenko Valery + ClipChopper + 1.1.0 + ClipChopper + ClipChopper + Kirichenko Valery + + + WinExe + netcoreapp3.1 + 8.0 + true + enable + CS8600,CS8602,CS8603,CS8618,CS8625 + ClipChopper + icon.ico + MinimumRecommendedRules.ruleset + app.manifest + + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + + + + + + \ No newline at end of file diff --git a/ClipChopper/Applications/ClipChopper.DesktopApp/DirectoryItem.cs b/ClipChopper/Applications/ClipChopper.DesktopApp/DirectoryItem.cs new file mode 100644 index 0000000..0544947 --- /dev/null +++ b/ClipChopper/Applications/ClipChopper.DesktopApp/DirectoryItem.cs @@ -0,0 +1,20 @@ +namespace ClipChopper.DesktopApp +{ + public sealed class DirectoryItem + { + public string Name { get; set; } + public string Path { get; set; } + + public DirectoryItem(string name, string path) + { + Name = name; + Path = path; + } + + public DirectoryItem(string path) + { + Name = System.IO.Path.GetFileName(path); + Path = path; + } + } +} diff --git a/ClipChopper/Applications/ClipChopper.DesktopApp/FragmentSelection.cs b/ClipChopper/Applications/ClipChopper.DesktopApp/FragmentSelection.cs new file mode 100644 index 0000000..df25b44 --- /dev/null +++ b/ClipChopper/Applications/ClipChopper.DesktopApp/FragmentSelection.cs @@ -0,0 +1,79 @@ +using System; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace ClipChopper.DesktopApp +{ + // TODO: use Prism.WPF BindableBase. + public sealed class FragmentSelection : INotifyPropertyChanged + { + private TimeSpan _start; + private TimeSpan _stop; + private TimeSpan _duration; + + public event PropertyChangedEventHandler? PropertyChanged; + + private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + public FragmentSelection(TimeSpan duration) + { + Duration = duration; + Start = TimeSpan.Zero; + Stop = duration; + } + + public TimeSpan Start + { + get => _start; + + set + { + if (value != _start) + { + _start = value; + NotifyPropertyChanged(); + + if (Stop <= Start) + { + Stop = Duration; + } + } + } + } + + public TimeSpan Stop + { + get => _stop; + + set + { + if (value != _stop) + { + _stop = value; + NotifyPropertyChanged(); + + if (Start >= value) + { + Start = TimeSpan.Zero; + } + } + } + } + + private TimeSpan Duration + { + get => _duration; + set + { + _duration = value; + if (Stop > value) + { + Stop = value; + } + } + } + } +} diff --git a/ClipChopper/KeyframeProber.cs b/ClipChopper/Applications/ClipChopper.DesktopApp/KeyframeProber.cs similarity index 57% rename from ClipChopper/KeyframeProber.cs rename to ClipChopper/Applications/ClipChopper.DesktopApp/KeyframeProber.cs index e3ba9c6..3ec3e1e 100644 --- a/ClipChopper/KeyframeProber.cs +++ b/ClipChopper/Applications/ClipChopper.DesktopApp/KeyframeProber.cs @@ -3,13 +3,17 @@ namespace ClipChopper { - static class KeyframeProber + internal static class KeyframeProber { public static TimeSpan FindClosestKeyframeTime(string filePath, TimeSpan time) { var ffprobePath = Unosquare.FFME.Library.FFmpegDirectory + @"\ffprobe.exe"; var keyframe = TimeSpan.Zero; - + + string args = $"-threads {Environment.ProcessorCount} -select_streams v -skip_frame nokey " + + $"-show_frames -print_format csv " + + $"-show_entries frame=key_frame,pkt_dts_time \"{filePath}\""; + var startInfo = new ProcessStartInfo() { RedirectStandardOutput = true, @@ -17,17 +21,24 @@ public static TimeSpan FindClosestKeyframeTime(string filePath, TimeSpan time) UseShellExecute = false, CreateNoWindow = true, FileName = ffprobePath, - Arguments = String.Format("-threads {0} -select_streams v -show_frames -print_format csv -show_entries frame=key_frame,pkt_dts_time \"{1}\"", Environment.ProcessorCount, filePath) + Arguments = args }; using (var probe = Process.Start(startInfo)) { - probe.OutputDataReceived += new DataReceivedEventHandler((s, e) => + Debug.Assert(probe != null, nameof(probe) + " != null"); + probe.OutputDataReceived += (s, e) => { - if (e.Data == null) return; + if (e.Data is null) return; + var data = e.Data.Split(','); - var splitted_time = data[2].Split('.'); - TimeSpan frame = TimeSpan.FromSeconds(Int32.Parse(splitted_time[0])) + TimeSpan.ParseExact(splitted_time[1], "ffffff", System.Globalization.CultureInfo.InvariantCulture); + var splittedTime = data[2].Split('.'); + + // TODO: move this logic to new function. + TimeSpan frame = TimeSpan.FromSeconds( + int.Parse(splittedTime[0])) + TimeSpan.ParseExact(splittedTime[1], + "ffffff", System.Globalization.CultureInfo.InvariantCulture + ); if (data[1] == "1") { @@ -40,7 +51,7 @@ public static TimeSpan FindClosestKeyframeTime(string filePath, TimeSpan time) keyframe = frame; } } - }); + }; probe.BeginOutputReadLine(); probe.WaitForExit(); } diff --git a/ClipChopper/MainWindow.xaml b/ClipChopper/Applications/ClipChopper.DesktopApp/MainWindow.xaml similarity index 82% rename from ClipChopper/MainWindow.xaml rename to ClipChopper/Applications/ClipChopper.DesktopApp/MainWindow.xaml index 63f521d..5293672 100644 --- a/ClipChopper/MainWindow.xaml +++ b/ClipChopper/Applications/ClipChopper.DesktopApp/MainWindow.xaml @@ -1,4 +1,4 @@ - + Title="Clip Chopper" + Height="870" + Width="1491" + WindowStartupLocation="CenterScreen"> - - @@ -72,7 +73,11 @@ - + - - - -