本文转自EasyDarwin团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/52755298

EasyCamera接收云平台实时视频请求命令,会向EasyDarwin流媒体服务器进行推流操作。那么EasyCamera是如何通过海康摄像机SDK获取到媒体流的呢?

我们继续看海康摄像机SDK

这里使用NET_DVR_RealPlay_V40/NET_DVR_StopRealPlay接口控制实时视频。

在获取实时视频调用之前,我们需要知道摄像机目前的参数配置,比如FPS,码率等等。

//参数获取
NET_DVR_COMPRESSIONCFG_V30 struCompressionCfg;
memset(&struCompressionCfg, 0, sizeof(struCompressionCfg));
DWORD dwReturned = 0;
EASY_MEDIA_INFO_T mediainfo;
memset(&mediainfo, 0x00, sizeof(EASY_MEDIA_INFO_T));
mediainfo.u32VideoCodec = EASY_SDK_VIDEO_CODEC_H264;
mediainfo.u32AudioChannel = 1;
if (!NET_DVR_GetDVRConfig(m_u32Handle, NET_DVR_GET_COMPRESSCFG_V30, 1, &struCompressionCfg, sizeof(NET_DVR_COMPRESSIONCFG_V30), &dwReturned))
{
printf("can't get config!\n"); mediainfo.u32VideoFps = 25;
mediainfo.u32AudioCodec = EASY_SDK_AUDIO_CODEC_G711A;
mediainfo.u32AudioSamplerate = 8000;
}
else
{
mediainfo.u32VideoFps = getFrameRateFromHKSDK(struCompressionCfg.struNormHighRecordPara.dwVideoFrameRate);
mediainfo.u32AudioCodec = getAudioCodecFromHKSDK(struCompressionCfg.struNormHighRecordPara.byAudioEncType);
mediainfo.u32AudioSamplerate = getAudioSimpleRateFromHKSDK(struCompressionCfg.struNormHighRecordPara.byAudioSamplingRate);
}
//实时视频调用
NET_DVR_PREVIEWINFO struPlayInfo = { 0 };
struPlayInfo.hPlayWnd = NULL; //需要 SDK 解码时句柄设为有效值,仅取流不解码时可设为空
struPlayInfo.lChannel = 1; //预览通道号
struPlayInfo.dwStreamType = 0; //0-主码流, 1-子码流, 2-码流 3, 3-码流 4,以此类推
struPlayInfo.dwLinkMode = 0; //0- TCP 方式, 1- UDP 方式, 2- 多播方式, 3- RTP 方式, 4-RTP/RTSP, 5-RSTP/HTTP
struPlayInfo.bBlocked = 1; //0- 非阻塞取流, 1- 阻塞取流 streamHandle = NET_DVR_RealPlay_V40(m_u32Handle, &struPlayInfo, myStreamProc, this);
if (streamHandle < 0)
{
qtss_printf("NET_DVR_RealPlay_V40 Fail\n");
LONG error = NET_DVR_GetLastError();
return QTSS_RequestFailed;
}
//数据回调
QTSS_Error EasyCameraSource::PushFrame(unsigned char* frame, int len, DWORD dataType)
{
OSMutexLocker locker(&fStreamingMutex);
if (fPusherHandle == NULL) return QTSS_Unimplemented; if (dataType == NET_DVR_STREAMDATA)
{
if (len > 0)
{
unsigned char *h264Buf = NULL;
int h264Len = 0;
BOOL isVideo;
GetH246FromPS(frame, len, &h264Buf, h264Len, isVideo);
if (isVideo)
{
if (h264Buf)
{
/*printf("size:%04d\t[0]:0x%08X\t[1]:0x%08X\t[2]:0x%08X\t[3]:0x%08X\t[4]:0x%08X \n",
h264Len, h264Buf[0], h264Buf[1], h264Buf[2], h264Buf[3], h264Buf[4]);*/ if (h264Buf[0] == 0 && h264Buf[1] == 0 && h264Buf[2] == 0 && h264Buf[3] == 1)
{
if (fPusherBuffOffset > 0)
{
EASY_AV_Frame avFrameVideo;
memset(&avFrameVideo, 0x00, sizeof(EASY_AV_Frame));
avFrameVideo.u32AVFrameLen = fPusherBuffOffset;
avFrameVideo.pBuffer = (unsigned char*)fPusherBuff;
bool isKeyFrame = IsIFrame(fPusherBuff);
avFrameVideo.u32VFrameType = isKeyFrame ? EASY_SDK_VIDEO_FRAME_I : EASY_SDK_VIDEO_FRAME_P;
avFrameVideo.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;
//avFrameVideo.u32TimestampSec = pstruAV->u32AVFramePTS / 1000;
//avFrameVideo.u32TimestampUsec = (pstruAV->u32AVFramePTS % 1000) * 1000;
Easy_U32 ret = EasyPusher_PushFrame(fPusherHandle, &avFrameVideo);
//printf("-- Pushing: Frame %s Result %d \n", isKeyFrame ? "I" : "P", ret);
fPusherBuffOffset = 0;
}
memcpy(fPusherBuff, h264Buf, h264Len);
fPusherBuffOffset += h264Len;
}
else
{
if (fPusherBuffOffset > 0)
{
memcpy(fPusherBuff + fPusherBuffOffset, h264Buf, h264Len);
fPusherBuffOffset += h264Len;
}
}
}
if (h264Buf)
{
delete[] h264Buf;
h264Buf = NULL;
}
}
}
}
else if (dataType == NET_DVR_AUDIOSTREAMDATA)
{
if (len > 0)
{
EASY_AV_Frame avFrameAudio;
memset(&avFrameAudio, 0x00, sizeof(EASY_AV_Frame));
avFrameAudio.u32AVFrameLen = len;
avFrameAudio.pBuffer = (unsigned char*)frame;
avFrameAudio.u32AVFrameFlag = EASY_SDK_AUDIO_FRAME_FLAG;
//avFrameAudio.u32TimestampSec = pstruAV->u32AVFramePTS / 1000;
//avFrameAudio.u32TimestampUsec = (pstruAV->u32AVFramePTS % 1000) * 1000;
EasyPusher_PushFrame(fPusherHandle, &avFrameAudio);
}
} return Easy_NoErr;
}

