STANAG 4609 Player .NET SDK  Version 4.0.0
Program.cs
using Colorful;
using Fclp;
using KlvPlayer;
using KlvPlayerTestApp.Properties;
using Newtonsoft.Json.Linq;
using StCoreWr;
using StMonitorAgent;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Console = Colorful.Console;
namespace KlvPlayerTestApp
{
[Flags]
public enum FrameCaptureFormat
{
none = 0,
jpeg = 1,
bmp = 2,
};
public enum SessionType
{
file,
stream,
}
class Program
{
static object ConsoleLock = new object();
static int m_VideoPid = -1;
static int m_KlvPid = -1;
static int m_PrivateDataPid = -1;
static string m_Url = @"udp://227.1.1.1:30120";
static string m_urlDvrRecording = string.Empty;
static CKlvPlayer m_KlvPlayer = null;
static string m_targetDir = String.Empty;
static FrameCaptureFormat m_frameCaptureFormat = FrameCaptureFormat.none;
static bool m_fVideoPlayback = true;
static int imageFileIndex = 0;
static int m_MaxDelay = Settings.Default.MaxDelay;
static int m_Caching = Settings.Default.Caching;
static int m_MinKlvPacketCount;
delegate void SaveFrameDlg(Bitmap bmp, string path);
static SaveFrameDlg SaveFrame;
static FluentCommandLineParser parser = new FluentCommandLineParser();
static CStMonitorAgent m_MonitorAgent = null;
static DateTime m_LastMonitorKlvUpdate = DateTime.Now;
static int MaxMonitorKlvUpdateRate = 200;
static int counter = 0;
static SessionType m_SessionType;
static bool m_fFullScreen = false;
static bool m_fDvr = false;
static bool m_fRtspSourceDefaultInterleaved;
static string m_licenseFilePath = string.Empty;
static string m_licenseKey = string.Empty;
static void Main(string[] args)
{
Console.WriteAscii("Klv Player", Color.Aqua);
ParseInputArgs(args);
if (args.Count() < 1)
{
PrintManual();
PrintNodeInfo();
Console.ReadLine();
return;
}
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
if (string.IsNullOrEmpty(m_targetDir))
m_targetDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
SetCaptureMode();
ConsoleKeyInfo cki = new ConsoleKeyInfo();
// Print manual
PrintCommands();
PrintNodeInfo();
PrintArguments();
StyleSheet styleSheet = new StyleSheet(Color.Gray);
styleSheet.AddStyle("[0-9]*", Color.GreenYellow);
DateTime lastPresentation = DateTime.Now;
// Get user input
do
{
#region MyRegion
while (Console.KeyAvailable == false) // Loop until input is entered. Show statistics.
{
if (m_KlvPlayer != null && DateTime.Now.Subtract(lastPresentation).TotalMilliseconds > 200)
{
if (m_KlvPlayer.PlayerState == Player_State.Running)
{
try
{
lock (ConsoleLock)
{
int left = Console.CursorLeft;
int top = Console.CursorTop;
var infoVideo = m_KlvPlayer.GetReceivedStatisticPcktInfo(m_VideoPid);
var infoKlv = m_KlvPlayer.GetReceivedStatisticPcktInfo(m_KlvPid);
var infoData = m_KlvPlayer.GetReceivedStatisticPcktInfo(m_PrivateDataPid);
string status = String.Format("Pos {0} Frames {1} ({2} fps) Klvs {3} ({4} p/s) Data {5} ({6} p/s) ",
m_KlvPlayer.GetCurrentPosition().ToString("0.00"),
infoVideo.TotalPackets, infoVideo.GetRate().ToString("0.0"),
infoKlv.TotalPackets, infoKlv.GetRate().ToString("0.0"),
infoData.TotalPackets, infoData.GetRate().ToString("0.0"));
Console.WriteStyled(status, styleSheet);
Spinner.Instance.Update();
Console.CursorLeft = left;
Console.CursorTop = top;
}
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
}
lastPresentation = DateTime.Now;
}
Thread.Sleep(100);
Application.DoEvents(); // This is extreamly important !!! For console and similar application you must dispatch messages. This is one of the (easiest) methods to do so.
}
#endregion
cki = Console.ReadKey(true);
switch (cki.Key)
{
case ConsoleKey.S:
Console.WriteLine("\nStart Processing.", Color.LightGreen);
if (m_KlvPlayer != null)
{
if (m_KlvPlayer.PlayerState != Player_State.Paused)
m_KlvPlayer.Stop();
else
{
// In pause state. Resume playback
if (!m_KlvPlayer.Start())
ReportError("\nError resuming playback.");
break;
}
}
if (InitPlayer())
{
// Start Processing
if (m_KlvPlayer.Start() == false)
ReportError("\nError starting Processing.");
else
{
if (m_fDvr)
m_KlvPlayer.AddRecordedUrl(m_urlDvrRecording);
Console.CursorVisible = false;
}
}
break;
case ConsoleKey.P:
if (m_KlvPlayer.PlayerState == Player_State.Paused)
break;
Console.WriteLine("\nPause Processing.", Color.LightGreen);
// Pause processing
if (m_KlvPlayer.Pause() == false)
ReportError("\nError pausing Processing.");
break;
case ConsoleKey.L:
Console.WriteLine("\nBack to live.", Color.LightGreen);
// Go back to live stream
if (m_KlvPlayer.GoToLive() == false)
ReportError("\nError resuming live playback.");
break;
case ConsoleKey.E:
Console.WriteLine("\nStop Processing", Color.LightGreen);
// Stop Processing
if (m_KlvPlayer != null)
{
m_KlvPlayer.Close();
m_KlvPlayer.Dispose();
m_KlvPlayer = null;
}
Console.CursorVisible = true;
break;
case ConsoleKey.G:
Console.WriteLine("\nGo to (Seek)", Color.RoyalBlue);
Console.WriteLine("\nSegment durtion {0}. Seek to 20.0 sec", m_KlvPlayer.GetDuration());
// Seek
if (m_KlvPlayer.SetPosition(20.0) == false)
ReportError("\nError seeking.");
break;
case ConsoleKey.RightArrow:
{
if (m_KlvPlayer.PlayerState != Player_State.Paused)
break;
Console.WriteLine("\nStepForward", Color.RoyalBlue);
if (m_KlvPlayer.StepForward())
{
TimeSpan t = TimeSpan.FromSeconds(m_KlvPlayer.GetCurrentPosition());
Console.WriteLine(String.Format("\nPos: {0}", t.ToString(@"hh\:mm\:ss\:fff")), Color.Green);
}
else
{
ReportError("Not supported in this mode.\n");
}
}
break;
case ConsoleKey.LeftArrow:
{
if (m_KlvPlayer.PlayerState != Player_State.Paused)
break;
Console.WriteLine("\nStepBackward", Color.RoyalBlue);
if (m_KlvPlayer.StepBackward())
{
TimeSpan t = TimeSpan.FromSeconds(m_KlvPlayer.GetCurrentPosition());
Console.WriteLine(String.Format("\nPos: {0}", t.ToString(@"hh\:mm\:ss\:fff")), Color.Green);
}
else
{
ReportError("Not supported in this mode.\n");
}
}
break;
case ConsoleKey.V:
Console.WriteLine("\nShow video resolution.", Color.Pink);
int Height = 0, Width = 0;
m_KlvPlayer.GetVideoResolution(out Height, out Width);
Console.WriteLineFormatted(@"Height {0} Width {1}", Color.White, Color.Aqua, new string[] { Height.ToString(), Width.ToString() });
break;
case ConsoleKey.F:
Console.WriteLine("\nFull Screen", Color.Pink);
m_fFullScreen = !m_fFullScreen;
m_KlvPlayer.SetFullScreen(m_fFullScreen);
break;
case ConsoleKey.K:
if (m_MonitorAgent == null)
{
Console.WriteLine("\nMonitor Klv on", Color.Pink);
// Open / Close Klv Monitor
Task.Factory.StartNew(() =>
{
m_MonitorAgent = new CStMonitorAgent();
if (!m_MonitorAgent.OpenMonitorWindow())
{
ReportError("Cannot open StMonitor\n");
m_MonitorAgent = null;
}
});
}
else
{
Console.WriteLine("\nMonitor Klv off", Color.Pink);
m_MonitorAgent.CloseAllSubscribers();
m_MonitorAgent = null;
}
break;
case ConsoleKey.N:
if (m_KlvPlayer == null)
InitPlayer();
// Get Node Info for license generation
Console.WriteLine("Node Info : " + m_KlvPlayer.GetNodeInfo(), Color.Wheat);
break;
case ConsoleKey.H:
// Show help
Console.ForegroundColor = Color.LightGray;
parser.HelpOption.ShowHelp(parser.Options);
Console.ForegroundColor = Color.White;
break;
}
} while (cki.Key != ConsoleKey.Q && cki.Key != ConsoleKey.Escape);
// Close the player
Close();
}
private static bool ParseInputArgs(string[] args)
{
try
{
parser.Setup<string>('i', "input").Callback(urlSource => m_Url = urlSource).SetDefault(@"udp://227.1.1.1:30120").WithDescription("Input url");
parser.Setup<string>('o', "output").Callback(urlTarget => m_targetDir = urlTarget).WithDescription("Target directory for frame capture");
parser.Setup<string>('r', "recording").Callback(urlRecording => m_urlDvrRecording = urlRecording).WithDescription("DVR recorded url");
parser.Setup<bool>('v', "video").Callback(showVideo => m_fVideoPlayback = showVideo).SetDefault(true).WithDescription("Show video during processing");
parser.Setup<FrameCaptureFormat>("frameCaptureFormat").Callback(frCaptureFormat => m_frameCaptureFormat = frCaptureFormat).WithDescription("Frame capture format: 0-none, 1-jpeg, 2-bmp");
parser.Setup<int>('d', "maxDelay").Callback(delay => m_MaxDelay = delay).WithDescription("Max sync delay");
parser.Setup<int>('c', "caching").Callback(caching => m_Caching = caching).WithDescription("Network caching");
parser.Setup<int>("minKlvPacketCount").Callback(minKlvPacketCount => m_MinKlvPacketCount = minKlvPacketCount).SetDefault(3).WithDescription("Minimal number of tags to be present in Klv packet");
parser.Setup<int>("klvPid").Callback(klvPid => m_KlvPid = klvPid).WithDescription("Select Klv Pid");
parser.Setup<bool>("rtspSourceInterleaved").Callback(rtspSourceInterleaved => m_fRtspSourceDefaultInterleaved = rtspSourceInterleaved).SetDefault(false).WithDescription("Use TCP for RTSP. Default - false");
parser.Setup<string>("licenseFile").Callback(file => m_licenseFilePath = file).WithDescription("License File path");
parser.Setup<string>("licenseKey").Callback(key => m_licenseKey = key).WithDescription("License key");
parser.SetupHelp("?", "help").Callback(text => Console.WriteLine(text));
parser.Parse(args);
}
catch (Exception er)
{
ReportError(er.Message);
return false;
}
return true;
}
private static void Close()
{
if (m_MonitorAgent != null)
m_MonitorAgent.CloseAllSubscribers();
if (m_KlvPlayer != null)
m_KlvPlayer.Close();
Console.ReplaceAllColorsWithDefaults();
Console.WriteLine("\nExiting...");
Console.CursorVisible = true;
Console.ResetColor();
Environment.Exit(0);
}
static bool InitPlayer()
{
try
{
// Create Player instance
m_fDvr = (m_Url.StartsWith("udp://") || m_Url.StartsWith("rtp://")) && !String.IsNullOrEmpty(m_urlDvrRecording); // Determie, do we need DVR mode or not
m_KlvPlayer = new CKlvPlayer(m_fDvr, null); // Create Player instance. If DVR mode (Shifted TV) is not needed, pass false to save the overhead related to DVR mode.
string licPath = string.IsNullOrEmpty(m_licenseFilePath) ? Application.StartupPath + @"\" + @"KlvPlayer.lic" : m_licenseFilePath;
string licKey = string.IsNullOrEmpty(m_licenseKey) ? Settings.Default.LicenseKey : m_licenseKey;
bool fLicExists = !string.IsNullOrEmpty(licPath) && File.Exists(licPath);
if (fLicExists && string.IsNullOrEmpty(licKey))
{
string license;
string licenseError;
// Activate the KLV player. Please contact ImpleoTV to get your license
if (m_KlvPlayer.Activate(licPath, out license, out licenseError))
{
JObject lic = JObject.Parse(license);
Console.WriteLine($"License is valid. {(string)lic["product"]["name"]} licensed to {(string)lic["user"]["name"]}");
}
else
ReportError($"License not valid. {licenseError}. Demo mode.");
}
else
if (fLicExists && !string.IsNullOrEmpty(licKey))
{
// For older versions, license file + key
if (!m_KlvPlayer.Activate("KlvPlayer", licPath, licKey)) // Activate the KLV player. Please contact ImpleoTV to get your license and a key
ReportError("License not valid. Demo mode");
}
// Setup events
m_KlvPlayer.PlayerEvent += new NotifyPlayerEvent(OnPlayerEvent); // Player general events notification
m_KlvPlayer.ErrorEvent += new NotifyError(OnErrorEvent); // Player error events
m_KlvPlayer.PidDetectionEvent += new NotifyPidDetection(OnPidDetectionEvent); // PID detection events (video / KLV / audio / data)
m_KlvPlayer.SyncFrameEvent += new NotifySyncFrame(OnSyncFrameEvent); // Synchronized Video frames / Klv / Private data
// Setup video / audio rendering
m_KlvPlayer.RenderVideo = m_fVideoPlayback; // Set to true if you want to decode and show the video
m_KlvPlayer.RenderAudio = Settings.Default.RenderAudio; // Set to true if you need audio processing.
m_KlvPlayer.VideoCaptureMode.uncompressedVideo = m_frameCaptureFormat != FrameCaptureFormat.none ? UncompressedVideoModeWr.UncompressedVideoMode_Rgb : UncompressedVideoModeWr.UncompressedVideoMode_None;
m_KlvPlayer.VideoCaptureMode.fCompressedVideo = m_frameCaptureFormat == FrameCaptureFormat.none; // set to true if you don't need an uncompressed frame, but still want to get video timing info.
m_KlvPlayer.Hwnd = 0; // Window handle to render video to. If set to 0, the window will be created internally.
m_KlvPlayer.FrameAccuracyMode = Settings.Default.FrameAccuracyMode; // Set this to true if you want to achieve an accurate StepForward / StepBackward functionality. Note, TimeToRender will be always zero (sync will be done internally).
m_KlvPlayer.FrameAccuracyRequiresSequenceHeaders = Settings.Default.FrameAccuracyRequiresSequenceHeaders;
m_KlvPlayer.AudioMayBeMissing = true;
// m_KlvPlayer.VideoPresenter().UseDirectX = true; // Set to true if you want to use Direct3D renderer (make sure you have the prerequisites installed)
m_KlvPlayer.Caching = m_Caching; // Caching for dejitter buffer. Set to minimal possible value to get a low latency stream playback,
m_KlvPlayer.MaxSyncDelay = m_MaxDelay; // Allowed Sync time for video / data synchronization
m_KlvPlayer.MinKlvPacketCount = m_MinKlvPacketCount; // Minimal number of tags to be present in Klv packet in order to be forwarded with the event.
m_KlvPlayer.DvrRefTimeMatchMode = (DVR_RefTimeMatchMode)Settings.Default.DvrTimeMatchMode; // Set DVR time matching mode
m_KlvPlayer.DvrLocalBufferSize = (uint)Settings.Default.DvrLocalBufferSize; // Set DVR local recording buffer size
//m_KlvPlayer.KlvProcessingMode = KLV_PROCESSING_MODE.KLV_TRANSCODE_104_TO_601; // Optional metadata transcoding for legacy stream
m_KlvPlayer.CalculatePacketRate = true; // Calculate average rate for received packets
if (!String.IsNullOrEmpty(m_Url) && m_Url.ToLower().StartsWith("rtsp://")) // For RTSP playback only
m_KlvPlayer.RtspSourceDefaultInterleaved = m_fRtspSourceDefaultInterleaved;
// Initialize player
if (!m_KlvPlayer.Init(m_Url))
{
ReportError("Error initializing url {0}", m_Url);
return false;
}
m_SessionType = (m_Url.ToLower().StartsWith("udp://") || m_Url.ToLower().StartsWith("rtp://")) ? SessionType.stream : SessionType.file;
}
catch (Exception ex)
{
Console.WriteLine($"{ex.Message}. {ex.InnerException.Message}");
throw;
}
return true;
}
static void OnPidDetectionEvent(List<PidInfoWr> pidList)
{
pidList.ForEach(pid =>
{
Console.WriteLine("Pid 0X{0} type {1}", pid.streamId.ToString("X"), pid.streamType, Color.LightGray);
if (pid.streamType == StreamType.VIDEO)
m_VideoPid = pid.streamId;
if (pid.streamType == StreamType.KLV && m_KlvPid == -1)
m_KlvPid = pid.streamId;
if (pid.streamType == StreamType.PRIVATE_DATA && m_PrivateDataPid == -1)
m_PrivateDataPid = pid.streamId;
});
}
static void OnPlayerEvent(Player_State ev, string info, long param)
{
lock (ConsoleLock)
{
StyleSheet styleSheet = new StyleSheet(Color.LawnGreen);
string message = String.Empty;
switch (ev)
{
case Player_State.Starting: //Starting graph is being built
message = String.Format("Playback of {0} is starting...", m_Url);
break;
case Player_State.WaitingFordata: //playback is started, but data source is timed out
message = String.Format("Playback of {0} is waiting for data", m_Url);
break;
case Player_State.Running: //Session is running
message = String.Format("Playback of {0} is running", m_Url);
break;
case Player_State.Paused: //Session is paused
message = String.Format("Playback of {0} is paused", m_Url);
break;
case Player_State.Stopped: //Session is stopped
message = String.Format("Playback of {0} is stopped", m_Url);
break;
case Player_State.Completed: //Session is complete
message = String.Format("Playback of {0} is completed. {1} klv packets procesed. {2} private data packets processed", m_Url, m_KlvPlayer.GetReceivedStatisticPcktInfo(m_KlvPid).TotalPackets, m_KlvPlayer.GetReceivedStatisticPcktInfo(m_PrivateDataPid).TotalPackets);
break;
case Player_State.Error: //Error
message = String.Format("Error in playback of {0}", m_Url);
break;
case Player_State.Demo_Expired: //Demo Expired
message = "\nPLAYER_EVENT.DEMO_EXPIRED";
break;
case Player_State.DurationChanged: // Total duration has changed
message = "\nDuration changed";
break;
case Player_State.SegmentChanged: // Current segment changed
message = "\nCurrent segment changed";
break;
case Player_State.SegmentListChanged: // Segment list has changed
message = "\nSegment list changed";
break;
case Player_State.SegmentStarted: // Segment start
message = String.Format("Playback of {0} segment is stated", info);
break;
case Player_State.SegmentCompleted: // Segment complete
message = String.Format("Playback of {0} segment is complete", info);
break;
case Player_State.PlayerChanged: // Segment complete
message = String.Format("Player changed to {0}", info);
break;
case Player_State.VideoDeleted: // Current local DVR video expired
message = String.Format("Locally recorded video segment is expired and does not contain the currently displayed video anymore", info);
break;
default:
message = String.Format("Unknown event {0}", ev);
break;
}
Console.WriteLineStyled(message, styleSheet);
Console.ForegroundColor = Color.White;
}
}
static void OnErrorEvent(Error_Type e, string err)
{
ReportError("Error {0} - {1}", e, err);
}
static void OnSyncFrameEvent(List<StreamFrameInfoWr> streamList)
{
streamList.ForEach(delegate (StreamFrameInfoWr streamFrame)
{
switch (streamFrame.streamType)
{
case StreamType.VIDEO:
{
// Here we got an uncompressed frame
VideoFrameInfoWr vf = streamFrame as VideoFrameInfoWr;
if (m_frameCaptureFormat != FrameCaptureFormat.none && !String.IsNullOrEmpty(m_targetDir))
CopyDataToBitmap(vf.Width, vf.Height, vf.pixelFormat, vf.data);
counter++;
}
break;
case StreamType.KLV:
{
// Here we got a klv packet
KlvFrameInfoWr kf = streamFrame as KlvFrameInfoWr;
if (kf.duplicateCounter == 0 && kf.decodedData != null)
{
if (m_MonitorAgent != null && DateTime.Now.Subtract(m_LastMonitorKlvUpdate).TotalMilliseconds > MaxMonitorKlvUpdateRate)
{
PubToMonitor(kf);
m_LastMonitorKlvUpdate = DateTime.Now;
}
}
}
break;
case StreamType.PRIVATE_DATA:
{
// Here we got a private data packet
DataFrameInfoWr df = streamFrame as DataFrameInfoWr;
if (df.duplicateCounter == 0)
{
}
}
break;
}
});
}
private static void SetCaptureMode()
{
switch (m_frameCaptureFormat)
{
case FrameCaptureFormat.jpeg:
SaveFrame = SaveFrameAsJpeg;
break;
case FrameCaptureFormat.bmp:
SaveFrame = SaveFrameAsBitmap;
break;
}
}
private static void PubToMonitor(KlvFrameInfoWr kf)
{
var jsonPckt = new JObject();
jsonPckt.Add("pcktNumber", m_KlvPlayer.GetReceivedStatisticPcktInfo(m_KlvPid).TotalPackets);
jsonPckt["klvs"] = (JObject)kf.decodedData;
m_MonitorAgent.PubNewPacket(jsonPckt.ToString());
}
static void ReportError(string format, params object[] args)
{
lock (ConsoleLock)
{
StyleSheet styleSheet = new StyleSheet(Color.Red);
styleSheet.AddStyle("[0-9]*", Color.GreenYellow);
Console.WriteLineStyled(format, args, styleSheet);
Console.ForegroundColor = Color.White;
}
}
static bool CopyDataToBitmap(int biWidth, int biHeight, PixelFormat pixelFormat, byte[] data)
{
try
{
Bitmap bmp = new Bitmap(biWidth, biHeight, pixelFormat);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat);
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
bmp.UnlockBits(bmpData);
bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
Task.Factory.StartNew(() => { SaveFrame(bmp, string.Format("{0}\\frame_{1}", m_targetDir, imageFileIndex++)); });
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
return false;
}
return true;
}
static void SaveFrameAsBitmap(Bitmap bmp, string path)
{
bmp.Save(path + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
static void SaveFrameAsJpeg(Bitmap bmp, string path)
{
bmp.Save(path + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
private static void PrintManual()
{
parser.HelpOption.ShowHelp(parser.Options);
string arguments = @"Usage: {0} -i {1} -o {2} ";
string[] cmds = new string[] { "KlvPlayerTestApp.exe", "urlSource", "urlTarget" };
Console.WriteLineFormatted(arguments, Color.White, Color.Aqua, cmds);
cmds = new string[] { "KlvPlayerTestApp.exe", @"udp://227.1.1.1:30120", @"C:\Movie\capture.ts" };
Console.WriteLineFormatted(arguments, Color.White, Color.Aqua, cmds);
arguments = @"Usage: {0} -i {1} ";
cmds = new string[] { "KlvPlayerTestApp.exe", @"C:\Movie\KLV\3t.mpg" };
Console.WriteLineFormatted(arguments, Color.White, Color.Aqua, cmds);
Console.ForegroundColor = Color.White;
}
private static void PrintCommands()
{
string arguments = "\n {0} Start/Continue \n" +
" {1} Pause \n" +
" {2} Back to live \n" +
" {3} Stop \n" +
" {4} Go To (Seek)\n" +
" {5} Step Forward\n" +
" {6} Step Backward\n" +
" {7} Show video resolution\n" +
" {8} Full Screen\n" +
" {9} Show Node Info\n" +
" {10} Show arguments\n" +
" {11} Monitor\n" +
" {12} Quit\n";
Formatter[] argCmds = new Formatter[]
{
new Formatter("S", Color.LightGreen),
new Formatter("P", Color.LightGreen),
new Formatter("L", Color.LightGreen),
new Formatter("E", Color.LightGreen),
new Formatter("G", Color.RoyalBlue),
new Formatter("->", Color.LightGreen),
new Formatter("<-", Color.LightGreen),
new Formatter("V", Color.Pink),
new Formatter("F", Color.Pink),
new Formatter("N", Color.Pink),
new Formatter("H", Color.White),
new Formatter("K", Color.Orange),
new Formatter("ESC/Q", Color.Aquamarine),
};
Console.WriteLineFormatted(arguments, Color.White, argCmds);
Console.ForegroundColor = Color.White;
}
private static void PrintArguments()
{
string arguments = "\n Parameters:\n Input Url {0}\n DVR (recording) Url {1}\n Frame Target Dir {2}\n Show video {3} MaxDelay {4} Caching {5} Frame Capture {6}\n Min Klv Packet count {7} Klv Pid {8}";
Formatter[] argCmds = new Formatter[]
{
new Formatter(m_Url, Color.LightGreen),
new Formatter(!String.IsNullOrEmpty(m_urlDvrRecording) ? m_urlDvrRecording : "-", Color.LightGreen),
new Formatter(m_targetDir, Color.LightGreen),
new Formatter(m_fVideoPlayback ? "Yes" : "No", Color.Coral),
new Formatter(m_MaxDelay, Color.Crimson),
new Formatter(m_Caching, Color.Crimson),
new Formatter(m_frameCaptureFormat, Color.Crimson),
new Formatter(m_MinKlvPacketCount, Color.Crimson),
new Formatter(m_KlvPid, Color.Crimson)
};
Console.WriteLineFormatted(arguments, Color.White, argCmds);
Console.ForegroundColor = Color.White;
}
static void PrintNodeInfo()
{
var klvPlayer = new CKlvPlayer();
string arguments = @" NodeInfo : {0}";
string[] ni = new string[] { klvPlayer.GetNodeInfo() };
Console.WriteLineFormatted(arguments, Color.Aqua, Color.White, ni);
klvPlayer.Close();
klvPlayer.Dispose();
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = (Exception)e.ExceptionObject;
string errStr = "Whoops! Please contact the developers with the following information:\n\n" + ex.Message + ex.StackTrace;
Trace.WriteLine(errStr);
}
finally
{
if (m_MonitorAgent != null)
m_MonitorAgent.CloseAllSubscribers();
Close();
}
}
}
public sealed class Spinner
{
private static Lazy<Spinner> lazy = new Lazy<Spinner>(() => new Spinner());
public static void Reset()
{
lazy = new Lazy<Spinner>(() => new Spinner());
}
public static Spinner Instance { get { return lazy.Value; } }
private readonly int _consoleX;
private readonly int _consoleY;
private readonly char[] _frames = { '|', '/', '-', '\\' };
private int _current;
private Spinner()
{
_current = 0;
_consoleX = Console.CursorLeft;
_consoleY = Console.CursorTop;
}
public void Update()
{
Console.Write(_frames[_current]);
Console.SetCursorPosition(_consoleX, _consoleY);
if (++_current >= _frames.Length)
_current = 0;
}
}
}
Untitled 1




 Copyright 2023,    IMPLEOTV SYSTEMS LTD