2024年9月1日 星期日

Tektronix MSO64B C# GUI Application

Purpose:
為了長時間去偵測TekTronix的MSO64B量到的數據並記錄下來, 因此才有這個專案產生. 利用C#寫的GUI來做這個動作!
Fundamental:
TEKTRONIX太克
6B 系列MSO 混合訊號示波器
GUI:
包含連接儀器控制, 儀器channel顯示控制, 個別channel 顯示 和即時儲存量測資料

Demo:



2024年8月13日 星期二

C# 利用ffmpeg將WebCAM影像Streaming to RTSP server

Purpose:
利用C#架構一個RTSP 影像streaming的環境.包含WebCAM控制, FFMpeg使用 and Emgu.CV的應用 
Fundamental:
RTSP
即時串流協定(Real Time Streaming Protocol,RTSP)是一種網路應用協定,專為娛樂和通訊系統的使用,以控制串流媒體伺服器。該協定用於建立和控制終端之間的媒體對談。媒體伺服器的客戶端發布VCR命令,例如播放,錄製和暫停,以便於即時控制從伺服器到客戶端(影片點播)或從客戶端到伺服器(語音錄音)的媒體流。
FFmpeg
FFmpeg 是一個開放原始碼的自由軟體,它包含了音訊和視訊多種格式的錄影、轉檔、串流功能,同時也是一個音訊與視訊格式轉換函式庫(Library),許多開源的工具都是基於 FFmpeg 打造的。

Reference:
感謝分享:包含 RTSP windows server 和一些相關軟體介紹與下載!!
public void StartRTSP(string path)
    {
       
        if (_RTSPPara._process != null && !_RTSPPara._process.HasExited)
            return;

        _RTSPPara._process = new Process();
        _RTSPPara._process.StartInfo.UseShellExecute = false;
        _RTSPPara._process.StartInfo.FileName = @path;
        _RTSPPara._process.StartInfo.Arguments = "";
        _RTSPPara._process.StartInfo.RedirectStandardInput = true;
        _RTSPPara._process.StartInfo.RedirectStandardOutput = true;
        _RTSPPara._process.StartInfo.RedirectStandardError = true;
        _RTSPPara._process.EnableRaisingEvents = true;
        _RTSPPara._process.StartInfo.CreateNoWindow = true;
        try
        {
            var started = _RTSPPara._process.Start();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
        }

        _RTSPPara._process.BeginErrorReadLine();
        _RTSPPara._process.BeginOutputReadLine();
    }


public void StartFFmpeg(string path, string webname)
    {
        string rtspServer = "rtsp://localhost:8554/test";
        string ffmpegCommand =
                $"-f dshow -i video=\"{webname}\" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -rtsp_transport tcp -f rtsp {rtspServer}";
        if (_FFmpegPara._process != null && !_FFmpegPara._process.HasExited)
            return;

        _FFmpegPara._process = new Process();
        _FFmpegPara._process.StartInfo.UseShellExecute = false;
        _FFmpegPara._process.StartInfo.FileName = @path;
        _FFmpegPara._process.StartInfo.Arguments = ffmpegCommand;
        _FFmpegPara._process.StartInfo.RedirectStandardInput = true;
        _FFmpegPara._process.StartInfo.RedirectStandardOutput = true;
        _FFmpegPara._process.StartInfo.RedirectStandardError = true;
        _FFmpegPara._process.EnableRaisingEvents = true;
        _FFmpegPara._process.StartInfo.CreateNoWindow = true;
        _FFmpegPara._process.StartInfo.Verb = "RunAs";
        try
        {
            var started = _FFmpegPara._process.Start();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
        }

        _FFmpegPara._process.BeginErrorReadLine();
        _FFmpegPara._process.BeginOutputReadLine();
    }

        private void button7_Click(object sender, EventArgs e)
        {

            if (FFmpeg._FFmpegPara.RunisFinish == true)
            {
                //button5.BackColor = Color.AliceBlue;
                button7.BackColor = Color.Green;
                WebCAM[0].show_screen = true;
                myVideoCapture = new VideoCapture("rtsp://127.0.0.1:8554/test");
                myVideoCapture.ImageGrabbed += imageGrabbedEvent;
                myVideoCapture.Start();
            }
            else if (WebCAM[0].run == true)
            {
                //button5.BackColor = Color.Green;
                button7.BackColor = Color.AliceBlue;
                if (myVideoCapture != null)
                {
                    myVideoCapture.ImageGrabbed -= imageGrabbedEvent;
                    Thread.Sleep(500);
                    myVideoCapture.Dispose();
                }

            }
        }

        public void imageGrabbedEvent(object sender, EventArgs arg)
        {
            try
            {
                TEmgu._EmguPara.ImageSource = myVideoCapture.QueryFrame().ToImage<Bgr, byte>();
            }
            catch (Exception Ex)
            {

            }
            if (TEmgu._EmguPara.ImageSource != null)
            {

                imageBox1.Image = TEmgu._EmguPara.ImageSource.Resize(imageBox1.Width, imageBox1.Height, Emgu.CV.CvEnum.Inter.Linear);

            } //----if (TEmgu._EmguPara.ImageSource != null)
           

        }

