海康摄像头播放库SDK播放转发过来的码流

暗夜流岚 2019-05-21 05:35:24
基于海康的SDK开发远程监控,使用C#窗体程序进行开发。客户端接收摄像头之后,是通过sockte转发到监听服务器,然后进行播放,代码:
客户端:
 
List<object> list = new List<object>();
byte[] write = new byte[dwBufSize];
Marshal.Copy(pBuffer, write, 0, write.Length);

list.Add(lRealHandle); //句柄参数
list.Add(write); // Data数据
list.Add(dwBufSize); //数据大小
list.Add(dwDataType); //数据类型

//VideoRecord(); //录像判断是否重新生成视频文件 (暂时注释)

#region 解码播放
switch (dwDataType) //1 系统头数据 2 流数据(包括复合流或音视频分开的视频流数据) 3 音频数据 112 私有数据,包括智能信息
{
#region sys head 系统头数据
case CHCNetSDK.NET_DVR_SYSHEAD:
if (dwBufSize > 0)
{
if (form1.indexPort[cameraIndex] >= 0)
{
return; //同一路码流不需要多次调用开流接口
}
//获取播放句柄 Get the port to play
if (!PlayCtrl.PlayM4_GetPort(ref m_lPort))
{
Console.WriteLine("获取播放句柄 错误码" + PlayCtrl.PlayM4_GetLastError(m_lPort));
break;
}


//设置流播放模式 Set the stream mode: real-time stream mode
if (!PlayCtrl.PlayM4_SetStreamOpenMode(m_lPort, PlayCtrl.STREAME_REALTIME))
{
Console.WriteLine("设置流播放模式 错误码" + PlayCtrl.PlayM4_GetLastError(m_lPort));
}

//打开码流,送入头数据 Open stream
if (!PlayCtrl.PlayM4_OpenStream(m_lPort, pBuffer, dwBufSize, 2 * 1024 * 1024))
{
Console.WriteLine("打开码流,送入头数据 错误码" + PlayCtrl.PlayM4_GetLastError(m_lPort));
break;
}


//设置显示缓冲区个数 Set the display buffer number
if (!PlayCtrl.PlayM4_SetDisplayBuf(m_lPort, 0))
{
Console.WriteLine("设置显示缓冲区个数 错误码" + PlayCtrl.PlayM4_GetLastError(m_lPort));
}

//设置显示模式 Set the display mode
if (!PlayCtrl.PlayM4_SetOverlayMode(m_lPort, 0, 0/* COLORREF(0)*/)) //play off screen
{
Console.WriteLine("设置显示模式 错误码" + PlayCtrl.PlayM4_GetLastError(m_lPort));
}

//设置解码回调函数,获取解码后音视频原始数据 Set callback function of decoded data
m_fDisplayFun = new PlayCtrl.DECCBFUN(DecCallbackFUN);
if (!PlayCtrl.PlayM4_SetDecCallBackEx(m_lPort, m_fDisplayFun, IntPtr.Zero, 0))
{
//this.BeginInvoke(AlarmInfo, "PlayM4_SetDisplayCallBack fail");
}

//开始解码 Start to play
if (!PlayCtrl.PlayM4_Play(m_lPort, m_ptrRealHandle))
{
Console.WriteLine("Start to play 错误码" + PlayCtrl.PlayM4_GetLastError(m_lPort));
//str = "PlayM4_Play failed, error code= " + iLastErr;
//this.BeginInvoke(AlarmInfo, str);
break;
}
#region 发送视频数据
ThreadPool.QueueUserWorkItem(new WaitCallback(implSendCameraSocket.SendMsg), list);
#endregion

form1.indexPort[cameraIndex] = m_lPort;
}
break;
#endregion

#region video stream data 视频流数据(包括复合流和音视频分开的视频流数据)
case CHCNetSDK.NET_DVR_STREAMDATA:
if (dwBufSize > 0 && m_lPort != -1)
{
for (int i = 0; i < 999; i++)
{
//送入码流数据进行解码 Input the stream data to decode
if (!PlayCtrl.PlayM4_InputData(m_lPort, pBuffer, dwBufSize))
{
Console.WriteLine("输入码流1 错误码" + PlayCtrl.PlayM4_GetLastError(m_lPort));
}
else
{
#region 发送视频数据
ThreadPool.QueueUserWorkItem(new WaitCallback(implSendCameraSocket.SendMsg), list);
#endregion
break;
}
}

}
break;
#endregion

#region 默认
default:
if (dwBufSize > 0 && m_lPort != -1)
{
//送入其他数据 Input the other data
for (int i = 0; i < 999; i++)
{
if (!PlayCtrl.PlayM4_InputData(m_lPort, pBuffer, dwBufSize))
{
Console.WriteLine("输入码流2 错误码" + PlayCtrl.PlayM4_GetLastError(m_lPort));
//str = "PlayM4_InputData failed, error code= " + iLastErr;
//Thread.Sleep(2);
}
else
{
ThreadPool.QueueUserWorkItem(new WaitCallback(form1.implSendCameraSocket.SendMsg), list);
break;
}
}
}
break;
#endregion
}
#endregion



服务端:


