EasyPusher应用
转自https://github.com/EasyDarwin/EasyPusher
easydarwin今年开始发力了, 不过有商业价值的模块都不开源,他们也得吃饭,可以理解。
本文仅实际体验一下demo,review一下示例代码,分析一下如何应用。
1)EasyPusher框图预览

2) EasyPusher应用实现
a. 推送h264文件
/*
Copyright (c) 2013-2014 EasyDarwin.ORG. All rights reserved.
Github: https://github.com/EasyDarwin
WEChat: EasyDarwin
Website: http://www.EasyDarwin.org
*/
#include "EasyPusherAPI.h"
#include "trace.h" int __EasyPusher_Callback(int _id, EASY_PUSH_STATE_T _state, EASY_AV_Frame *_frame, void *_userptr)
{
if (_state == EASY_PUSH_STATE_CONNECTING) printf("Connecting...\n");
else if (_state == EASY_PUSH_STATE_CONNECTED) printf("Connected\n");
else if (_state == EASY_PUSH_STATE_CONNECT_FAILED) printf("Connect failed\n");
else if (_state == EASY_PUSH_STATE_CONNECT_ABORT) printf("Connect abort\n");
else if (_state == EASY_PUSH_STATE_PUSHING) printf("P->");
else if (_state == EASY_PUSH_STATE_DISCONNECTED) printf("Disconnect.\n"); return ;
} int main()
{
char szIP[] = {};
Easy_Pusher_Handle pusherId = ;
EASY_MEDIA_INFO_T mediainfo; int buf_size = *;
char *pbuf = (char *) malloc(buf_size);
FILE *fES = NULL;
int position = ;
int iFrameNo = ; WSADATA wsaData;
WSAStartup(MAKEWORD(,), &wsaData); memset(&mediainfo, 0x00, sizeof(EASY_MEDIA_INFO_T));
mediainfo.u32VideoCodec = 0x1C; fES = fopen("./EasyDarwin.264", "rb");
if (NULL == fES) return ; pusherId = EasyPusher_Create(); EasyPusher_SetEventCallback(pusherId, __EasyPusher_Callback, , NULL); EasyPusher_StartStream(pusherId, "127.0.0.1", , "live.sdp", "admin", "admin", &mediainfo, );
//printf("*** live streaming url:rtsp://115.29.139.20:554/live.sdp ***\n"); while ()
{
int nReadBytes = fread(pbuf+position, , , fES);
if (nReadBytes < )
{
if (feof(fES))
{
position = ;
fseek(fES, , SEEK_SET);
continue;
}
break;
} position ++; if (position > )
{
unsigned char naltype = ( (unsigned char)pbuf[position-] & 0x1F); if ( (unsigned char)pbuf[position-]== 0x00 &&
(unsigned char)pbuf[position-]== 0x00 &&
(unsigned char)pbuf[position-] == 0x00 &&
(unsigned char)pbuf[position-] == 0x01 &&
//(((unsigned char)pbuf[position-1] == 0x61) ||
//((unsigned char)pbuf[position-1] == 0x67) ) )
(naltype==0x07||naltype==0x01) )
{
int framesize = position - ;
EASY_AV_Frame avFrame; naltype = (unsigned char)pbuf[] & 0x1F; memset(&avFrame, 0x00, sizeof(EASY_AV_Frame));
avFrame.u32AVFrameLen = framesize;
avFrame.pBuffer = (unsigned char*)pbuf;
avFrame.u32VFrameType = (naltype==0x07)?EASY_SDK_VIDEO_FRAME_I:EASY_SDK_VIDEO_FRAME_P;
EasyPusher_PushFrame(pusherId, &avFrame); Sleep(); memmove(pbuf, pbuf+position-, );
position = ; iFrameNo ++; //if (iFrameNo > 100000) break;
//break;
}
}
} _TRACE("Press Enter exit...\n");
getchar();
EasyPusher_StopStream(pusherId);
EasyPusher_Release(pusherId); WSACleanup();
return ;
}
b. 推送Camera SDK回调的音视频数据,示例中的SDK是EasyDarwin开源摄像机的配套库,EasyCamera SDK及配套源码可在 http://www.easydarwin.org 或者 https://github.com/EasyDarwin/EasyCamera 获取到,也可以用自己项目中用到的SDK获取音视频数据进行推送;
/*
Copyright (c) 2013-2014 EasyDarwin.ORG. All rights reserved.
Github: https://github.com/EasyDarwin
WEChat: EasyDarwin
Website: http://www.EasyDarwin.org
*/
#define _CRTDBG_MAP_ALLOC
#include <stdio.h>
#include "EasyPusherAPI.h"
#include <winsock2.h>
#include "hi_type.h"
#include "hi_net_dev_sdk.h"
#include "hi_net_dev_errors.h"
#include "trace.h" #define UNAME "admin"
#define PWORD "admin"
#define DHOST "192.168.66.189" //EasyCamera摄像机IP地址
#define DPORT 80 //EasyCamera摄像机端口 #define SHOST "115.29.139.20" //EasyDarwin流媒体服务器地址
#define SPORT 554 //EasyDarwin流媒体服务器端口 HI_U32 u32Handle = ;
Easy_Pusher_Handle pusherHandle = ; HI_S32 OnEventCallback(HI_U32 u32Handle, /* 句柄 */
HI_U32 u32Event, /* 事件 */
HI_VOID* pUserData /* 用户数据*/
)
{
return HI_SUCCESS;
} HI_S32 NETSDK_APICALL OnStreamCallback(HI_U32 u32Handle, /* 句柄 */
HI_U32 u32DataType, /* 数据类型,视频或音频数据或音视频复合数据 */
HI_U8* pu8Buffer, /* 数据包含帧头 */
HI_U32 u32Length, /* 数据长度 */
HI_VOID* pUserData /* 用户数据*/
)
{ HI_S_AVFrame* pstruAV = HI_NULL;
HI_S_SysHeader* pstruSys = HI_NULL; if (u32DataType == HI_NET_DEV_AV_DATA)
{
pstruAV = (HI_S_AVFrame*)pu8Buffer; if (pstruAV->u32AVFrameFlag == HI_NET_DEV_VIDEO_FRAME_FLAG)
{
if(pusherHandle == )
return ; if(pstruAV->u32AVFrameLen > )
{
unsigned char* pbuf = (unsigned char*)(pu8Buffer+sizeof(HI_S_AVFrame));
unsigned char naltype = ( (unsigned char)pbuf[] & 0x1F); if ( (unsigned char)pbuf[]== 0x00 &&
(unsigned char)pbuf[]== 0x00 &&
(unsigned char)pbuf[] == 0x00 &&
(unsigned char)pbuf[] == 0x01 &&
(naltype==0x07 || naltype==0x01) )
{
EASY_AV_Frame avFrame; naltype = (unsigned char)pbuf[] & 0x1F;
memset(&avFrame, 0x00, sizeof(EASY_AV_Frame));
avFrame.u32AVFrameLen = pstruAV->u32AVFrameLen;
avFrame.pBuffer = (unsigned char*)pbuf;
avFrame.u32VFrameType = (naltype==0x07)?EASY_SDK_VIDEO_FRAME_I:EASY_SDK_VIDEO_FRAME_P;
EasyPusher_PushFrame(pusherHandle, &avFrame);
}
}
}
else
if (pstruAV->u32AVFrameFlag == HI_NET_DEV_AUDIO_FRAME_FLAG)
{
//printf("Audio %u PTS: %u \n", pstruAV->u32AVFrameLen, pstruAV->u32AVFramePTS);
//SaveRecordFile("Video.hx", pu8Buffer, u32Length);
}
}
else
if (u32DataType == HI_NET_DEV_SYS_DATA)
{
pstruSys = (HI_S_SysHeader*)pu8Buffer;
printf("Video W:%u H:%u Audio: %u \n", pstruSys->struVHeader.u32Width, pstruSys->struVHeader.u32Height, pstruSys->struAHeader.u32Format);
} return HI_SUCCESS;
} HI_S32 OnDataCallback(HI_U32 u32Handle, /* 句柄 */
HI_U32 u32DataType, /* 数据类型*/
HI_U8* pu8Buffer, /* 数据 */
HI_U32 u32Length, /* 数据长度 */
HI_VOID* pUserData /* 用户数据*/
)
{
return HI_SUCCESS;
} int __EasyPusher_Callback(int _id, EASY_PUSH_STATE_T _state, EASY_AV_Frame *_frame, void *_userptr)
{
if (_state == EASY_PUSH_STATE_CONNECTING) printf("Connecting...\n");
else if (_state == EASY_PUSH_STATE_CONNECTED) printf("Connected\n");
else if (_state == EASY_PUSH_STATE_CONNECT_FAILED) printf("Connect failed\n");
else if (_state == EASY_PUSH_STATE_CONNECT_ABORT) printf("Connect abort\n");
//else if (_state == EASY_PUSH_STATE_PUSHING) printf("P->");
else if (_state == EASY_PUSH_STATE_DISCONNECTED) printf("Disconnect.\n"); return ;
} int main()
{
HI_S32 s32Ret = HI_SUCCESS;
HI_S_STREAM_INFO struStreamInfo;
HI_U32 a; HI_NET_DEV_Init(); s32Ret = HI_NET_DEV_Login(&u32Handle, UNAME, PWORD, DHOST, DPORT);
if (s32Ret != HI_SUCCESS)
{
HI_NET_DEV_DeInit();
return -;
} //HI_NET_DEV_SetEventCallBack(u32Handle, OnEventCallback, &a);
HI_NET_DEV_SetStreamCallBack(u32Handle, (HI_ON_STREAM_CALLBACK)OnStreamCallback, &a);
//HI_NET_DEV_SetDataCallBack(u32Handle, OnDataCallback, &a); struStreamInfo.u32Channel = HI_NET_DEV_CHANNEL_1;
struStreamInfo.blFlag = HI_FALSE;//HI_FALSE;
struStreamInfo.u32Mode = HI_NET_DEV_STREAM_MODE_TCP;
struStreamInfo.u8Type = HI_NET_DEV_STREAM_ALL;
s32Ret = HI_NET_DEV_StartStream(u32Handle, &struStreamInfo);
if (s32Ret != HI_SUCCESS)
{
HI_NET_DEV_Logout(u32Handle);
u32Handle = ;
return -;
} WSADATA wsaData;
WSAStartup(MAKEWORD(,), &wsaData); EASY_MEDIA_INFO_T mediainfo; memset(&mediainfo, 0x00, sizeof(EASY_MEDIA_INFO_T));
mediainfo.u32VideoCodec = 0x1C; pusherHandle = EasyPusher_Create(); EasyPusher_SetEventCallback(pusherHandle, __EasyPusher_Callback, , NULL); EasyPusher_StartStream(pusherHandle, SHOST, SPORT, "live.sdp", "admin", "admin", &mediainfo, );
printf("*** live streaming url:rtsp://%s:%d/live.sdp ***\n", SHOST, SPORT); while()
{
Sleep();
}; EasyPusher_StopStream(pusherHandle);
EasyPusher_Release(pusherHandle);
pusherHandle = ; HI_NET_DEV_StopStream(u32Handle);
HI_NET_DEV_Logout(u32Handle); HI_NET_DEV_DeInit(); return ;
}
3) demo运行
先启动EasyDarwin服务器,然后启动EasyPusher,这里推送H264文件做测试

