diff --git a/README.md b/README.md index 15f7606..9793759 100644 --- a/README.md +++ b/README.md @@ -73,11 +73,14 @@ Scripting is supported via Python, C#, Lua, JavaScript and PowerShell ### Changelog -### 3.0 (20??-??-??) +### 3.0 (2019-04-20) -- the history feature logs only files that were opened longer than 90 seconds +- the history feature logs now only files that were opened longer than 90 seconds - the default input command for cycling the audio tracks was replaced with an mpv.net command that shows detailed track info and has no 'no audio' track +- new web site for mpv.net +- the tracks menu supports now mkv edition selection +- the Navigate menu supports now chapter selection [go to download page](https://github.com/stax76/mpv.net/releases) diff --git a/mpv.net/MainForm.cs b/mpv.net/MainForm.cs index a8cbe97..b9ef1d0 100644 --- a/mpv.net/MainForm.cs +++ b/mpv.net/MainForm.cs @@ -6,10 +6,10 @@ using System.Threading; using System.Windows.Forms; using System.Linq; using System.Collections.Generic; +using System.ComponentModel; using VBNET; -using System.Threading.Tasks; -using System.ComponentModel; +using System.Globalization; namespace mpvnet { @@ -19,11 +19,14 @@ namespace mpvnet public static IntPtr Hwnd { get; set; } public new ContextMenuStripEx ContextMenu; + MenuItemEx TracksMenu; + MenuItemEx ChaptersMenu; Point LastCursorPosChanged; int LastCursorChangedTickCount; bool IgnoreDpiChanged = true; + float MpvAutofit = 0.50f; bool MpvFullscreen; int MpvScreen = -1; @@ -31,6 +34,7 @@ namespace mpvnet string MpvSid = ""; string MpvAid = ""; string MpvVid = ""; + int MpvEdition; public MainForm() { @@ -70,15 +74,17 @@ namespace mpvnet { lock (mp.MediaTracks) { - TracksMenu.DropDownItems.Clear(); + if (TracksMenu != null) + TracksMenu.DropDownItems.Clear(); MediaTrack[] audTracks = mp.MediaTracks.Where(track => track.Type == "a").ToArray(); MediaTrack[] subTracks = mp.MediaTracks.Where(track => track.Type == "s").ToArray(); MediaTrack[] vidTracks = mp.MediaTracks.Where(track => track.Type == "v").ToArray(); + MediaTrack[] ediTracks = mp.MediaTracks.Where(track => track.Type == "e").ToArray(); foreach (MediaTrack track in vidTracks) { - var mi = ContextMenu.Add("Track > " + track.Text); + MenuItemEx mi = ContextMenu.Add("Track > " + track.Text); mi.Action = () => { mp.commandv("set", "vid", track.ID.ToString()); }; mi.Checked = MpvVid == track.ID.ToString(); } @@ -88,7 +94,7 @@ namespace mpvnet foreach (MediaTrack track in audTracks) { - var mi = ContextMenu.Add("Track > " + track.Text); + MenuItemEx mi = ContextMenu.Add("Track > " + track.Text); mi.Action = () => { mp.commandv("set", "aid", track.ID.ToString()); }; mi.Checked = MpvAid == track.ID.ToString(); } @@ -98,17 +104,40 @@ namespace mpvnet foreach (MediaTrack track in subTracks) { - var mi = ContextMenu.Add("Track > " + track.Text); + MenuItemEx mi = ContextMenu.Add("Track > " + track.Text); mi.Action = () => { mp.commandv("set", "sid", track.ID.ToString()); }; mi.Checked = MpvSid == track.ID.ToString(); } if (subTracks.Length > 0) { - var mi = ContextMenu.Add("Track > S: No subtitles"); + MenuItemEx mi = ContextMenu.Add("Track > S: No subtitles"); mi.Action = () => { mp.commandv("set", "sid", "no"); }; mi.Checked = MpvSid == "no"; } + + if (ediTracks.Length > 0) + ContextMenu.Add("Track > -"); + + foreach (MediaTrack track in ediTracks) + { + MenuItemEx mi = ContextMenu.Add("Track > " + track.Text); + mi.Action = () => { mp.commandv("set", "edition", track.ID.ToString()); }; + mi.Checked = MpvEdition == track.ID; + } + } + + lock (mp.Chapters) + { + if (ChaptersMenu != null) + ChaptersMenu.DropDownItems.Clear(); + + foreach (var i in mp.Chapters) + { + MenuItemEx mi = ContextMenu.Add("Navigate > Chapters > " + i.Key); + mi.ShortcutKeyDisplayString = TimeSpan.FromSeconds(i.Value).ToString() + " "; + mi.Action = () => { mp.commandv("seek", i.Value.ToString(CultureInfo.InvariantCulture), "absolute"); }; + } } } @@ -279,6 +308,11 @@ namespace mpvnet menuItem.Text.Trim() == "Track") TracksMenu = menuItem; + + if (ChaptersMenu == null && menuItem.Text.StartsWith("Chapters ") && + menuItem.Text.Trim() == "Chapters") + + ChaptersMenu = menuItem; } } } @@ -467,6 +501,7 @@ namespace mpvnet mp.observe_property_string("sid", mpPropChangeSid); mp.observe_property_string("aid", mpPropChangeAid); mp.observe_property_string("vid", mpPropChangeVid); + mp.observe_property_int("edition", mpPropChangeEdition); mp.Shutdown += mp_Shutdown; mp.VideoSizeChanged += mp_VideoSizeChanged; mp.PlaybackRestart += mp_PlaybackRestart; @@ -481,6 +516,8 @@ namespace mpvnet void mpPropChangeVid(string value) => MpvVid = value; + void mpPropChangeEdition(int value) => MpvEdition = value; + protected override void OnShown(EventArgs e) { base.OnShown(e); diff --git a/mpv.net/Misc.cs b/mpv.net/Misc.cs index e97aa80..dd89d9e 100644 --- a/mpv.net/Misc.cs +++ b/mpv.net/Misc.cs @@ -136,6 +136,6 @@ namespace mpvnet { public string Text { get; set; } public string Type { get; set; } - public int ID { get; set; } + public int ID { get; set; } } } \ No newline at end of file diff --git a/mpv.net/Properties/AssemblyInfo.cs b/mpv.net/Properties/AssemblyInfo.cs index 2461995..3f087c7 100644 --- a/mpv.net/Properties/AssemblyInfo.cs +++ b/mpv.net/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.9.0.0")] -[assembly: AssemblyFileVersion("2.9.0.0")] +[assembly: AssemblyVersion("3.0.0.0")] +[assembly: AssemblyFileVersion("3.0.0.0")] diff --git a/mpv.net/Resources/input.conf.txt b/mpv.net/Resources/input.conf.txt index 99f163b..0c710bb 100644 --- a/mpv.net/Resources/input.conf.txt +++ b/mpv.net/Resources/input.conf.txt @@ -53,6 +53,8 @@ _ ignore #menu: Navigate > - Ctrl+Right no-osd seek 300 #menu: Navigate > Jump 5 min forward Ctrl+Left no-osd seek -300 #menu: Navigate > Jump 5 min backward + _ ignore #menu: Navigate > - + _ ignore #menu: Navigate > Chapters Ctrl++ add video-zoom 0.1 #menu: Pan & Scan > Increase Size Ctrl+- add video-zoom -0.1 #menu: Pan & Scan > Decrease Size diff --git a/mpv.net/mp.cs b/mpv.net/mp.cs index 878d67b..a13ee14 100644 --- a/mpv.net/mp.cs +++ b/mpv.net/mp.cs @@ -57,6 +57,7 @@ namespace mpvnet public static IntPtr MpvWindowHandle { get; set; } public static Addon Addon { get; set; } public static List>> BoolPropChangeActions { get; set; } = new List>>(); + public static List>> IntPropChangeActions { get; set; } = new List>>(); public static List>> StringPropChangeActions { get; set; } = new List>>(); public static Size VideoSize { get; set; } = new Size(1920, 1080); public static string MpvConfFolderPath { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\mpv\\"; @@ -66,6 +67,7 @@ namespace mpvnet public static List PythonScripts { get; set; } = new List(); public static AutoResetEvent AutoResetEvent { get; set; } = new AutoResetEvent(false); public static List MediaTracks { get; set; } = new List(); + public static List> Chapters { get; set; } = new List>(); static Dictionary _mpvConf; @@ -268,6 +270,11 @@ namespace mpvnet foreach (var i in StringPropChangeActions) if (i.Key == propData.name) i.Value.Invoke(StringFromNativeUtf8(Marshal.PtrToStructure(propData.data))); + + if (propData.format == mpv_format.MPV_FORMAT_INT64) + foreach (var i in IntPropChangeActions) + if (i.Key == propData.name) + i.Value.Invoke(Marshal.PtrToStructure(propData.data)); break; case mpv_event_id.MPV_EVENT_PLAYBACK_RESTART: PlaybackRestart?.Invoke(); @@ -281,7 +288,7 @@ namespace mpvnet Task.Run(new Action(() => { WriteHistory(mp.get_property_string("path")); - SetMediaTracks(); + ReadMetaData(); })); break; case mpv_event_id.MPV_EVENT_CHAPTER_CHANGE: @@ -444,6 +451,16 @@ namespace mpvnet throw new Exception($"{name}: {(mpv_error)err}"); } + public static void observe_property_int(string name, Action action) + { + int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_INT64); + + if (err < 0) + throw new Exception($"{name}: {(mpv_error)err}"); + else + IntPropChangeActions.Add(new KeyValuePair>(name, action)); + } + public static void observe_property_bool(string name, Action action) { int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_FLAG); @@ -454,18 +471,6 @@ namespace mpvnet BoolPropChangeActions.Add(new KeyValuePair>(name, action)); } - public static void unobserve_property_bool(string name, Action action) - { - foreach (var i in BoolPropChangeActions.ToArray()) - if (i.Value == action) - BoolPropChangeActions.Remove(i); - - int err = mpv_unobserve_property(MpvHandle, (ulong)action.GetHashCode()); - - if (err < 0) - throw new Exception($"{name}: {(mpv_error)err}"); - } - public static void observe_property_string(string name, Action action) { int err = mpv_observe_property(MpvHandle, (ulong)action.GetHashCode(), name, mpv_format.MPV_FORMAT_STRING); @@ -476,18 +481,6 @@ namespace mpvnet StringPropChangeActions.Add(new KeyValuePair>(name, action)); } - public static void unobserve_property_string(string name, Action action) - { - foreach (var i in StringPropChangeActions.ToArray()) - if (i.Value == action) - StringPropChangeActions.Remove(i); - - int err = mpv_unobserve_property(MpvHandle, (ulong)action.GetHashCode()); - - if (err < 0) - throw new Exception($"{name}: {(mpv_error)err}"); - } - protected static void ProcessCommandLine() { var args = Environment.GetCommandLineArgs().Skip(1); @@ -629,7 +622,7 @@ namespace mpvnet LastHistoryStartDateTime = DateTime.Now; } - static void SetMediaTracks() + static void ReadMetaData() { lock (MediaTracks) { @@ -693,6 +686,17 @@ namespace mpvnet MediaTracks.Add(track); } + count = get_property_int("edition-list/count"); + + for (int i = 0; i < count; i++) + { + MediaTrack track = new MediaTrack(); + track.Text = "E: " + get_property_string($"edition-list/{i}/title"); + track.Type = "e"; + track.ID = i; + MediaTracks.Add(track); + } + void Add(MediaTrack track, string val) { if (!string.IsNullOrEmpty(val) && !(track.Text != null && track.Text.Contains(val))) @@ -700,6 +704,19 @@ namespace mpvnet } } } + + lock (Chapters) + { + Chapters.Clear(); + int count = get_property_int("chapter-list/count"); + + for (int x = 0; x < count; x++) + { + string text = get_property_string($"chapter-list/{x}/title"); + double time = get_property_number($"chapter-list/{x}/time"); + Chapters.Add(new KeyValuePair(text, time)); + } + } } }