//连接客户端
private void watchconnecting(object state)
{
while (true)
{
connection = socketWatch.Accept();
//获取客户端的IP和端口号
IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port;
//向客户端发送回执
string sendmsg = "连接服务端成功!\r\n" + "本地IP:" + clientIP + ",本地端口" + clientPort.ToString();
byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg);
connection.Send(arrSendMsg);
//客户端网络节点号
string remoteEndPoint = connection.RemoteEndPoint.ToString();
Console.WriteLine("成功与" + remoteEndPoint + "客户端建立连接!");
IPEndPoint netpoint = connection.RemoteEndPoint as IPEndPoint;

ThreadPool.QueueUserWorkItem(new WaitCallback(this.recv), connection);

Thread.Sleep(5);
}
}


private void recv(object state)
{
socketServer = state as Socket;
byte[] arrServerRecMsg = new byte[1024 * 1024 * 8];

//视频显示句柄
m_ptrRealHandle = panel1.Handle;
while (true)
{
try
{
int length = socketServer.Receive(arrServerRecMsg);
DataAnalysis(arrServerRecMsg, length); //接受数据方法
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
Thread.Sleep(5);
}
}






...全文
1683 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
暗夜流岚 2019-05-24
  • 打赏
  • 举报
回复
要沉了么
暗夜流岚 2019-05-23
  • 打赏
  • 举报
回复
自己顶一下
暗夜流岚 2019-05-21
  • 打赏
  • 举报
回复
好的我试一下,解决后给分,谢谢
OrdinaryCoder 2019-05-21
  • 打赏
  • 举报
回复
看一下 摄像头码流的编码格式 如果是H265 改成264试试
暗夜流岚 2019-05-21
  • 打赏
  • 举报
回复
接上面代码

 private void DataAnalysis(byte[] arrServerRecMsg, int length)
        {
            Int32 lRealHandle;            //句柄
            UInt32 dwBufSize = (UInt32)length;             //数据长度
            UInt32 dwDataType;            //数据类型
            #region 数据头文件   自定义传输的字节
            if (arrServerRecMsg[0] != 0xbb || arrServerRecMsg[1] != 0xcc)   //|| bt[5] == 0xfd 
            {
                return;
            }
            lRealHandle = arrServerRecMsg[2];
            dwBufSize = (UInt32)(arrServerRecMsg[3] * 16777216 + arrServerRecMsg[4] * 65536 + arrServerRecMsg[5] * 256 + arrServerRecMsg[6]);
            dwDataType = arrServerRecMsg[7];
            #endregion
            
            //码流字节
            byte[] newByte = caneraBytes(arrServerRecMsg, length, dwBufSize);  //视频数据
            
            //转换成指针类型
            IntPtr pBuffer = Marshal.AllocHGlobal((int)dwBufSize);
            Marshal.Copy(newByte, 0, pBuffer, (int)dwBufSize);
            Marshal.FreeHGlobal(pBuffer);


            #region 视频预览
            try
            {

                if (dwDataType == 1)
                {
                    //m_ptrRealHandle = previewPanels[lRealHandle].Handle;       // 播放窗口的句柄,为NULL表示不播放图象  
                    //获取播放句柄 Get the port to play
                    if (!PlayCtrl.PlayM4_GetPort(ref m_lPort))
                    {
                        iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
                        break;
                    }

                    //设置流播放模式 Set the stream mode: real-time stream mode
                    if (!PlayCtrl.PlayM4_SetStreamOpenMode(m_lPort, PlayCtrl.STREAME_REALTIME))
                    {
                        iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
                        
                    }

                    //打开码流,送入头数据 Open stream
                    if (!PlayCtrl.PlayM4_OpenStream(m_lPort, pBuffer, dwBufSize, 2 * 1024 * 1024))
                    {
                        iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
                        break;
                    }


                    //设置显示缓冲区个数 Set the display buffer number
                    if (!PlayCtrl.PlayM4_SetDisplayBuf(m_lPort, 5))
                    {
                        iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
                    }

                    //设置显示模式 Set the display mode
                    if (!PlayCtrl.PlayM4_SetOverlayMode(m_lPort, 0, 0/* COLORREF(0)*/)) //play off screen 
                    {
                        iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
                    }

                    //设置解码回调函数,获取解码后音视频原始数据 Set callback function of decoded data
                    m_fDisplayFun = new PlayCtrl.DECCBFUN(DecCallbackFUN);
                    if (!PlayCtrl.PlayM4_SetDecCallBackExMend(m_lPort, m_fDisplayFun, IntPtr.Zero, 0, 0))
                    {
                       
                    }
                    if (!PlayCtrl.PlayM4_SetDecCallBackEx(m_lPort, m_fDisplayFun, IntPtr.Zero, 0))
                    {
                       
                    }
                    //开始解码 Start to play                       
                    if (!PlayCtrl.PlayM4_Play(m_lPort, panel1.Handle))
                    {
                        iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
                        Console.WriteLine("播放首帧失败;错误码:" + iLastErr);
                         break;
                        
                    }
                }
                else if(dwDataType == 2)
                //else if(y == false)
                {
                    //送入码流数据进行解码 Input the stream data to decode
                    if (!PlayCtrl.PlayM4_InputData(m_lPort, pBuffer, dwBufSize))
                    {
                        iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
                        Console.WriteLine("播放失败;错误码:" + iLastErr);
                        Thread.Sleep(2);
                    }
                    else
                    {
                        Console.WriteLine("播放成功!");
                    }
                }


            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.Message +  ex.StackTrace);
            }
            #endregion
        }
接收数据后进行解析,调用海康播放库SDK接口(和开发SDK不一样,具体都可以在海康官网下载),不报异常但是却不显示画面,求各位大神帮助!

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