4)总结
重点:获取数据帧,发送数据帧,查找数据帧帧头。
end
EasyPusher应用的更多相关文章
- EasyPusher推流服务接口的.NET导出
本文是在使用由 EasyDarwin 团队开发的EasyPusher时导出的C++接口的.NET实现 public class EasyPushSDK { public EasyPushSDK() { ...
- 流媒体服务器+EasyDarwin+EasyPusher+VLC+Red5+OBS+Unity+RTSP+RTMP+FFMPEG
最近有个需求在Unity中直播桌面,着用到了视频流. ------------------------------ VLC自身有流服务器功能,但是非常慢非常慢,还是用VLC拉流吧,好像大家也是这么做的 ...
- EasyPusher RTSP推流/EasyRTMP RTMP推流Android安卓摄像头视频偏暗的问题解决方案
本文转自EasyDarwin团队成员JOHN的博客:http://blog.csdn.net/jyt0551/article/details/75730226 在我们测试EasyPusher/Easy ...
- EasyPusher安卓直播推流到EasyDarwin开源流媒体服务器工程简析
EasyPusher主要有三部分组件组成:采集,编码,叠加,上传.在这个基础上同时支持本地存储\后台预览的功能.主要业务模块与相关类之间的关系如图所示: Created with Raphaël 2. ...
- EasyPusher/EasyDarwin支持H.265 RTSP/RTP直播推流与分发播放
前言描述 随着大屏时代和高清时代的到来,人们已经不再满足于VGA.CIF这种小分辨率了,取而代之的是720P.1080P.4K级的视频传输,虽然我们国家的基础带宽一直在上升,但普遍情况下,传输高清视频 ...
- EasyPusher推流类库的.NET调用说明
EasyPusher推流类库的.NET调用说明 以下内容基于在使用EasyPusher过程中遇到的问题,以及相应的注意事项.本文主要是基于对C++类库的二次封装(便于调试发现问题)以供C#调用以及对一 ...
- C#调用EasyPusher推送到EasyDarwin实现视频流中转
本文转自:http://www.cnblogs.com/kangkey/p/6772863.html 最近在公司项目中,遇到需要将内网的监控视频信息,在外网进行查看,最终通过查阅资料,发现EasyDa ...
- C#调用EasyPusher推送到EasyDarwin流媒体服务器直播方案及示例代码整理
博客一:转自:http://blog.csdn.net/u011039529/article/details/70832857 大家好,本人刚毕业程序猿一枚.受人所托,第一次写博客,如有错误之处敬请谅 ...
- EasyPusher进行Android UVC外接摄像头直播推送实现方法
最近EasyPusher针对UVC摄像头做了适配.我们结合了UVCCamera与EasyPusher,支持将UVC摄像头的视频推送到RTSP服务器上.在此特别感谢UVCCamera这个牛逼的项目! 来 ...
随机推荐
- Storm中遇到的日志多次重写问题(一)
业务描述: 统计从kafka spout中读取的数据条数,以及写入redis的数据的条数,写入hdfs的数据条数,写入kafaka的数据条数.并且每过5秒将数据按照json文件的形式写入日志.其中保存 ...
- jquery的几个常用方法
第一部份关键词: .bind() .unbind() .css() .hasclass() .removeclass .parent() .children() .html() .hide() .sh ...
- CSS3文字渐变效果
background-clip + text-fill-color下的实现 如果您手头上的浏览器是Chrome或是Safari,则您可以在demo页面中看到类似下面的效果: <h2 class= ...
- tomcat 8.5.9.0 解决catalina.out过大的问题
先吐嘈一下tomcat这个项目,日志切割这么常见的功能,tomcat这种知名开源项目默认居然不开启,生产环境跑不了几天,磁盘就满了,而且很多网上流传的方法,比如修改conf/logging.prope ...
- [LeetCode] Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历
Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...
- [LeetCode] Restore IP Addresses 复原IP地址
Given a string containing only digits, restore it by returning all possible valid IP address combina ...
- JavaScript检测对象的类属性
function classof(o) { if(o === null) { return "Null"; } if(o === undefined) { return " ...
- 安装Anaconda
安装Anaconda来安装一切 spyder是python科学计算IDE,类似matlab.这是一个基于Qt的软件,如果使用pip install安装,会出现各种bug.pip install spy ...
- WebAPI中无法获取Session对象的解决办法
在MVC的WebApi中默认是没有开启Session会话支持的.需要在Global中重写Init方法来指定会话需要支持的类型 public override void Init() { PostAut ...
- IOS比较常用的第三方组件及应用源代码(持续更新中)
把平时看到或项目用到的一些插件进行整理,文章后面分享一些不错的实例,若你有其它的插件欢迎分享,不断的进行更新~ 一:第三方插件 1:基于响应式编程思想的oc 地址:https://github.com ...