2024年7月10日 星期三

c# 如何檢測目錄檔案有變動

Purpose:
在一個測試系統中, 有時候會在特定的目錄中存放測試中的測試資料. 所以便可以在測試時去偵測特定目錄中是否有資料檔案產再去做資料的分析!
Method:

        DirectoryInfo dirInfo;
        FileSystemWatcher watcher = new FileSystemWatcher();
        private void button24_Click(object sender, EventArgs e)
        {
            button24.BackColor = Color.Green;
            button24.Enabled = false;

            FolderBrowserDialog folderDialog = new FolderBrowserDialog();
            folderDialog.SelectedPath = FileCtrl.CANFilePath;
            folderDialog.Description = "Select an listen Folder";

            if (folderDialog.ShowDialog() == DialogResult.OK)
            {
                string selectedPath = folderDialog.SelectedPath;
                dirInfo = new DirectoryInfo(selectedPath);
                string[] files = Directory.GetFiles(selectedPath);
                //設定所要監控的資料夾
                watcher.Path = selectedPath;
                CommonData.WriteMessage(DateTime.Now.ToString("yyyyMMdd_hhmmss_ffff") + " -- ", "選擇監聽目錄檔案於:" + watcher.Path, Color.Blue, Color.Green);
            }

            //FileSystemWatcher watcher = new FileSystemWatcher(@"C:\path\to\folder");

            watcher.NotifyFilter = NotifyFilters.Attributes
                                 | NotifyFilters.CreationTime
                                 | NotifyFilters.DirectoryName
                                 | NotifyFilters.FileName
                                 | NotifyFilters.LastAccess
                                 | NotifyFilters.LastWrite
                                 | NotifyFilters.Security
                                 | NotifyFilters.Size;

            //watcher.Changed += OnChanged;
            watcher.Created += OnCreated;
            //watcher.Deleted += OnDeleted;
            //watcher.Renamed += OnRenamed;
            //watcher.Error += OnError;

            if (comboBox_carmodel.Text == "PeakCAN_csv")
            {
                CommonData.Auto_Detect_Mode = 0;
                watcher.Filter = "*.csv";
            }
            else if (comboBox_carmodel.Text == "CANoe_asc")
            {
                CommonData.Auto_Detect_Mode = 1;
                watcher.Filter = "*.asc";
            }
           
            watcher.IncludeSubdirectories = true;
            watcher.EnableRaisingEvents = true;
            button24.BackColor = Color.PeachPuff;
            button24.Enabled = true;
        }

private void OnCreated(object sender, FileSystemEventArgs e)
        {
            dirInfo = new DirectoryInfo(e.FullPath.ToString());
            CommonData.FilterFlag = true;
            Thread.Sleep(100);
            CommonData.WriteMessage(DateTime.Now.ToString("yyyyMMdd_hhmmss_ffff") + " -- ", "新建檔案於:" + dirInfo.FullName.Replace(dirInfo.Name, ""), Color.Blue, Color.Green);
            CommonData.WriteMessage(DateTime.Now.ToString("yyyyMMdd_hhmmss_ffff") + " -- ", "新建檔案名稱:" + dirInfo.Name, Color.Blue, Color.Green);
            CommonData.WriteMessage(DateTime.Now.ToString("yyyyMMdd_hhmmss_ffff") + " -- ", "建立時間:" + dirInfo.CreationTime.ToString(), Color.Blue, Color.Green);
            CommonData.WriteMessage(DateTime.Now.ToString("yyyyMMdd_hhmmss_ffff") + " -- ", "目錄下共有:" + dirInfo.Parent.GetFiles().Count() + " 檔案", Color.Blue, Color.Green);
            CommonData.WriteMessage(DateTime.Now.ToString("yyyyMMdd_hhmmss_ffff") + " -- ", "目錄下共有:" + dirInfo.Parent.GetDirectories().Count() + " 資料夾", Color.Blue, Color.Green);

        }

2024年7月9日 星期二

C# 讀取超大檔案方式

Purpose:
在專案中, 有一需求是去搜尋一些500MB個別檔案重複資料, 嘗試了很多讀取檔案的方式. 最後試出來最快的方法.
Method:
using System.IO;

string strLine;
const int MAX_BUFFER = 33554432; //32MB 
using (FileStream fs = File.Open(csvFile, FileMode.Open, FileAccess.Read))
using (BufferedStream bs = new BufferedStream(fs, MAX_BUFFER)
using (StreamReader sr = new StreamReader(bs))
{  
    while (!sr.EndOfStream)
   {
        while ((strLine = sr.ReadLine()) != null)
       {
               //---處理資料
        }

    }
    sr.Close();
    sr.Dispose();
}

希望對你們有幫助!!