/// <summary> /// Configure the VLC Control(s) and overlay(s) that handle mouse events /// </summary> private void SetupVlc() { NumberOfViews = GetNumberOfViews(); myVlcControl = new VlcControl[NumberOfViews]; vlcOverlay = new VlcOverlay[NumberOfViews]; string[] vlcMediaOptions = Regex.Split(getIniValue("VlcOptions"), "\\s*,\\s*"); // Split by comma and trim whitespace BgPtzWorker = new BackgroundWorker[NumberOfViews]; for (int i = 0; i < NumberOfViews; i++) { BgPtzWorker[i] = new BackgroundWorker(); BgPtzWorker[i].WorkerReportsProgress = true; BgPtzWorker[i].WorkerSupportsCancellation = true; BgPtzWorker[i].DoWork += BgPtzWorker_DoWork; myVlcControl[i] = new VlcControl(); vlcOverlay[i] = new VlcOverlay() { Name = "VLC Overlay " + i, BackColor = Color.Transparent, TabIndex = i }; //, Parent = myVlcControl[i], Dock = DockStyle.Fill, TabIndex = i }; vlcOverlay[i].GotoPtzPreset += Viewer_GotoPtzPreset; vlcOverlay[i].ToggleMute += Viewer_ToggleMute; // Add panel to VlcControl container to capture mouse events Panel MouseEventPanel = new Panel() { Parent = myVlcControl[i], BackColor = Color.Transparent, Dock = DockStyle.Fill, TabIndex = i, }; MouseEventPanel.MouseEnter += VlcOverlay_MouseEnter; MouseEventPanel.MouseLeave += VlcOverlay_MouseLeave; MouseEventPanel.MouseDoubleClick += VlcOverlay_MouseDoubleClick; MouseEventPanel.MouseMove += VlcOverlay_MouseMove; MouseEventPanel.MouseDown += VlcOverlay_MouseDown; MouseEventPanel.MouseUp += VlcOverlay_MouseUp; MouseEventPanel.MouseWheel += VlcOverlay_MouseWheel; ((System.ComponentModel.ISupportInitialize)(myVlcControl[i])).BeginInit(); myVlcControl[i].VlcLibDirectory = VlcViewer.GetVlcLibLocation(); // Tried to call once outside loop, but it causes in exception on program close myVlcControl[i].VlcMediaplayerOptions = vlcMediaOptions; // new string[] { "--network-caching=150", "--video-filter=deinterlace" }; myVlcControl[i].Location = new Point(0, 0); myVlcControl[i].Name = string.Format("VLC Viewer {0}", i); myVlcControl[i].Rate = (float)0.0; myVlcControl[i].BackColor = Color.Gray; myVlcControl[i].TabIndex = i; //myVlcControl[i].MouseDoubleClick += VlcOverlay_MouseDoubleClick; // Events myVlcControl[i].Playing += OnVlcPlaying; myVlcControl[i].EncounteredError += MyVlcControl_EncounteredError; myVlcControl[i].Buffering += Form1_Buffering; //myVlcControl[i].Controls.Add(vlcOverlay[i]); // Had to add this line to make work ((System.ComponentModel.ISupportInitialize)(myVlcControl[i])).EndInit(); } setSizes(); }
private void VlcOverlay_MouseLeave(object sender, EventArgs e) { // This is a terrible way to make sure the PTZ stops - replace with better solution Panel p = (Panel)sender; VlcOverlay overlay = vlcOverlay[p.TabIndex]; // (VlcOverlay)sender; log.Info(string.Format("Mouse exited view {0} [NOTE: REPLACE PTZ STOP ON EXIT WITH BETTER SOLUTION]", overlay.Name)); PtzStop(overlay); }
private void Viewer_ToggleMute(object sender, EventArgs e) { VlcOverlay overlay = (VlcOverlay)sender; VlcControl vlc = myVlcControl[overlay.TabIndex]; if (vlc?.Audio != null) { vlc.Audio.ToggleMute(); } overlay.SetMuteState(vlc.Audio.IsMute); }
private void PtzStop(VlcOverlay overlay) { // Stop PTZ if moving Debug.Print(string.Format("{0} Stop PTZ if necessary ({1})", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), overlay.Name)); // Check if PTZ and enable PTZ controls if necessary if (overlay.PtzEnabled && overlay.PtzController != null && overlay.PtzController.PtzMoving) { log.Debug(string.Format("Camera stopping on view {0} [{1}]", overlay.Name, overlay.LastCamUri)); Debug.Print(string.Format("Camera stopping on view {0} [{1}]", overlay.Name, overlay.LastCamUri)); overlay.PtzController.Stop(); } }
private void SetVlcFullView(int viewerIndex) { log.Info(string.Format("Display full screen layout (View #{0})", viewerIndex)); foreach (VlcOverlay vlc in vlcOverlay) { if (vlc.TabIndex == viewerIndex) { VlcOverlay.SetFullView(this, vlc); statusBg.Visible = true; statusBg.BringToFront(); SetViewerStatus(viewerIndex); break; } } }
/// <summary> /// Sends PTZ commands to the relevant camera /// </summary> /// <param name="sender"></param> /// <param name="e">Object containing the relevant Vlc View overlay and the mouse event args</param> private void BgPtzWorker_DoWork(object sender, DoWorkEventArgs e) { object[] args = e.Argument as object[]; VlcOverlay overlay = (VlcOverlay)args[0]; MouseEventArgs mouseArgs = (MouseEventArgs)args[1]; if (!myVlcControl[overlay.TabIndex].IsPlaying) { Debug.Print(string.Format("{0} VLC not playing. No PTZ command sent.", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"))); //log.Debug(string.Format("VLC not playing. No PTZ command sent to view {0}", overlay.Name)); return; } // Check if PTZ and enable PTZ controls if necessary if (overlay.PtzEnabled) { if (overlay.PtzController == null) { log.Warn(string.Format("No PtzController configured for camera stream [{0}]", overlay.LastCamUri)); throw new Exception(string.Format("No PtzController configured for camera stream [{0}]", overlay.LastCamUri)); } if (mouseArgs.Delta != 0) { // Initiate continuous move zoom. Stopped by ScrollTimer Elapsed event overlay.PtzController.Zoom(overlay.ScrollSpeed); } else { // Calculate the speed Pan and Tilt using the mouse location // Uses the center of the control as point 0, 0 (i.e the center) // A negative pan speed moves the camera to the left, positive to the right // A negative tilt speed moves the camera down, positive moves it up // The speed is a value between 0 and 1 (represents a percent of max speed) float panSpeed = (float)(mouseArgs.X - (overlay.Width / 2)) / (float)(overlay.Width / 2); float tiltSpeed = (float)((overlay.Height / 2) - mouseArgs.Y) / (float)(overlay.Height / 2); log.Debug(string.Format("Sending PTZ Command to move [Pan Speed: {0}, Tilt Speed: {1}] on view {2} [{3}]", panSpeed, tiltSpeed, overlay.Name, overlay.LastCamUri)); overlay.PtzController.PanTilt(panSpeed, tiltSpeed); } } }
private void VlcOverlay_MouseDown(object sender, MouseEventArgs e) { Panel p = (Panel)sender; VlcOverlay overlay = vlcOverlay[p.TabIndex]; // (VlcOverlay)sender; Debug.Print(string.Format("{0} Mouse down ({1})", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), overlay.Name)); log.Debug(string.Format("Mouse down on view {0}", overlay.Name)); // Use BackgroundWorker to send command to prevent UI lockup if (!BgPtzWorker[overlay.TabIndex].IsBusy) { object[] args = new object[] { overlay, e }; BgPtzWorker[overlay.TabIndex].RunWorkerAsync(args); } else { log.Debug(string.Format("Background worker busy. Ignoring mouse down for view {0} [{1}]", overlay.Name, overlay.LastCamUri)); } }
private void VlcOverlay_MouseWheel(object sender, MouseEventArgs e) { Panel p = (Panel)sender; VlcOverlay overlay = vlcOverlay[p.TabIndex]; // Have overlay process mouse change overlay.SetZoomSpeed(e); // Use BackgroundWorker to send command to prevent UI lockup if (!BgPtzWorker[overlay.TabIndex].IsBusy) { object[] args = new object[] { overlay, e }; BgPtzWorker[overlay.TabIndex].RunWorkerAsync(args); } else { //log.Debug(string.Format("Background worker busy. Ignoring mouse wheel for view {0} [{1}]", overlay.Name, overlay.LastCamUri)); } }
private void VlcOverlay_MouseEnter(object sender, EventArgs e) { // Select control so the mouse wheel event will go to the proper control Panel p = (Panel)sender; VlcOverlay overlay = vlcOverlay[p.TabIndex]; // (VlcOverlay)sender; p.Select(); log.Debug(string.Format("Mouse entered view {0}", overlay.Name)); if (!overlay.PtzEnabled | !myVlcControl[overlay.TabIndex].IsPlaying) { // Disable PTZ actions if not playing overlay.PtzEnabled = false; this.Cursor = Cursors.Default; } ActiveViewer = overlay.TabIndex; }
private void VlcOverlay_MouseDoubleClick(object sender, EventArgs e) { Panel overlay = (Panel)sender; VlcControl vlc = myVlcControl[overlay.TabIndex]; // (VlcControl)overlay.Parent; this.SuspendLayout(); if (vlc.Width >= this.ClientSize.Width) { setSizes(); vlc.SendToBack(); } else { VlcOverlay.SetFullView(this, vlcOverlay[vlc.TabIndex]); statusBg.Visible = true; statusBg.BringToFront(); } this.ResumeLayout(); }
private void VlcOverlay_MouseUp(object sender, MouseEventArgs e) { Panel p = (Panel)sender; VlcOverlay overlay = vlcOverlay[p.TabIndex]; // (VlcOverlay)sender; log.Debug(string.Format("Mouse up on view {0}", overlay.Name)); // Set the viewer status cbxViewSelect.SelectedIndex = p.TabIndex; SetViewerStatus(p.TabIndex); txtUri.Text = MyIni.Read("lastURI", "Viewer_" + p.TabIndex); if (e.Button == MouseButtons.Right) { VlcViewer.TogglePause(myVlcControl[p.TabIndex]); } // Attempt to prevent unstopping PTZ (stop sent before PTZ?) BgPtzWorker[overlay.TabIndex].CancelAsync(); PtzStop(overlay); }
private void Viewer_GotoPtzPreset(object sender, PresetEventArgs e) { Panel pan = (Panel)sender; VlcOverlay overlay = vlcOverlay[pan.TabIndex]; // Check if PTZ and enable PTZ controls if necessary if (overlay.PtzEnabled) { if (overlay.PtzController == null) { log.Warn(string.Format("No PtzController configured for camera stream [{0}]", overlay.LastCamUri)); throw new Exception(string.Format("No PtzController configured for camera stream [{0}]", overlay.LastCamUri)); } try { overlay.PtzController.ShowPreset(e.Preset); } catch (IndexOutOfRangeException) { overlay.ShowNotification(string.Format("Preset #{0} undefined", e.Preset), 3000); } } }
private void VlcOverlay_MouseMove(object sender, MouseEventArgs e) { Panel p = (Panel)sender; VlcOverlay overlay = vlcOverlay[p.TabIndex]; // (VlcOverlay)sender; int minMovePercent = 3; if (overlay.LastMouseArgs == null) { overlay.LastMouseArgs = e; } int x = overlay.Size.Width / 2; int y = overlay.Size.Height / 2; //string quadrant = ""; int deltaX = e.X - x; int deltaY = y - e.Y; //float radius = (float)Math.Sqrt((deltaX * deltaX) + (deltaY * deltaY)); double angle = Math.Atan2(deltaY, deltaX) * (180 / Math.PI); //if (deltaY >= 0) // quadrant = "Top"; //else // quadrant = "Bottom"; //if (deltaX >= 0) // quadrant += " Right"; //else // quadrant += " Left"; if (overlay.PtzEnabled) { this.Cursor = Utilities.GetPtzCursor(angle); } //Invoke((Action)(() => { overlay.Controls["Status"].Text = string.Format("{0}\nMouse @ ({1}, {2})\nPolar: {3:0.#}@{4:0.##}\nCart.: {5},{6}", quadrant, e.Location.X, e.Location.Y, radius, angle, deltaX, deltaY); overlay.Controls["Status"].Visible = true; })); // Change PTZ command based on mouse position (only if left button down) if (e.Button == MouseButtons.Left) { //Debug.Print(string.Format("Mouse Move with button {0} pressed @ {1}, {2}", e.Button, e.X, e.Y)); if (Math.Abs((overlay.LastMouseArgs.X - e.X)) > (overlay.Width * ((float)minMovePercent / 100))) { Debug.Print(string.Format("{0} {1}", Math.Abs((overlay.LastMouseArgs.X - e.X)), (overlay.Width * ((float)minMovePercent / 100)))); Debug.Print(string.Format("Mouse moved horizontally by more than the minimum percentage [{0}] to [{1}, {2}]", minMovePercent, e.X, e.Y)); } else if (Math.Abs((overlay.LastMouseArgs.Y - e.Y)) > (overlay.Height * ((float)minMovePercent / 100))) { Debug.Print(string.Format("{0} {1}", Math.Abs((overlay.LastMouseArgs.Y - e.Y)), (overlay.Height * ((float)minMovePercent / 100)))); Debug.Print(string.Format("Mouse moved vertically by more than the minimum percentage [{0}] to [{1}, {2}]", minMovePercent, e.X, e.Y)); } else { return; } // Use BackgroundWorker to send command to prevent UI lockup if (!BgPtzWorker[overlay.TabIndex].IsBusy) { // Only store new mouse position if a command is successfully sent // Otherwise an attempt to send the command should be made the next time the mouse moves overlay.LastMouseArgs = e; object[] args = new object[] { overlay, e }; BgPtzWorker[overlay.TabIndex].RunWorkerAsync(args); } else { //log.Debug(string.Format("Background worker busy. Ignoring mouse down for view {0} [{1}]", overlay.Name, overlay.LastCamUri)); } } else if (e.Button == MouseButtons.None) { // Allow some mouse movement (hard to use scroll wheel with no change in mouse position) if (Math.Abs((overlay.LastMouseArgs.X - e.X)) > (overlay.Width * ((float)minMovePercent / 100)) | (Math.Abs((overlay.LastMouseArgs.Y - e.Y)) > (overlay.Height * ((float)minMovePercent / 100)))) { // PtzMoving should be false if no buttons are pressed. // This is to help prevent the Ptz from moving continuously as // it does sometime if the mouse up is not detected or the stop is sent before the PTZ command // Should become unecessary when a real fix for those issues is implemented if (overlay.PtzEnabled && overlay.PtzController != null && overlay.PtzController.PtzMoving) { PtzStop(overlay); } } } }