聲明:本系列文章只提供交流與學習使用。文章中所有涉及到??低曉O備的SDK均可在??低暪俜骄W站下載得到。文章中所有除官方SDK以為的代碼均可隨意使用,任何涉及到??低暪纠娴姆钦J褂糜墒褂谜咦约贺撠?,與本人無關。
前言:
《??低曨l監控設備Web查看系統(一):概要篇》
《??低曨l監控設備Web查看系統(二):服務器篇》
本文是本系列三篇文章中的最后一篇,在前兩篇文章中,介紹了開發??当O控的方案及中轉服務器的實現,本篇文章介紹Web端的功能實現,經過本篇文章中的項目開發,我們就實現了最初的項目需求。 項目中需要??倒俜讲シ牌鱏DK,請各位根據項目需要下載相應版本。先來作者就帶著大家一步步來實現客戶端插件的開發。
播放器開發:
根據??倒俜降腟DK,我們要做的播放器其實只是將海康的播放庫引入到我們自己的項目中,然后接收來自中轉服務器的數據,最后播放顯示到客戶Web瀏覽器上。其實整個就是一個引入了??挡シ艓斓腁ctiveX插件開發。下面按照開發流程一步步實現播放器插件開發。
關于C#開發ActiveX的詳細過程,園子里有好多文章寫的非常詳細,我這里不在累述,有不太了解的朋友,我這里推薦一篇比較詳細的文章《asp.net C# 之 Activex用C#編寫ActiveX控件》。本篇文章寫播放器插件的核心功能。
首先來看SDK的C#調用的內容:
1 public class PlayCtrlSDK 2 { 3 #region 解碼庫 4 [DllImport("PlayCtrl.dll")] 5 public static extern uint PlayM4_GetLastError(int nPort); 6 [DllImport("PlayCtrl.dll")] 7 public static extern int PlayM4_GetCaps(); 8 /// <summary> 9 /// 獲取未使用的通道號10 /// </summary>11 /// <param name="nPort"></param>12 /// <returns></returns>13 [DllImport("PlayCtrl.dll")]14 public static extern bool PlayM4_GetPort(ref int nPort);15 /// <summary>16 /// 設置流播放模式17 /// </summary>18 /// <param name="port"></param>19 /// <param name="mode"></param>20 /// <returns></returns>21 [DllImport("PlayCtrl.dll")]22 public static extern bool PlayM4_SetStreamOpenMode(int nPort, int mode);23 /// <summary>24 /// 打開流25 /// </summary>26 /// <param name="nPort"></param>27 /// <param name="pFileHeadBuf"></param>28 /// <param name="nSize"></param>29 /// <param name="nBufPoolSize"></param>30 /// <returns></returns>31 [DllImport("PlayCtrl.dll")]32 public static extern bool PlayM4_OpenStream(int nPort, byte[] pFileHeadBuf, UInt32 nSize, uint nBufPoolSize);33 /// <summary>34 /// 設置播放緩沖區最大緩沖幀數35 /// </summary>36 /// <param name="nPort"></param>37 /// <param name="nNum"></param>38 /// <returns></returns>39 [DllImport("PlayCtrl.dll")]40 public static extern bool PlayM4_SetDisplayBuf(int nPort, uint nBufPoolSize);41 /// <summary>42 /// 開啟播放43 /// </summary>44 /// <param name="nPort"></param>45 /// <param name="hWnd"></param>46 /// <returns></returns>47 [DllImport("PlayCtrl.dll")]48 public static extern bool PlayM4_Play(int nPort, IntPtr hWnd);49 /// <summary>50 /// 開始倒放51 /// </summary>52 /// <param name="nPort"></param>53 /// <returns></returns>54 [DllImport("PlayCtrl.dll")]55 public static extern bool PlayM4_ReversePlay(int nPort);56 /// <summary>57 /// 輸入流數據58 /// </summary>59 /// <param name="nPort"></param>60 /// <param name="pBuf"></param>61 /// <param name="nSize"></param>62 /// <returns></returns>63 [DllImport("PlayCtrl.dll")]64 public static extern bool PlayM4_InputData(int nPort, byte[] pBuf, uint nSize);65 /// <summary>66 /// 關閉播放67 /// </summary>68 /// <param name="nPort"></param>69 /// <returns></returns>70 [DllImport("PlayCtrl.dll")]71 public static extern bool PlayM4_Stop(int nPort);72 /// <summary>73 /// 關閉流74 /// </summary>75 /// <param name="nPort"></param>76 /// <returns></returns>77 [DllImport("PlayCtrl.dll")]78 public static extern bool PlayM4_CloseStream(int nPort);79 /// <summary>80 /// 釋放已使用的通道號81 /// </summary>82 /// <param name="nPort"></param>83 /// <returns></returns>84 [DllImport("PlayCtrl.dll")]85 public static extern bool PlayM4_FreePort(int nPort);86 87 #endregion88 }根據SDK文檔內的說明,這幾個函數的調用順序如下:

下面就該組織我們自己的程序接收來自中轉服務器的數據,并將這些數據交給播放庫的方法來處理。
[Guid("A4277AC0-7F3F-4950-9130-27025D6E18F8")] public partial class Player : UserControl, IObjectSafety { int PRot = -1; static Socket socket; bool isPlayInit = false; ipEndPoint iep; Thread thread; #region Web頁面調用的接口 /// <summary> /// 釋放Socket連接和SDK播放庫資源 /// </summary> public void PageClose() { isPlayInit = false; if (thread != null && thread.IsAlive) { thread.Abort(); } if (socket != null && socket.Connected) { socket.Shutdown(SocketShutdown.Both); socket.Close(); socket = null; } if (prot != -1) { PlayCtrlSDK.PlayM4_CloseStream(prot); } } //插件初始化 public Player() { InitializeComponent(); } /// <summary> /// 初始化網絡連接 /// </summary> /// <param name="ip">中轉服務器IP</param> /// <param name="iPprot">中轉服務器端口</param> public void InitPlay(string ip, int iPprot) { PageClose(); iep = new IPEndPoint(IPAddress.Parse(ip), iPprot); socket = new Socket(iep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); thread = new Thread((object o) => { socket.Connect(iep); byte[] bt = new byte[262144]; while (true) { int count = socket.Receive(bt); StreamType st = count == 40 ? StreamType.Head : StreamType.Body; setPlay(bt, (uint)count, st); Thread.Sleep(100); } }); thread.IsBackground = true; } /// <summary> /// 開始播放 /// </summary> /// <returns></returns> public bool ShowVideo() { thread.Start(); return true; } #endregion /// <summary> /// 調用SDK播放庫 /// </summary> /// <param name="buffer">從中轉服務器接收到的數據</param> /// <param name="size">中轉服務器發送的數據大小</param> /// <param name="type">數據類型</param> private void setPlay(byte[] buffer, uint size, StreamType type) { switch (type) { case StreamType.Head: if (size > 40) { return; } if (!PlayCtrlSDK.PlayM4_GetPort(ref prot)) { PageClose(); showError(PlayCtrlSDK.PlayM4_GetLastError(prot)); break; } if (!PlayCtrlSDK.PlayM4_SetStreamOpenMode(prot, 0)) { PageClose(); showError(PlayCtrlSDK.PlayM4_GetLastError(prot)); break; } if (!PlayCtrlSDK.PlayM4_OpenStream(prot, buffer, size, 1024 * 1024)) { PageClose(); showError(PlayCtrlSDK.Pla
新聞熱點
疑難解答