Skip to content

Commit

Permalink
System Tray Features, Reddit Cropping and Bug Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
adanvdo committed May 5, 2022
1 parent 704459d commit 78f85ba
Show file tree
Hide file tree
Showing 25 changed files with 5,173 additions and 271 deletions.
52 changes: 47 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This project is UNLICENSED and uses licensed DevExpress WinForms Controls.
- Windows 7, 8, 10
- .NET Framework 4.8

### Current Features
### Current Features (Scroll Down for More Info)
- List Video Format Options
- Download Selected Format
- Download Best Quality Video
Expand All @@ -17,18 +17,60 @@ This project is UNLICENSED and uses licensed DevExpress WinForms Controls.
- Download History Log / File Browser
- File Format Preference for Downloads
- Segment Downloads for YT and Reddit
- Video Cropping for YT (Reddit In Progress)
- Video Cropping
- Minimize to System Tray
- Quick Download while in System Tray
- Quick Download Hotkey

### Known Issues
- Reddit GIF downloads are not supported

![image](https://user-images.githubusercontent.com/26498008/160806413-9cf735e9-ef8f-4492-af48-92b226cb210b.png)

![image](https://user-images.githubusercontent.com/26498008/160806436-2c31ab5e-4c51-406f-be0e-346dc7218569.png)

![image](https://user-images.githubusercontent.com/26498008/160806455-8a14d646-e87c-4515-9de4-80ecc8baf2d9.png)


## YT-RED Youtube & Reddit Video Downloader
### How To Use

YT-RED's main interface is pretty straight forward. Simply enter the URL of any Youtube video or reddit video post in address bar of the corresponding tab.

- #### List Formats
Both Youtube and Reddit tabs have a "List Formats" button.
This will retrieve all video formats available to download.
An individual format can be selected and downloaded.

- #### Download Best
The "Download Best" option evaluates all available video and audio formats before downloading the best available.

*Note* Download Best often requires downloading separate video and audio files, which are then merged after downloading. This can take a little longer than downloading a specific format.

- #### Download Segment
The "Download Segment" option can be toggled on and off. This feature is only available when downloading a specific format in order to improve performance and reduce resource usage.

Specify the start time of the segment, and the duration.

- #### Crop Video
The "Crop Video" option is available for all video downloads. The feature only accepts crop sizes in pixels at this time.

Enter the number of pixels to crop on each desired side, and then start the download.

- #### Quick Downloads
Quick Download is only available when YT-RED has been minimized to the System Tray. Right-click on the YT-RED icon in the tray, and select "Quick Download" to open the Quick Download form.

- #### Quick Download Hotkey
When the Quick Download Hotkey is enabled in advanced settings, YT-RED will register a custom Hotkey that initiates a Quick Download.

To use, Highlight a youtube or reddit media post url in your browser, and press the configured hotkey. This will perform an automatic "Best Download" with the progress displayed above the system tray.

## CHANGELOG

### 5/5/2022 v1.0.0.7
- Added System Tray Support - Can now be minimized to System Tray
- Added Quick Download Hotkey Feature
- Added "About" Section in Settings
- Fully Implemented Crop Feature for Youtube and Reddit downloads
- Fixed bug where youtube "Best" downloads were not converted to preferred format

### 4/27/2022 v1.0.0.6
- Added Video Cropping for YouTube Downloads
- Added Function in Settings to Delete Downloaded Files
Expand Down
4 changes: 3 additions & 1 deletion YT-RED/AppFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public enum AppFeature
[Description("General")]
General = 0,
[Description("Advanced")]
Advanced = 1
Advanced = 1,
[Description("About")]
About = 2
}
}
15 changes: 15 additions & 0 deletions YT-RED/Classes/AssemblyBuildAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace YT_RED.Classes
{
[AttributeUsage(AttributeTargets.Assembly)]
public class AssemblyBuildAttribute : Attribute
{
public string Value { get; set; }
public AssemblyBuildAttribute() : this("") { }
public AssemblyBuildAttribute(string value) { Value = value; }
}
}
41 changes: 41 additions & 0 deletions YT-RED/Classes/HotkeyConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Windows.Forms;
using DevExpress.Utils;

namespace YT_RED.Classes
{
public class HotkeyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(KeyShortcut));
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);

string keys = token.ToString();
KeysConverter keysConverter = new KeysConverter();
Keys dlKey = (Keys)keysConverter.ConvertFrom(keys);
KeyShortcut keyShortcut = new KeyShortcut(dlKey);
return keyShortcut;
}

public override bool CanWrite
{
get { return false; }
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}
149 changes: 149 additions & 0 deletions YT-RED/Classes/KeyboardHook.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Input;

namespace YT_RED.Classes
{
public sealed class KeyboardHook : IDisposable
{
// Registers a hot key with Windows.
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
// Unregisters the hot key with Windows.
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

/// <summary>
/// Represents the window that is used internally to get the messages.
/// </summary>
private class Window : NativeWindow, IDisposable
{
private static int WM_HOTKEY = 0x0312;

public Window()
{
// create the handle for the window.
this.CreateHandle(new CreateParams());
}

/// <summary>
/// Overridden to get the notifications.
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);

// check if we got a hot key pressed.
if (m.Msg == WM_HOTKEY)
{
// get the keys.
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF);
ModifierKeys modifier = (ModifierKeys)((int)m.LParam & 0xFFFF);

// invoke the event to notify the parent.
if (KeyPressed != null)
KeyPressed(this, new KeyPressedEventArgs(modifier, key));
}
}

public event EventHandler<KeyPressedEventArgs> KeyPressed;

#region IDisposable Members

public void Dispose()
{
this.DestroyHandle();
}

#endregion
}

private Window _window = new Window();
private int _currentId;

public KeyboardHook()
{
// register the event of the inner native window.
_window.KeyPressed += delegate (object sender, KeyPressedEventArgs args)
{
if (KeyPressed != null)
KeyPressed(this, args);
};
}

/// <summary>
/// Registers a hot key in the system.
/// </summary>
/// <param name="modifier">The modifiers that are associated with the hot key.</param>
/// <param name="key">The key itself that is associated with the hot key.</param>
public void RegisterHotKey(ModifierKeys modifier, Keys key)
{
// increment the counter.
_currentId = _currentId + 1;

// register the hot key.
if (!RegisterHotKey(_window.Handle, _currentId, (uint)modifier, (uint)key))
MessageBox.Show("Failed to register Hotkey");
}

public void UnregisterHotKey()
{
for (int i = _currentId; i > 0; i--)
{
UnregisterHotKey(_window.Handle, i);
}
}

/// <summary>
/// A hot key has been pressed.
/// </summary>
public event EventHandler<KeyPressedEventArgs> KeyPressed;

#region IDisposable Members

public void Dispose()
{
// unregister all the registered hot keys.
for (int i = _currentId; i > 0; i--)
{
UnregisterHotKey(_window.Handle, i);
}

// dispose the inner native window.
_window.Dispose();
}

#endregion
}

/// <summary>
/// Event Args for the event that is fired after the hot key has been pressed.
/// </summary>
public class KeyPressedEventArgs : EventArgs
{
private ModifierKeys _modifier;
private Keys _key;

internal KeyPressedEventArgs(ModifierKeys modifier, Keys key)
{
_modifier = modifier;
_key = key;
}

public ModifierKeys Modifier
{
get { return _modifier; }
}

public Keys Key
{
get { return _key; }
}
}
}
13 changes: 8 additions & 5 deletions YT-RED/Controls/PropertyGrid.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 16 additions & 1 deletion YT-RED/Controls/PropertyGrid.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Repository;
using System;
using System.Collections.Generic;
using System.ComponentModel;
Expand All @@ -8,6 +9,7 @@
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraVerticalGrid;

namespace YT_RED.Controls
{
Expand All @@ -18,9 +20,22 @@ public partial class PropertyGrid : DevExpress.XtraEditors.XtraUserControl
public int GridTabIndex { get { return this.pgcPropertyGrid.TabIndex; } set { this.pgcPropertyGrid.TabIndex = value; } }

public object SelectedObject { get { return this.pgcPropertyGrid.SelectedObject; } set { this.pgcPropertyGrid.SelectedObject = value; } }

public PropertyGridControl Grid { get { return this.pgcPropertyGrid; } set { this.pgcPropertyGrid = value; } }

public PropertyGrid()
{
InitializeComponent();

}
}

private void pgcPropertyGrid_CustomPropertyDescriptors(object sender, DevExpress.XtraVerticalGrid.Events.CustomPropertyDescriptorsEventArgs e)
{
if(e.Properties.Find("Version", false) != null)
{
this.pgcPropertyGrid.OptionsBehavior.PropertySort = DevExpress.XtraVerticalGrid.PropertySort.NoSort;
e.Properties = e.Properties.Sort(new string[] { "Version", "Build", "GitHub", "Contact" });
}
}
}
}
4 changes: 4 additions & 0 deletions YT-RED/Controls/SettingsDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ private void createFeatureOptionsPages()
tabPage.Controls.Add(propertyGrid);
tabPage.Name = $"tpg{setting.Feature}";
tabPage.Text = setting.Feature.ToFriendlyString().Replace("&", "&&");
if (setting.Feature == AppFeature.About)
{
propertyGrid.Grid.OptionsBehavior.Editable = false;
}

this.tcSettingsTabControl.TabPages.Add(tabPage);

Expand Down
Loading

0 comments on commit 78f85ba

Please sign in to comment.