源码及视频教程

源码地址:https://github.com/EasyDarwin/EasyDarwin/tree/master/EasyCamera-HK

视频教程地址:[http://edu.csdn.net/course/detail/3029

](http://edu.csdn.net/course/detail/3029)

获取更多信息

邮件:support@easydarwin.org

WEB:www.EasyDarwin.org

Copyright © EasyDarwin.org 2012-2016

EasyDarwin流媒体云平台:EasyCamera开源摄像机接入海康威视摄像机实时视频的更多相关文章

  1. EasyDarwin流媒体云平台架构

    EasyDarwin目前正在做的开源流媒体云平台架构:

  2. EasyDarwin云平台:EasyCamera开源摄像机接入海康威视摄像机PS流转ES流

    本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376 海康威视使用PS流封装H.264流,EasyDarwin云平台支持ES流.当我们 ...

  3. EasyDarwin开源流媒体云平台设计与实现(分布式+负载均衡)

    前言 早在2013年我就设计了一套架构非常简单的分布式流媒体服务器平台<基于Darwin实现的分布式流媒体直播服务器系统>,当时的考虑如今看来有诸多的细节点没有考虑到:1.CMS是单点部署 ...

  4. EasyDarwin开源流媒体云平台支持EasyCamera摄像机、EasyCamera手机直播监控、EasyNVR等多终端接入

    云平台架构 EasyDarwin开源流媒体云平台目前已经包括了EasyCMS中心管理服务.EasyDarwin流媒体服务.EasyCamera设备端(支持Arm_Linux.Android.PC).E ...

  5. EasyCamera Android安卓移动视频监控单兵设备接入EasyDarwin开源流媒体云平台

    前言 随着Android系统的不断更新和发展,现在越来越多的硬件产品选择用安卓系统作为运行环境,电视机,机顶盒.门禁.行车记录仪.车载系统.单兵设备等等,Android系统底层还是Linux,但对上层 ...

  6. EasyDarwin开源流媒体云平台之语音对讲功能设计与实现

    本文由EasyDarwin开源团队成员Alex贡献:http://blog.csdn.net/cai6811376/article/details/52006958 EasyDarwin云平台一直在稳 ...

  7. EasyDarwin开源流媒体云平台之云台ptz控制设计与实现

    本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/51912692 近日,EasyDarwin云平 ...

  8. EasyDarwin开源流媒体云平台之EasyRMS录播服务器功能设计

    需求背景 EasyDarwin开发团队维护EasyDarwin开源流媒体服务器也已经很多年了,之前也陆陆续续尝试过很多种服务端录像的方案,有:在EasyDarwin中直接解析收到的RTP包,重新组包录 ...

  9. EasyDarwin开源流媒体云平台VS调试断点提示“还没有为该文档加载任何符号”的解决办法

    本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/52063666 近日,我们EasyDarwin ...

随机推荐

  1. APUE 学习笔记(七) 信号

    1.信号是软件中断,提供一种异步处理事件的方法 很多事件产生信号: (1)用户按下某些中断键,如 Ctrl + C键产生 SIGINT信号 (2)硬件异常产生信号,比如 除数为0,无效的内存引用  ( ...

  2. POJ 2893 M × N Puzzle

    逆序对 n 数码问题的扩展 对于一个n * m 的问题来说,结论和 列数 m 奇偶有关 对于 m 是奇数来说 , 两个局面互相可达,当且仅当这两个局面按顺序写成一个数列,这个数列的逆序对数的奇偶性相同 ...

  3. LeetCode OJ-- Spiral Matrix

    https://oj.leetcode.com/problems/spiral-matrix/ 螺旋矩阵,逆着转,输出矩阵中的元素. 在纸上模仿,然后记左上角(l1,l2)右上角(l1,r2),左下角 ...

  4. 设计模式原来如此-单例模式(Singleton Pattern)

    简单介绍一下我对Singleton的理解,说的不好请大家多多指点. 单例模式的简单定义就是确保一个类只有一个实例,并提供一个全局访问点. 单例模式有哪些用处呢? 有一些对象其实我们只需要一个,比方说: ...

  5. (1)sqlite基础

    一.安装sqlite 下载页面:http://www.sqlite.org/download.html 1.下载 sqlite-tools-win32-*.zip 和 sqlite-dll-win32 ...

  6. HDU 3534 Tree (经典树形dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3534 题意: 给你一棵树,问你有多少对点的距离等于树的直径. 思路: dp[i][0]表示在i的子树中 ...

  7. JDK1.8日期时间库学习

    这周在阅读<阿里巴巴Java开发手册>时,在并发处理一节的日期处理中,其强调SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果 定义为 stati ...

  8. JavaScript的变量:变量提升

    JavaScript代码的运行规则 在JavaScript代码运行之前其实是有一个编译阶段的.编译之后才是从上到下,一行一行解释执行.这样一来也给初学者造成很大的误解.初学者会觉得JavaScript ...

  9. Linux如何显示文件指定行数的内容;显示第一行、中间几行和最后几行

    1.tail -n +/-数字 文件名 2.head -n 数字 文件名 3.sed -n "开始行,结束行p" 文件名 4.sed -n '1p;20,40p; "显示 ...

  10. 【Todo】Java并发学习 & 示例练习及代码

    接上一篇:http://www.cnblogs.com/charlesblc/p/6097111.html <Java并发学习 & Executor学习 & 异常逃逸 & ...