mirror of
https://github.com/wagesj45/butterflow-ui.git
synced 2024-12-22 09:12:42 -06:00
Subregions auto update. ButterflowWrapper now calls butterflow.exe
This commit is contained in:
parent
9145071e23
commit
d0b29f20fd
11 changed files with 604 additions and 35 deletions
105
butterflow-ui/ButterflowSubregion.cs
Normal file
105
butterflow-ui/ButterflowSubregion.cs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace butterflow_ui
|
||||||
|
{
|
||||||
|
public class ButterflowSubregion : PropertyChangedAlerter, System.ComponentModel.INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
#region Members
|
||||||
|
|
||||||
|
/// <summary> The start of the subregion. </summary>
|
||||||
|
private TimeSpan start = TimeSpan.Zero;
|
||||||
|
/// <summary> The end of the subregion. </summary>
|
||||||
|
private TimeSpan end = TimeSpan.Zero;
|
||||||
|
/// <summary> Type of opersion to perform on the subregion. </summary>
|
||||||
|
private RegionType subregionType;
|
||||||
|
/// <summary> The value targeted for the subregion. </summary>
|
||||||
|
private decimal value;
|
||||||
|
/// <summary> True if the subregion runs to the end, false if not. </summary>
|
||||||
|
private bool toEnd;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the start of the subregion. </summary>
|
||||||
|
/// <value> The start of the subregion. </value>
|
||||||
|
public TimeSpan Start
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.start;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.start = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the end of the subregion. </summary>
|
||||||
|
/// <value> The end of the subregion. </value>
|
||||||
|
public TimeSpan End
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.end;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.end = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the operation to be performed on the subregion. </summary>
|
||||||
|
/// <value> The operation to be performed on subregion. </value>
|
||||||
|
public RegionType SubregionType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.subregionType;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.subregionType = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the targeted value of the subregion. </summary>
|
||||||
|
/// <value> The value targeted for the subregion. </value>
|
||||||
|
public decimal Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Gets or sets a value indicating whether the subregion runs to the end of the video. </summary>
|
||||||
|
/// <value> True if the subregion runs to the end, false if not. </value>
|
||||||
|
public bool ToEnd
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.toEnd;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.toEnd = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,12 +9,35 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace butterflow_ui
|
namespace butterflow_ui
|
||||||
{
|
{
|
||||||
public class ButterflowWrapper
|
public class ButterflowWrapper : PropertyChangedAlerter
|
||||||
{
|
{
|
||||||
#region Members
|
#region Members
|
||||||
|
|
||||||
/// <summary> Full pathname of the butterflow executable file. </summary>
|
/// <summary> Full pathname of the butterflow executable file. </summary>
|
||||||
private Lazy<string> executablePath = new Lazy<string>(() => Path.Combine(Assembly.GetExecutingAssembly().Location, "ThirdPartyCompiled", "butterflow.exe"));
|
private Lazy<string> executablePath = new Lazy<string>(() => Path.Combine(Directory.GetCurrentDirectory(), "ThirdPartyCompiled", "butterflow.exe"));
|
||||||
|
/// <summary> The console output from butterflow. </summary>
|
||||||
|
private string consoleOutput = string.Empty;
|
||||||
|
/// <summary> Event queue for all listeners interested in ConsoleOutputRecieved events. </summary>
|
||||||
|
//public event EventHandler<ButterflowConsoleOutputArgs> ConsoleOutputRecieved;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary> Gets the console output from butterflow. </summary>
|
||||||
|
/// <value> The console output from butterflow. </value>
|
||||||
|
public string ConsoleOutput
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.consoleOutput;
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
this.consoleOutput = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -29,20 +52,74 @@ namespace butterflow_ui
|
||||||
Run(arguments);
|
Run(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Probes a video file. </summary>
|
||||||
|
/// <param name="videoFile"> The video file to be probed. </param>
|
||||||
public void Probe(string videoFile)
|
public void Probe(string videoFile)
|
||||||
{
|
{
|
||||||
string arguments = string.Format("-prb \"{0}\"", videoFile);
|
string arguments = string.Format("-prb \"{0}\"", videoFile);
|
||||||
|
Run(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Runs butterflow with the given <paramref name="arguments"/>. </summary>
|
/// <summary> Runs butterflow with the given <paramref name="arguments"/>. </summary>
|
||||||
/// <param name="arguments"> Options for controlling the operation. </param>
|
/// <param name="arguments"> Options for controlling the operation. </param>
|
||||||
private void Run(string arguments)
|
private void Run(string arguments)
|
||||||
{
|
{
|
||||||
var processStartInfo = new ProcessStartInfo(executablePath.Value, arguments);
|
var process = new Process();
|
||||||
|
process.StartInfo = new ProcessStartInfo(executablePath.Value, arguments);
|
||||||
|
|
||||||
processStartInfo.CreateNoWindow = true;
|
process.StartInfo.CreateNoWindow = true;
|
||||||
processStartInfo.UseShellExecute = false;
|
process.StartInfo.UseShellExecute = false;
|
||||||
processStartInfo.RedirectStandardOutput = true;
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
|
process.EnableRaisingEvents = true;
|
||||||
|
process.OutputDataReceived += ProcessOutputDataReceived;
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
process.BeginOutputReadLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Process the output data received from the butterflow executable. </summary>
|
||||||
|
/// <param name="sender"> Source of the event. </param>
|
||||||
|
/// <param name="e"> Data received event information. </param>
|
||||||
|
private void ProcessOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
this.ConsoleOutput += string.Format("{0}{1}", e.Data, Environment.NewLine);
|
||||||
|
//OnConsoleOutputRecieved(e.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Executes the console output recieved event handler. </summary>
|
||||||
|
/// <param name="output"> The output that has been recieved from butterflow. </param>
|
||||||
|
//protected void OnConsoleOutputRecieved(string output)
|
||||||
|
//{
|
||||||
|
// if (this.ConsoleOutputRecieved != null)
|
||||||
|
// {
|
||||||
|
// this.ConsoleOutputRecieved(this, new ButterflowConsoleOutputArgs(output));
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Subclasses
|
||||||
|
|
||||||
|
public class ButterflowConsoleOutputArgs : EventArgs
|
||||||
|
{
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary> Gets the console output. </summary>
|
||||||
|
/// <value> The console output. </value>
|
||||||
|
public string ConsoleOutput { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary> Constructor. </summary>
|
||||||
|
/// <param name="consoleOutput"> The console output. </param>
|
||||||
|
public ButterflowConsoleOutputArgs(string consoleOutput)
|
||||||
|
{
|
||||||
|
this.ConsoleOutput = consoleOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -112,4 +112,22 @@
|
||||||
</Path>
|
</Path>
|
||||||
</Viewbox>
|
</Viewbox>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
|
<ControlTemplate x:Key="SnipOpenIcon">
|
||||||
|
<Viewbox>
|
||||||
|
<Path Fill="#000000">
|
||||||
|
<Path.Data>
|
||||||
|
<PathGeometry Figures="M12.026 14.116c-3.475 1.673-7.504 3.619-8.484 4.09-1.848.889-3.542-1.445-3.542-1.445l8.761-4.226 3.265 1.581zm7.93 6.884c-.686 0-1.393-.154-2.064-.479-1.943-.941-2.953-3.001-2.498-4.854.26-1.057-.296-1.201-1.145-1.612l-14.189-6.866s1.7-2.329 3.546-1.436c1.134.549 5.689 2.747 9.614 4.651l.985-.474c.85-.409 1.406-.552 1.149-1.609-.451-1.855.564-3.913 2.51-4.848.669-.321 1.373-.473 2.054-.473 2.311 0 4.045 1.696 4.045 3.801 0 1.582-.986 3.156-2.613 3.973-1.625.816-2.765.18-4.38.965l-.504.245.552.27c1.613.789 2.754.156 4.377.976 1.624.819 2.605 2.392 2.605 3.97 0 2.108-1.739 3.8-4.044 3.8zm-2.555-12.815c.489 1.022 1.876 1.378 3.092.793 1.217-.584 1.809-1.893 1.321-2.916-.489-1.022-1.876-1.379-3.093-.794s-1.808 1.894-1.32 2.917zm-3.643 3.625c0-.414-.335-.75-.75-.75-.414 0-.75.336-.75.75s.336.75.75.75.75-.336.75-.75zm6.777 3.213c-1.215-.588-2.604-.236-3.095.786-.491 1.022.098 2.332 1.313 2.919 1.215.588 2.603.235 3.094-.787.492-1.021-.097-2.33-1.312-2.918z" FillRule="NonZero"/>
|
||||||
|
</Path.Data>
|
||||||
|
</Path>
|
||||||
|
</Viewbox>
|
||||||
|
</ControlTemplate>
|
||||||
|
<ControlTemplate x:Key="SnipCloseIcon">
|
||||||
|
<Viewbox>
|
||||||
|
<Path Fill="#000000">
|
||||||
|
<Path.Data>
|
||||||
|
<PathGeometry Figures="M14.686 13.646l-6.597 3.181c-1.438.692-2.755-1.124-2.755-1.124l6.813-3.287 2.539 1.23zm6.168 5.354c-.533 0-1.083-.119-1.605-.373-1.511-.731-2.296-2.333-1.943-3.774.203-.822-.23-.934-.891-1.253l-11.036-5.341s1.322-1.812 2.759-1.117c.881.427 4.423 2.136 7.477 3.617l.766-.368c.662-.319 1.094-.43.895-1.252-.351-1.442.439-3.043 1.952-3.77.521-.251 1.068-.369 1.596-.369 1.799 0 3.147 1.32 3.147 2.956 0 1.23-.766 2.454-2.032 3.091-1.266.634-2.15.14-3.406.75l-.394.19.431.21c1.254.614 2.142.122 3.404.759 1.262.638 2.026 1.861 2.026 3.088 0 1.64-1.352 2.956-3.146 2.956zm-1.987-9.967c.381.795 1.459 1.072 2.406.617.945-.455 1.405-1.472 1.027-2.267-.381-.796-1.46-1.073-2.406-.618-.946.455-1.408 1.472-1.027 2.268zm-2.834 2.819c0-.322-.261-.583-.583-.583-.321 0-.583.261-.583.583s.262.583.583.583c.322.001.583-.261.583-.583zm5.272 2.499c-.945-.457-2.025-.183-2.408.611-.381.795.078 1.814 1.022 2.271.945.458 2.024.184 2.406-.611.382-.795-.075-1.814-1.02-2.271zm-18.305-3.351h-3v2h3v-2zm4 0h-3v2h3v-2z" FillRule="NonZero"/>
|
||||||
|
</Path.Data>
|
||||||
|
</Path>
|
||||||
|
</Viewbox>
|
||||||
|
</ControlTemplate>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
90
butterflow-ui/Localization/Localization.Designer.cs
generated
90
butterflow-ui/Localization/Localization.Designer.cs
generated
|
@ -159,6 +159,15 @@ namespace butterflow_ui.Localization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Clip a subregion in the video..
|
||||||
|
/// </summary>
|
||||||
|
public static string ClipTooltip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ClipTooltip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Common Options.
|
/// Looks up a localized string similar to Common Options.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -186,6 +195,15 @@ namespace butterflow_ui.Localization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to E.
|
||||||
|
/// </summary>
|
||||||
|
public static string EndLabel {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("EndLabel", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Input.
|
/// Looks up a localized string similar to Input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -285,6 +303,15 @@ namespace butterflow_ui.Localization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Play/Pause the video..
|
||||||
|
/// </summary>
|
||||||
|
public static string PlayPauseTooltip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("PlayPauseTooltip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Video Rendering.
|
/// Looks up a localized string similar to Video Rendering.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -303,6 +330,60 @@ namespace butterflow_ui.Localization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Skip backward in the video..
|
||||||
|
/// </summary>
|
||||||
|
public static string SkipBackTooltip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SkipBackTooltip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Skip forward in the video..
|
||||||
|
/// </summary>
|
||||||
|
public static string SkipForwardTooltip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SkipForwardTooltip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to S.
|
||||||
|
/// </summary>
|
||||||
|
public static string StartLabel {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("StartLabel", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Stop the video..
|
||||||
|
/// </summary>
|
||||||
|
public static string StopTooltip {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("StopTooltip", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Individual regions of the video to process..
|
||||||
|
/// </summary>
|
||||||
|
public static string SubregionsDescription {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SubregionsDescription", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Subregions.
|
||||||
|
/// </summary>
|
||||||
|
public static string SubregionsLabel {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SubregionsLabel", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to butterflow-ui.
|
/// Looks up a localized string similar to butterflow-ui.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -312,6 +393,15 @@ namespace butterflow_ui.Localization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to To End.
|
||||||
|
/// </summary>
|
||||||
|
public static string ToEndLabel {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ToEndLabel", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Width.
|
/// Looks up a localized string similar to Width.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -129,6 +129,9 @@
|
||||||
<data name="AdvancedOptionsGroupBox" xml:space="preserve">
|
<data name="AdvancedOptionsGroupBox" xml:space="preserve">
|
||||||
<value>Advanced Options</value>
|
<value>Advanced Options</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ClipTooltip" xml:space="preserve">
|
||||||
|
<value>Clip a subregion in the video.</value>
|
||||||
|
</data>
|
||||||
<data name="CommonOptionsGroupBox" xml:space="preserve">
|
<data name="CommonOptionsGroupBox" xml:space="preserve">
|
||||||
<value>Common Options</value>
|
<value>Common Options</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -138,6 +141,9 @@
|
||||||
<data name="EditMenu" xml:space="preserve">
|
<data name="EditMenu" xml:space="preserve">
|
||||||
<value>_Edit</value>
|
<value>_Edit</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EndLabel" xml:space="preserve">
|
||||||
|
<value>E</value>
|
||||||
|
</data>
|
||||||
<data name="FileInputGroupBox" xml:space="preserve">
|
<data name="FileInputGroupBox" xml:space="preserve">
|
||||||
<value>Input</value>
|
<value>Input</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -171,15 +177,39 @@
|
||||||
<data name="PlaybackRateLabel" xml:space="preserve">
|
<data name="PlaybackRateLabel" xml:space="preserve">
|
||||||
<value>Playback Rate</value>
|
<value>Playback Rate</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="PlayPauseTooltip" xml:space="preserve">
|
||||||
|
<value>Play/Pause the video.</value>
|
||||||
|
</data>
|
||||||
<data name="RenderingLabel" xml:space="preserve">
|
<data name="RenderingLabel" xml:space="preserve">
|
||||||
<value>Video Rendering</value>
|
<value>Video Rendering</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ResolutionLabel" xml:space="preserve">
|
<data name="ResolutionLabel" xml:space="preserve">
|
||||||
<value>Output Resolution</value>
|
<value>Output Resolution</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SkipBackTooltip" xml:space="preserve">
|
||||||
|
<value>Skip backward in the video.</value>
|
||||||
|
</data>
|
||||||
|
<data name="SkipForwardTooltip" xml:space="preserve">
|
||||||
|
<value>Skip forward in the video.</value>
|
||||||
|
</data>
|
||||||
|
<data name="StartLabel" xml:space="preserve">
|
||||||
|
<value>S</value>
|
||||||
|
</data>
|
||||||
|
<data name="StopTooltip" xml:space="preserve">
|
||||||
|
<value>Stop the video.</value>
|
||||||
|
</data>
|
||||||
|
<data name="SubregionsDescription" xml:space="preserve">
|
||||||
|
<value>Individual regions of the video to process.</value>
|
||||||
|
</data>
|
||||||
|
<data name="SubregionsLabel" xml:space="preserve">
|
||||||
|
<value>Subregions</value>
|
||||||
|
</data>
|
||||||
<data name="Title" xml:space="preserve">
|
<data name="Title" xml:space="preserve">
|
||||||
<value>butterflow-ui</value>
|
<value>butterflow-ui</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ToEndLabel" xml:space="preserve">
|
||||||
|
<value>To End</value>
|
||||||
|
</data>
|
||||||
<data name="WidthLabel" xml:space="preserve">
|
<data name="WidthLabel" xml:space="preserve">
|
||||||
<value>Width</value>
|
<value>Width</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -3,12 +3,21 @@
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:System="clr-namespace:System;assembly=mscorlib"
|
||||||
xmlns:gu="https://github.com/JohanLarsson/Gu.Wpf.Media"
|
xmlns:gu="https://github.com/JohanLarsson/Gu.Wpf.Media"
|
||||||
xmlns:loc="clr-namespace:butterflow_ui.Localization"
|
xmlns:loc="clr-namespace:butterflow_ui.Localization"
|
||||||
xmlns:butterflow_ui="clr-namespace:butterflow_ui"
|
xmlns:butterflow_ui="clr-namespace:butterflow_ui"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
x:Name="butterflowUIWindow"
|
x:Name="butterflowUIWindow"
|
||||||
Title="{x:Static loc:Localization.Title}" Height="600" Width="800">
|
Title="{x:Static loc:Localization.Title}" Height="600" Width="800">
|
||||||
|
<Window.Resources>
|
||||||
|
<ObjectDataProvider x:Key="enumDataProvider" MethodName="GetValues"
|
||||||
|
ObjectType="{x:Type System:Enum}">
|
||||||
|
<ObjectDataProvider.MethodParameters>
|
||||||
|
<x:Type TypeName="butterflow_ui:RegionType"/>
|
||||||
|
</ObjectDataProvider.MethodParameters>
|
||||||
|
</ObjectDataProvider>
|
||||||
|
</Window.Resources>
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<Menu DockPanel.Dock="Top">
|
<Menu DockPanel.Dock="Top">
|
||||||
<MenuItem Header="{x:Static loc:Localization.FileMenu}">
|
<MenuItem Header="{x:Static loc:Localization.FileMenu}">
|
||||||
|
@ -134,18 +143,39 @@
|
||||||
<GroupBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Header="{x:Static loc:Localization.AdvancedOptionsGroupBox}">
|
<GroupBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Header="{x:Static loc:Localization.AdvancedOptionsGroupBox}">
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
|
<butterflow_ui:ButterflowOption LabelValue="{x:Static loc:Localization.SubregionsLabel}" DescriptionValue="{x:Static loc:Localization.SubregionsDescription}">
|
||||||
|
<ListView Name="listSubregions" MinHeight="25" ItemsSource="{Binding OptionsConfiguration.Subregions, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type butterflow_ui:MainWindow}}, UpdateSourceTrigger=PropertyChanged}">
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<WrapPanel>
|
||||||
|
<TextBlock Text="{x:Static loc:Localization.StartLabel}" />
|
||||||
|
<TextBlock Text="{Binding Start, Converter={x:Static gu:TimeSpanToStringConverter.Default}}" ToolTip="{Binding Start}"/>
|
||||||
|
<TextBlock Text="{x:Static loc:Localization.EndLabel}" />
|
||||||
|
<TextBlock Text="{Binding End, Converter={x:Static gu:TimeSpanToStringConverter.Default}}" ToolTip="{Binding End}"/>
|
||||||
|
<ComboBox ItemsSource="{Binding Source={StaticResource enumDataProvider}}" SelectedItem="{Binding SubregionType, Mode=TwoWay}"/>
|
||||||
|
<TextBox MinWidth="35" Text="{Binding Value, Mode=TwoWay}" />
|
||||||
|
<TextBlock Text="{x:Static loc:Localization.ToEndLabel}" />
|
||||||
|
<CheckBox IsChecked="{Binding ToEnd, Mode=TwoWay}" />
|
||||||
|
</WrapPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
</butterflow_ui:ButterflowOption>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
<Grid Grid.Row="1" Grid.RowSpan="2" Grid.Column="2" Grid.ColumnSpan="2">
|
<Grid Grid.Row="1" Grid.RowSpan="2" Grid.Column="2" Grid.ColumnSpan="2">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="0.3*" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<gu:MediaElementWrapper Grid.Row="0" Name="mediaPreview" Stretch="Uniform" ScrubbingEnabled="True" Source="{Binding OptionsConfiguration.VideoInput, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type butterflow_ui:MainWindow}}, UpdateSourceTrigger=PropertyChanged}" MediaOpened="mediaPreview_MediaOpened" MediaEnded="mediaPreview_MediaEnded" />
|
<ScrollViewer VerticalScrollBarVisibility="Auto" ScrollChanged="ScrollViewer_ScrollChanged">
|
||||||
<Grid Grid.Row="1">
|
<TextBlock Grid.Row="0" Name="txtConsoleOutput" Background="Black" Foreground="White" TextWrapping="Wrap" Text="{Binding ButterflowWrapper.ConsoleOutput, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type butterflow_ui:MainWindow}}, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
</ScrollViewer>
|
||||||
|
<gu:MediaElementWrapper Grid.Row="1" Name="mediaPreview" Stretch="Uniform" ScrubbingEnabled="True" Source="{Binding OptionsConfiguration.VideoInput, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type butterflow_ui:MainWindow}}, UpdateSourceTrigger=PropertyChanged}" MediaOpened="mediaPreview_MediaOpened" MediaEnded="mediaPreview_MediaEnded" />
|
||||||
|
<Grid Grid.Row="2">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
|
@ -157,7 +187,7 @@
|
||||||
Maximum="{Binding Path=Length, ElementName=mediaPreview, Converter={x:Static gu:NullableTimeSpanToSecondsConverter.Default}}" />
|
Maximum="{Binding Path=Length, ElementName=mediaPreview, Converter={x:Static gu:NullableTimeSpanToSecondsConverter.Default}}" />
|
||||||
<Label Grid.Column="2" Content="{Binding Path=Length, ElementName=mediaPreview, Converter={x:Static gu:TimeSpanToStringConverter.Default}}" />
|
<Label Grid.Column="2" Content="{Binding Path=Length, ElementName=mediaPreview, Converter={x:Static gu:TimeSpanToStringConverter.Default}}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
|
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
<Button Name="bntVideoBackward" BorderThickness="0" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Click="bntVideoBackward_Click">
|
<Button Name="bntVideoBackward" BorderThickness="0" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Click="bntVideoBackward_Click">
|
||||||
<ContentControl HorizontalAlignment="Center" Template="{StaticResource BackwardIcon}" />
|
<ContentControl HorizontalAlignment="Center" Template="{StaticResource BackwardIcon}" />
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -170,6 +200,9 @@
|
||||||
<Button Name="bntVideoForward" BorderThickness="0" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Click="bntVideoForward_Click">
|
<Button Name="bntVideoForward" BorderThickness="0" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Click="bntVideoForward_Click">
|
||||||
<ContentControl HorizontalAlignment="Center" Template="{StaticResource ForwardIcon}" />
|
<ContentControl HorizontalAlignment="Center" Template="{StaticResource ForwardIcon}" />
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button Name="bntClip" BorderThickness="0" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Click="bntClip_Click">
|
||||||
|
<ContentControl HorizontalAlignment="Center" Name="ClippingButtonIcon" Template="{StaticResource SnipOpenIcon}" />
|
||||||
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<StatusBar Grid.Row="3" Grid.ColumnSpan="4">
|
<StatusBar Grid.Row="3" Grid.ColumnSpan="4">
|
||||||
|
|
|
@ -23,15 +23,20 @@ namespace butterflow_ui
|
||||||
{
|
{
|
||||||
#region Members
|
#region Members
|
||||||
|
|
||||||
//
|
/// <summary> True if is the user has started clipping, false if not. </summary>
|
||||||
|
private bool isClipping;
|
||||||
|
/// <summary> The temporary storage for the clip start time. </summary>
|
||||||
|
private TimeSpan clipStart;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary> Gets or sets the butyterflow options configuration. </summary>
|
/// <summary> Gets or sets the butterflow options configuration. </summary>
|
||||||
/// <value> The options configuration. </value>
|
/// <value> The options configuration. </value>
|
||||||
public OptionsConfiguration OptionsConfiguration { get; set; } = new OptionsConfiguration();
|
public OptionsConfiguration OptionsConfiguration { get; set; } = new OptionsConfiguration();
|
||||||
|
/// <summary> The butterflow wrapper used to call butterflow. </summary>
|
||||||
|
public ButterflowWrapper ButterflowWrapper { get; set; } = new ButterflowWrapper();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -49,12 +54,14 @@ namespace butterflow_ui
|
||||||
var ofd = new OpenFileDialog();
|
var ofd = new OpenFileDialog();
|
||||||
ofd.Filter = "Supported Video Files|*.mp4;*.mkv";
|
ofd.Filter = "Supported Video Files|*.mp4;*.mkv";
|
||||||
|
|
||||||
|
|
||||||
var result = ofd.ShowDialog(this);
|
var result = ofd.ShowDialog(this);
|
||||||
if (result.HasValue && result.Value)
|
if (result.HasValue && result.Value)
|
||||||
{
|
{
|
||||||
this.OptionsConfiguration.VideoInput = ofd.FileName;
|
this.OptionsConfiguration.VideoInput = ofd.FileName;
|
||||||
|
|
||||||
|
//this.ButterflowWrapper.ConsoleOutputRecieved += (o, ce) => this.txtConsoleOutput.Text = ce.ConsoleOutput;
|
||||||
|
this.ButterflowWrapper.Probe(ofd.FileName);
|
||||||
|
|
||||||
//Hack to get the first frame to display in the media preview element.
|
//Hack to get the first frame to display in the media preview element.
|
||||||
//This also triggers the MediaOpened event so we can get the metadata from the element.
|
//This also triggers the MediaOpened event so we can get the metadata from the element.
|
||||||
mediaPreview.Play();
|
mediaPreview.Play();
|
||||||
|
@ -69,7 +76,7 @@ namespace butterflow_ui
|
||||||
{
|
{
|
||||||
var typedSender = (RadioButton)sender;
|
var typedSender = (RadioButton)sender;
|
||||||
|
|
||||||
if(typedSender != null)
|
if (typedSender != null)
|
||||||
{
|
{
|
||||||
var tag = typedSender.Tag.ToString();
|
var tag = typedSender.Tag.ToString();
|
||||||
this.OptionsConfiguration.PlaybackRate = tag;
|
this.OptionsConfiguration.PlaybackRate = tag;
|
||||||
|
@ -86,7 +93,7 @@ namespace butterflow_ui
|
||||||
this.mediaPreview.TogglePlayPause();
|
this.mediaPreview.TogglePlayPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.mediaPreview.IsPlaying)
|
if (this.mediaPreview.IsPlaying)
|
||||||
{
|
{
|
||||||
this.PlayPauseButtonIcon.Template = Application.Current.Resources["PauseIcon"] as ControlTemplate;
|
this.PlayPauseButtonIcon.Template = Application.Current.Resources["PauseIcon"] as ControlTemplate;
|
||||||
}
|
}
|
||||||
|
@ -127,6 +134,31 @@ namespace butterflow_ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Event handler. Called by bntClip for click events. </summary>
|
||||||
|
/// <param name="sender"> Source of the event. </param>
|
||||||
|
/// <param name="e"> Routed event information. </param>
|
||||||
|
private void bntClip_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (this.mediaPreview.Position.HasValue)
|
||||||
|
{
|
||||||
|
if (!this.isClipping)
|
||||||
|
{
|
||||||
|
//start clipping
|
||||||
|
this.isClipping = true;
|
||||||
|
this.ClippingButtonIcon.Template = Application.Current.Resources["SnipCloseIcon"] as ControlTemplate;
|
||||||
|
this.clipStart = this.mediaPreview.Position.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//end clipping
|
||||||
|
this.isClipping = false;
|
||||||
|
this.ClippingButtonIcon.Template = Application.Current.Resources["SnipOpenIcon"] as ControlTemplate;
|
||||||
|
this.OptionsConfiguration.Subregions.Add(new ButterflowSubregion() { Start = this.clipStart, End = this.mediaPreview.Position.Value, ToEnd = false, Value = 1, SubregionType = RegionType.spd });
|
||||||
|
this.clipStart = TimeSpan.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Event handler. Called by mediaPreview for media opened events. </summary>
|
/// <summary> Event handler. Called by mediaPreview for media opened events. </summary>
|
||||||
/// <param name="sender"> Source of the event. </param>
|
/// <param name="sender"> Source of the event. </param>
|
||||||
/// <param name="e"> Routed event information. </param>
|
/// <param name="e"> Routed event information. </param>
|
||||||
|
@ -143,5 +175,43 @@ namespace butterflow_ui
|
||||||
{
|
{
|
||||||
this.PlayPauseButtonIcon.Template = Application.Current.Resources["PlayIcon"] as ControlTemplate;
|
this.PlayPauseButtonIcon.Template = Application.Current.Resources["PlayIcon"] as ControlTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Event handler. Called by ScrollViewer for scroll changed events. </summary>
|
||||||
|
/// <param name="sender"> Source of the event. </param>
|
||||||
|
/// <param name="e"> Scroll changed event information. </param>
|
||||||
|
/// <remarks>
|
||||||
|
/// This code autoscrolls the scroll viewer as more text is added. It is based on this example
|
||||||
|
/// from Stack Overflow:
|
||||||
|
/// https://stackoverflow.com/questions/2984803/how-to-automatically-scroll-scrollviewer-only-if-the-user-did-not-change-scrol.
|
||||||
|
/// </remarks>
|
||||||
|
private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var scrollViewer = sender as ScrollViewer;
|
||||||
|
bool autoScroll = true;
|
||||||
|
|
||||||
|
if (scrollViewer != null)
|
||||||
|
{
|
||||||
|
if (e.ExtentHeightChange == 0)
|
||||||
|
{ // Content unchanged : user scroll event
|
||||||
|
if (scrollViewer.VerticalOffset == scrollViewer.ScrollableHeight)
|
||||||
|
{ // Scroll bar is in bottom
|
||||||
|
// Set auto-scroll mode
|
||||||
|
autoScroll = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Scroll bar isn't in bottom
|
||||||
|
// Unset auto-scroll mode
|
||||||
|
autoScroll = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Content scroll event : auto-scroll eventually
|
||||||
|
if (autoScroll && e.ExtentHeightChange != 0)
|
||||||
|
{ // Content changed and auto-scroll mode set
|
||||||
|
// Autoscroll
|
||||||
|
scrollViewer.ScrollToEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -11,13 +12,10 @@ namespace butterflow_ui
|
||||||
|
|
||||||
/// <summary> (Serializable) the options configuration. </summary>
|
/// <summary> (Serializable) the options configuration. </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class OptionsConfiguration : INotifyPropertyChanged
|
public class OptionsConfiguration : PropertyChangedAlerter
|
||||||
{
|
{
|
||||||
#region Members
|
#region Members
|
||||||
|
|
||||||
/// <summary> Occurs when a property value changes. </summary>
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
/// <summary> An interpreter used to ensure numeric input is correctly calculated. </summary>
|
/// <summary> An interpreter used to ensure numeric input is correctly calculated. </summary>
|
||||||
private InputInterpreter interpreter = new InputInterpreter();
|
private InputInterpreter interpreter = new InputInterpreter();
|
||||||
|
|
||||||
|
@ -29,6 +27,7 @@ namespace butterflow_ui
|
||||||
private bool losslessQuality;
|
private bool losslessQuality;
|
||||||
private string videoInput;
|
private string videoInput;
|
||||||
private string videoOutput;
|
private string videoOutput;
|
||||||
|
private ObservableCollection<ButterflowSubregion> subregions = new ObservableCollection<ButterflowSubregion>();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ namespace butterflow_ui
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.playbackRate = value;
|
this.playbackRate = value;
|
||||||
OnPropertyChanged("PlaybackRate");
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +69,7 @@ namespace butterflow_ui
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.keepAudio = value;
|
this.keepAudio = value;
|
||||||
OnPropertyChanged("KeepAudio");
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +85,7 @@ namespace butterflow_ui
|
||||||
{
|
{
|
||||||
interpreter.Interpret(value);
|
interpreter.Interpret(value);
|
||||||
this.width = interpreter.Int;
|
this.width = interpreter.Int;
|
||||||
OnPropertyChanged("Width");
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +101,7 @@ namespace butterflow_ui
|
||||||
{
|
{
|
||||||
interpreter.Interpret(value);
|
interpreter.Interpret(value);
|
||||||
this.height = interpreter.Int;
|
this.height = interpreter.Int;
|
||||||
OnPropertyChanged("Height");
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +116,7 @@ namespace butterflow_ui
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.keepAspectRatio = value;
|
this.keepAspectRatio = value;
|
||||||
OnPropertyChanged("KeepAspectRatio");
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +131,7 @@ namespace butterflow_ui
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.losslessQuality = value;
|
this.losslessQuality = value;
|
||||||
OnPropertyChanged("LosslessQuality");
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +146,7 @@ namespace butterflow_ui
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.videoInput = value;
|
this.videoInput = value;
|
||||||
OnPropertyChanged("VideoInput");
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,20 +161,64 @@ namespace butterflow_ui
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.videoOutput = value;
|
this.videoOutput = value;
|
||||||
OnPropertyChanged("VideoOutput");
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the subregions of the video on which to work. </summary>
|
||||||
|
/// <value> The subregions of the video. </value>
|
||||||
|
public ObservableCollection<ButterflowSubregion> Subregions
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.subregions;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.subregions = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Contructors
|
||||||
|
|
||||||
|
/// <summary> Default constructor. </summary>
|
||||||
|
public OptionsConfiguration()
|
||||||
|
{
|
||||||
|
AddConstantCallProperty("CommandLineOutput");
|
||||||
|
|
||||||
|
this.subregions.CollectionChanged += SubregionsCollectionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubregionsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if(e.NewItems != null)
|
||||||
|
{
|
||||||
|
foreach(ButterflowSubregion newItem in e.NewItems)
|
||||||
|
{
|
||||||
|
newItem.PropertyChanged += SubregionPropertyChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(e.OldItems != null)
|
||||||
|
{
|
||||||
|
foreach(ButterflowSubregion oldItem in e.OldItems)
|
||||||
|
{
|
||||||
|
oldItem.PropertyChanged -= SubregionPropertyChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPropertyChanged("CommandLineOutput");
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
/// <summary> Executes the property changed action. </summary>
|
private void SubregionPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
/// <param name="name"> The name. </param>
|
|
||||||
protected void OnPropertyChanged(string name)
|
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
OnPropertyChanged("CommandLineOutput");
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CommandLineOutput"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Converts this object to a butterflow options. </summary>
|
/// <summary> Converts this object to a butterflow options. </summary>
|
||||||
|
@ -184,7 +227,7 @@ namespace butterflow_ui
|
||||||
{
|
{
|
||||||
var stringBuilder = new StringBuilder("-v "); //Verbose
|
var stringBuilder = new StringBuilder("-v "); //Verbose
|
||||||
|
|
||||||
if(this.KeepAspectRatio)
|
if (this.KeepAspectRatio)
|
||||||
{
|
{
|
||||||
stringBuilder.AppendFormat("-vs {0}:-1 ", this.Width);
|
stringBuilder.AppendFormat("-vs {0}:-1 ", this.Width);
|
||||||
}
|
}
|
||||||
|
@ -193,13 +236,37 @@ namespace butterflow_ui
|
||||||
stringBuilder.AppendFormat("-vs {0}:{1} ", this.Width, this.Height);
|
stringBuilder.AppendFormat("-vs {0}:{1} ", this.Width, this.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
stringBuilder.AppendFormat("-r {0} ", this.PlaybackRate);
|
if (!string.IsNullOrWhiteSpace(this.PlaybackRate)) stringBuilder.AppendFormat("-r {0} ", this.PlaybackRate);
|
||||||
|
|
||||||
if (this.KeepAudio) stringBuilder.Append("-audio ");
|
if (this.KeepAudio) stringBuilder.Append("-audio ");
|
||||||
if (this.LosslessQuality) stringBuilder.Append("-l ");
|
if (this.LosslessQuality) stringBuilder.Append("-l ");
|
||||||
|
|
||||||
stringBuilder.AppendFormat("\"{0}\"", this.VideoInput);
|
stringBuilder.AppendFormat("\"{0}\"", this.VideoInput);
|
||||||
|
|
||||||
|
if (this.Subregions.Any())
|
||||||
|
{
|
||||||
|
foreach (var anon in this.Subregions.Select((sr, index) => new { Index = index, Subregion = sr }))
|
||||||
|
{
|
||||||
|
string format = "ss\\.fff";
|
||||||
|
|
||||||
|
if (anon.Index > 0)
|
||||||
|
{
|
||||||
|
stringBuilder.Append(":");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anon.Subregion.Start.TotalHours > 1)
|
||||||
|
{
|
||||||
|
format = "h\\:m\\:s\\.fff";
|
||||||
|
}
|
||||||
|
else if (anon.Subregion.Start.TotalMinutes > 1)
|
||||||
|
{
|
||||||
|
format = "m\\:s\\.fff";
|
||||||
|
}
|
||||||
|
|
||||||
|
stringBuilder.AppendFormat("a={0},b={1},{2}={3}", anon.Subregion.Start.ToString(format), anon.Subregion.ToEnd ? "end" : anon.Subregion.End.ToString(format), anon.Subregion.SubregionType, anon.Subregion.Value);
|
||||||
|
}
|
||||||
|
stringBuilder.Append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
return stringBuilder.ToString();
|
return stringBuilder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
56
butterflow-ui/PropertyChangedAlerter.cs
Normal file
56
butterflow-ui/PropertyChangedAlerter.cs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace butterflow_ui
|
||||||
|
{
|
||||||
|
public abstract class PropertyChangedAlerter : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
#region Members
|
||||||
|
|
||||||
|
/// <summary> Occurs when a property value changes. </summary>
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
/// <summary> A list of properties to always call as updated. Generally used for composite properties. </summary>
|
||||||
|
private List<string> alwaysCall = new List<string>();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
/// <summary> Executes the property changed action. </summary>
|
||||||
|
/// <param name="name"> The name. </param>
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName]string name = null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||||
|
foreach (var updatedProperty in this.alwaysCall)
|
||||||
|
{
|
||||||
|
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(updatedProperty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Adds a property that will always be called when any property is updated.. </summary>
|
||||||
|
/// <param name="name"> The name of the property. </param>
|
||||||
|
public void AddConstantCallProperty(string name)
|
||||||
|
{
|
||||||
|
if (!this.alwaysCall.Any(c => c.Equals(name, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
this.alwaysCall.Add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
20
butterflow-ui/RegionType.cs
Normal file
20
butterflow-ui/RegionType.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace butterflow_ui
|
||||||
|
{
|
||||||
|
/// <summary> Values that represent subregion types. </summary>
|
||||||
|
public enum RegionType
|
||||||
|
{
|
||||||
|
/// <summary> Speed. </summary>
|
||||||
|
spd,
|
||||||
|
/// <summary> Duration. </summary>
|
||||||
|
dur,
|
||||||
|
/// <summary> Frames per second. </summary>
|
||||||
|
fps
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -60,6 +60,8 @@
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
|
<Compile Include="PropertyChangedAlerter.cs" />
|
||||||
|
<Compile Include="RegionType.cs" />
|
||||||
<Page Include="Icons.xaml">
|
<Page Include="Icons.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
@ -77,6 +79,7 @@
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="ButterflowOption.cs" />
|
<Compile Include="ButterflowOption.cs" />
|
||||||
|
<Compile Include="ButterflowSubregion.cs" />
|
||||||
<Compile Include="ButterflowWrapper.cs" />
|
<Compile Include="ButterflowWrapper.cs" />
|
||||||
<Compile Include="Localization\Localization.Designer.cs">
|
<Compile Include="Localization\Localization.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|
Loading…
Reference in a new issue