diff --git a/AiQ_GUI.Designer.cs b/AiQ_GUI.Designer.cs index dfaa612..814f3c5 100644 --- a/AiQ_GUI.Designer.cs +++ b/AiQ_GUI.Designer.cs @@ -112,6 +112,7 @@ namespace AiQ_GUI BtnEzOn = new Button(); BtnSetAll211 = new Button(); PnlLbls = new Panel(); + VidView = new LibVLCSharp.WinForms.VideoView(); BtnOpenWebpage = new Button(); LblIRImageF16 = new Label(); ToolTipClipboard = new ToolTip(components); @@ -129,6 +130,12 @@ namespace AiQ_GUI BtnAdminStart = new Button(); BtnFirewall = new Button(); TabImages = new TabPage(); + Video = new TabPage(); + VLCVideo = new Label(); + pictureBox2 = new PictureBox(); + label7 = new Label(); + OVImage = new Label(); + pictureBox1 = new PictureBox(); TabSoak = new TabPage(); BtnFactoryDefault = new Button(); SetGodModeAll = new Button(); @@ -153,6 +160,7 @@ namespace AiQ_GUI PnlQuestion.SuspendLayout(); PnlInputValue.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)RMANumBox).BeginInit(); + ((System.ComponentModel.ISupportInitialize)VidView).BeginInit(); TabImagesandSettings.SuspendLayout(); TabControls.SuspendLayout(); groupBox4.SuspendLayout(); @@ -161,6 +169,9 @@ namespace AiQ_GUI groupBox1.SuspendLayout(); TabSettings.SuspendLayout(); TabImages.SuspendLayout(); + Video.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox2).BeginInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit(); TabSoak.SuspendLayout(); Mobile.SuspendLayout(); SuspendLayout(); @@ -1358,6 +1369,16 @@ namespace AiQ_GUI PnlLbls.Size = new Size(503, 452); PnlLbls.TabIndex = 198; // + // VidView + // + VidView.BackColor = Color.Black; + VidView.Location = new Point(12, 579); + VidView.MediaPlayer = null; + VidView.Name = "VidView"; + VidView.Size = new Size(392, 221); + VidView.TabIndex = 233; + VidView.Text = "VidView"; + // // BtnOpenWebpage // BtnOpenWebpage.BackColor = Color.FromArgb(70, 65, 80); @@ -1401,6 +1422,7 @@ namespace AiQ_GUI TabImagesandSettings.Controls.Add(TabControls); TabImagesandSettings.Controls.Add(TabSettings); TabImagesandSettings.Controls.Add(TabImages); + TabImagesandSettings.Controls.Add(Video); TabImagesandSettings.Controls.Add(TabSoak); TabImagesandSettings.Controls.Add(Mobile); TabImagesandSettings.Font = new Font("Segoe UI Semibold", 9F, FontStyle.Bold); @@ -1637,6 +1659,85 @@ namespace AiQ_GUI TabImages.TabIndex = 0; TabImages.Text = "Images"; // + // Video + // + Video.BackColor = Color.FromArgb(39, 37, 55); + Video.Controls.Add(VidView); + Video.Controls.Add(VLCVideo); + Video.Controls.Add(pictureBox2); + Video.Controls.Add(label7); + Video.Controls.Add(OVImage); + Video.Controls.Add(pictureBox1); + Video.Location = new Point(4, 24); + Video.Name = "Video"; + Video.Padding = new Padding(3); + Video.Size = new Size(411, 806); + Video.TabIndex = 5; + Video.Text = "Video"; + // + // VLCVideo + // + VLCVideo.AutoSize = true; + VLCVideo.BackColor = Color.Transparent; + VLCVideo.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold); + VLCVideo.ForeColor = SystemColors.Control; + VLCVideo.Location = new Point(12, 545); + VLCVideo.Margin = new Padding(4, 0, 4, 0); + VLCVideo.Name = "VLCVideo"; + VLCVideo.Size = new Size(86, 21); + VLCVideo.TabIndex = 238; + VLCVideo.Text = "Live Video"; + // + // pictureBox2 + // + pictureBox2.BackColor = Color.Transparent; + pictureBox2.BorderStyle = BorderStyle.FixedSingle; + pictureBox2.Location = new Point(7, 303); + pictureBox2.Margin = new Padding(4, 3, 4, 3); + pictureBox2.Name = "pictureBox2"; + pictureBox2.Size = new Size(392, 221); + pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage; + pictureBox2.TabIndex = 237; + pictureBox2.TabStop = false; + // + // label7 + // + label7.AutoSize = true; + label7.BackColor = Color.Transparent; + label7.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold); + label7.ForeColor = SystemColors.Control; + label7.Location = new Point(12, 279); + label7.Margin = new Padding(4, 0, 4, 0); + label7.Name = "label7"; + label7.Size = new Size(101, 21); + label7.TabIndex = 236; + label7.Text = "Night Image"; + // + // OVImage + // + OVImage.AutoSize = true; + OVImage.BackColor = Color.Transparent; + OVImage.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold); + OVImage.ForeColor = SystemColors.Control; + OVImage.Location = new Point(12, 14); + OVImage.Margin = new Padding(4, 0, 4, 0); + OVImage.Name = "OVImage"; + OVImage.Size = new Size(87, 21); + OVImage.TabIndex = 235; + OVImage.Text = "Day Image"; + // + // pictureBox1 + // + pictureBox1.BackColor = Color.Transparent; + pictureBox1.BorderStyle = BorderStyle.FixedSingle; + pictureBox1.Location = new Point(7, 46); + pictureBox1.Margin = new Padding(4, 3, 4, 3); + pictureBox1.Name = "pictureBox1"; + pictureBox1.Size = new Size(392, 221); + pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; + pictureBox1.TabIndex = 234; + pictureBox1.TabStop = false; + // // TabSoak // TabSoak.BackColor = Color.FromArgb(39, 37, 55); @@ -1863,6 +1964,7 @@ namespace AiQ_GUI PnlInputValue.ResumeLayout(false); PnlInputValue.PerformLayout(); ((System.ComponentModel.ISupportInitialize)RMANumBox).EndInit(); + ((System.ComponentModel.ISupportInitialize)VidView).EndInit(); TabImagesandSettings.ResumeLayout(false); TabControls.ResumeLayout(false); groupBox4.ResumeLayout(false); @@ -1875,6 +1977,10 @@ namespace AiQ_GUI TabSettings.ResumeLayout(false); TabImages.ResumeLayout(false); TabImages.PerformLayout(); + Video.ResumeLayout(false); + Video.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox2).EndInit(); + ((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit(); TabSoak.ResumeLayout(false); TabSoak.PerformLayout(); Mobile.ResumeLayout(false); @@ -2015,5 +2121,12 @@ namespace AiQ_GUI public ComboBox CbBxCamType; public TabPage Mobile; private Button BtnUpFirm; + private LibVLCSharp.WinForms.VideoView VidView; + private TabPage Video; + public Label label7; + public Label OVImage; + public PictureBox pictureBox1; + public Label VLCVideo; + public PictureBox pictureBox2; } } diff --git a/AiQ_GUI.cs b/AiQ_GUI.cs index 9d11fc5..5d868cc 100644 --- a/AiQ_GUI.cs +++ b/AiQ_GUI.cs @@ -1,4 +1,6 @@ using AiQ_GUI.AiQ_Tests; +using LibVLCSharp.Shared; +using LibVLCSharp.WinForms; using Newtonsoft.Json; using System.ComponentModel; using System.Diagnostics; @@ -38,7 +40,8 @@ namespace AiQ_GUI [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public static MainForm? Instance { get; private set; } - private TabPage CurrentTab; // remember what's currently inserted + private List CurrentTabs; + public MainForm() { @@ -56,6 +59,9 @@ namespace AiQ_GUI Network.Initialize("admin", "admin"); // Initialise HTTP client with basic auth creds. + VidView.MediaPlayer = new MediaPlayer(VLC.libVLC); // Initialize VideoView's MediaPlayer + + if (await Network.PingIP("8.8.8.8")) // Ping to check if we're online { if (!GoogleAPI.Setup()) @@ -70,6 +76,8 @@ namespace AiQ_GUI // Hide on default so will only show based on the camera type selected later TabImagesandSettings.TabPages.Remove(TabSoak); TabImagesandSettings.TabPages.Remove(Mobile); + TabImagesandSettings.TabPages.Remove(Video); + TabImagesandSettings.TabPages.Remove(TabImages); GUIUpdate.GUIVerShort = await guiVerTask; // Guess the GUI version will be first to finish this.Name = "AiQ GUI V" + GUIUpdate.GUIVerShort; @@ -106,28 +114,32 @@ namespace AiQ_GUI private void InsertCamTab(string camType) { - // Remove previously inserted tab if present - if (CurrentTab != null && TabImagesandSettings.TabPages.Contains(CurrentTab)) - TabImagesandSettings.TabPages.Remove(CurrentTab); - - // Choose desired tab - TabPage desired = null; - if (camType == "Mobile") desired = Mobile; - else if (camType == "AiQ") desired = TabSoak; - - // Insert desired tab if any - if (desired != null && !TabImagesandSettings.TabPages.Contains(desired)) + // Remove previous tabs + if (CurrentTabs != null) { - int idx = Math.Min(3, TabImagesandSettings.TabPages.Count); - TabImagesandSettings.TabPages.Insert(idx, desired); - CurrentTab = desired; + foreach (var tab in CurrentTabs) + TabImagesandSettings.TabPages.Remove(tab); } - else + + var tabsToInsert = new List(); + + if (camType == "Mobile") + tabsToInsert.AddRange([Video, Mobile]); + else if (camType == "AiQ") + tabsToInsert.AddRange([TabImages, TabSoak]); + + int idx = Math.Min(3, TabImagesandSettings.TabPages.Count); + + foreach (var tab in tabsToInsert) { - CurrentTab = desired; // may be null + if (!TabImagesandSettings.TabPages.Contains(tab)) + TabImagesandSettings.TabPages.Insert(idx++, tab); } + + CurrentTabs = tabsToInsert; } + private async void CbBxCamType_SelectedIndexChanged(object sender, EventArgs e) { CbBxCameraModel.Items.Clear(); @@ -1437,6 +1449,10 @@ namespace AiQ_GUI //StatsExcel excelExporter = new(); //excelExporter.ExportDatabaseToExcel(); //await MobilePreTest.CheckFirmwareAsync(); + + VLC.Play(VidView); + await Task.Delay(5000); + VLC.TakeSnapshot(VidView); AddToActionsList("RunTime " + stopWatchTest.Elapsed.ToString(@"hh\:mm\:ss\.ff"), Level.LOG); } @@ -1466,3 +1482,4 @@ namespace AiQ_GUI } } + diff --git a/AiQ_GUI_NET_Test.csproj b/AiQ_GUI_NET_Test.csproj index beb9a14..15f968d 100644 --- a/AiQ_GUI_NET_Test.csproj +++ b/AiQ_GUI_NET_Test.csproj @@ -59,6 +59,8 @@ + + @@ -68,6 +70,7 @@ + diff --git a/Mobile Tests/MobileTests.cs b/Mobile Tests/MobileTests.cs index 8ee8c6b..c1cd00c 100644 --- a/Mobile Tests/MobileTests.cs +++ b/Mobile Tests/MobileTests.cs @@ -9,6 +9,7 @@ using System.Text.Json; using System.Threading.Tasks; using System.Windows.Forms; using System.Diagnostics; +using System.Drawing; public static class MobilePreTest { @@ -38,7 +39,7 @@ public static class MobilePreTest JsonElement json = JsonSerializer.Deserialize(body); string version = json.GetProperty("version").GetString()?.Trim(); - + // Compare against expected SRZFirmware from UniversalData if (string.IsNullOrEmpty(UniversalData.SRZFirmware)) { diff --git a/Mobile Tests/VLC.cs b/Mobile Tests/VLC.cs new file mode 100644 index 0000000..7203e68 --- /dev/null +++ b/Mobile Tests/VLC.cs @@ -0,0 +1,48 @@ +using AiQ_GUI; +using LibVLCSharp.Shared; +using LibVLCSharp.WinForms; +using System.IO; + +internal class VLC +{ + public static LibVLC libVLC; + + static VLC() + { + // Ensure LibVLC is initialized before first use + Core.Initialize(); + libVLC = new LibVLC(); + } + + public static string RtspUrl = $"rtsp://ADMIN:1234@192.168.0.85:554/live/main"; + public static string SnapshotPath = Path.Combine(LDS.MAVPath, "Mobile_ov_snapshot.png"); + + public static void Play(VideoView VLCVV) + { + var media = new Media(libVLC, RtspUrl, FromType.FromLocation); + VLCVV.MediaPlayer.Play(media); + } + + public static bool IsPLaying(VideoView VLCVV) + { + return VLCVV.MediaPlayer.IsPlaying; + } + + public static void TakeSnapshot(VideoView VLCVV) + { + VLCVV.MediaPlayer.TakeSnapshot(0, SnapshotPath, 1280, 720); + + } + + public static void Stop(VideoView VLCVV) + { + VLCVV.MediaPlayer.Stop(); + } + + public static void Capture(VideoView VLCVV) + { + var media = new Media(libVLC, RtspUrl, FromType.FromLocation); + media.AddOption(":rtsp-tcp"); + VLCVV.MediaPlayer.Play(media); + } +}