首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 視訊監控系列(8):服務端本地預覽與啟用客戶端連線完整實作

     編輯:關於C#

本文示範如何在服務端實現本地視訊預覽,並配置 SDK 使客戶端能成功連線預覽。重點解析初始化順序、視窗移動重繪、關鍵回調註冊與啟動參數設定,附完整 C# 程式碼。

一、僅本地預覽


IntPtr channelHandle;

private void Form2_Load(object sender, EventArgs e)
{
    // 設定預設制式
    HikVisionSDK.SetDefaultVideoStandard(VideoStandard.StandardNTSC);

    // 初始化 DSP
    if (HikVisionSDK.InitDSPs() < 0)
    {
        MessageBox.Show("DSP 初始化失敗!");
        return;
    }
    if (HikVisionSDK.GetTotalDSPs() == 0)
    {
        MessageBox.Show("無可用通道,請確認服務端已啟動。");
        return;
    }

    // 開啟通道 0
    channelHandle = HikVisionSDK.ChannelOpen(0);
    HikVisionSDK.SetIBPMode(channelHandle, 100, 2, 1, 25); // IBP 間隔、幀率
    HikVisionSDK.SetDefaultQuant(channelHandle, 15, 15, 20); // 量化參數

    StartVideoPreview();
}

private void StartVideoPreview()
{
    Rectangle rect = panel1.ClientRectangle;
    HikVisionSDK.StartVideoPreview(channelHandle, panel1.Handle, ref rect, false, (int)VideoFormat.vdfRGB16, 25);
}

// 視窗移動時必須重繪
private void Form2_Move(object sender, EventArgs e)
{
    HikVisionSDK.StopVideoPreview(channelHandle);
    StartVideoPreview();
}

關鍵點:StartVideoPreview 的 rect 參數直接用 Rectangle 結構;視窗移動需先 StopVideoPreview 再重新啟動,否則畫面會殘留。

二、啟用客戶端連線並預覽


// 回調委派必須為成員變數
private STREAM_DIRECT_READ_CALLBACK sdrc;

private void PreviewAndClientConnect()
{
    // 1. 註冊碼流直接讀取回調(必須)
    sdrc = new STREAM_DIRECT_READ_CALLBACK(STREAM_DIRECT_READ_CALLBACK1);
    HikVisionSDK.RegisterStreamDirectReadCallback(sdrc, this.Handle);

    // 2. 設定服務端啟動/停止捕獲回調(必須)
    HikServer.MP4_ServerSetStart(new StartCap(StartCapCallback));
    HikServer.MP4_ServerSetCapIFrame(new MakeIFrame(MakeIFrameCallback)); // 關鍵:客戶端連線觸發 I 幀

    // 3. 設定視訊資訊結構
    PSERVER_VIDEOINFO info = new PSERVER_VIDEOINFO();
    info.m_datatype = new byte[64];
    HikServer.MP4_ServerSetBufNum(0, 90); // 發送緩衝 90*8KB
    info.m_datatype[0] = (byte)ChannelDataType.SMALLPIC;
    info.m_channum = 1;
    info.m_waittime = 5;

    // 4. 啟動服務端(必須)
    if (HikServer.MP4_ServerStart(ref info) == 0)
    {
        MessageBox.Show("服務端啟動失敗!");
        return;
    }

    // 5. 開啟本地預覽
    StartVideoPreview();
}

// 回調實作
public void StartCapCallback(int port) => HikVisionSDK.StartVideoCapture(channelHandle);
public void MakeIFrameCallback(ulong port) => HikVisionSDK.CaptureIFrame(channelHandle);

public int STREAM_DIRECT_READ_CALLBACK1(int channelNum, IntPtr dataBuf, int length, FrameType frameType, IntPtr context)
{
    // 僅寫入發送緩衝,不做本地存檔
    int status = (frameType == FrameType.PktIFrames || frameType == FrameType.PktSubIFrames) ? 1 : 0;
    HikServer.MP4_ServerWriteDataEx(channelNum, dataBuf, length, (int)frameType, status, 0);
    return 0;
}

關鍵成功因子總結

  1. MakeIFrame 回調必須實作:客戶端連線時 SDK 會呼叫此回調請求關鍵幀,缺少則客戶端永遠黑畫面。
  2. 回調委派聲明為成員:防止 GC 回收導致執行時錯誤。
  3. 啟動順序:註冊回調 → 設定參數 → MP4_ServerStart → StartVideoPreview。
  4. Rectangle 代替 RECT 結構體傳遞。
  5. GetTotalDSPs() 取得所有通道數,GetDspCount() 僅取啟用數。

調試心得

作者花費一周才攻克「本地有畫面、客戶端連得上但無畫面」的問題,關鍵在於補上 MakeIFrame 回調。建議開發者務必細讀 SDK 文件中「伺服器啟動流程」章節。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved