转自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应用的更多相关文章

  1. EasyPusher推流服务接口的.NET导出

    本文是在使用由 EasyDarwin 团队开发的EasyPusher时导出的C++接口的.NET实现 public class EasyPushSDK { public EasyPushSDK() { ...

  2. 流媒体服务器+EasyDarwin+EasyPusher+VLC+Red5+OBS+Unity+RTSP+RTMP+FFMPEG

    最近有个需求在Unity中直播桌面,着用到了视频流. ------------------------------ VLC自身有流服务器功能,但是非常慢非常慢,还是用VLC拉流吧,好像大家也是这么做的 ...

  3. EasyPusher RTSP推流/EasyRTMP RTMP推流Android安卓摄像头视频偏暗的问题解决方案

    本文转自EasyDarwin团队成员JOHN的博客:http://blog.csdn.net/jyt0551/article/details/75730226 在我们测试EasyPusher/Easy ...

  4. EasyPusher安卓直播推流到EasyDarwin开源流媒体服务器工程简析

    EasyPusher主要有三部分组件组成:采集,编码,叠加,上传.在这个基础上同时支持本地存储\后台预览的功能.主要业务模块与相关类之间的关系如图所示: Created with Raphaël 2. ...

  5. EasyPusher/EasyDarwin支持H.265 RTSP/RTP直播推流与分发播放

    前言描述 随着大屏时代和高清时代的到来,人们已经不再满足于VGA.CIF这种小分辨率了,取而代之的是720P.1080P.4K级的视频传输,虽然我们国家的基础带宽一直在上升,但普遍情况下,传输高清视频 ...

  6. EasyPusher推流类库的.NET调用说明

    EasyPusher推流类库的.NET调用说明 以下内容基于在使用EasyPusher过程中遇到的问题,以及相应的注意事项.本文主要是基于对C++类库的二次封装(便于调试发现问题)以供C#调用以及对一 ...

  7. C#调用EasyPusher推送到EasyDarwin实现视频流中转

    本文转自:http://www.cnblogs.com/kangkey/p/6772863.html 最近在公司项目中,遇到需要将内网的监控视频信息,在外网进行查看,最终通过查阅资料,发现EasyDa ...

  8. C#调用EasyPusher推送到EasyDarwin流媒体服务器直播方案及示例代码整理

    博客一:转自:http://blog.csdn.net/u011039529/article/details/70832857 大家好,本人刚毕业程序猿一枚.受人所托,第一次写博客,如有错误之处敬请谅 ...

  9. EasyPusher进行Android UVC外接摄像头直播推送实现方法

    最近EasyPusher针对UVC摄像头做了适配.我们结合了UVCCamera与EasyPusher,支持将UVC摄像头的视频推送到RTSP服务器上.在此特别感谢UVCCamera这个牛逼的项目! 来 ...

随机推荐

  1. 关于在安装MySQL时报错"本地计算机上的mysql服务启动后停止,某些服务在未由其他服务或程序使用时将自动停止"的解决方法

    首先将你下载的MySQL安装或者解压(对应安装版和解压版),下载地址http://dev.mysql.com/downloads/mysql/ 然后复制你安装目录中的my-default.ini,更改 ...

  2. nginx 网站搭建

    nginx目录详解 默认nginx做了nginx配置文件的备份 #查看nginx配置文件去掉#号的内容,并且追加到nginx.conf.tmp egrep -v "#|^$" ng ...

  3. C语言运算符优先级

    优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 -- () 圆括号 (表达式)/函数名(形参表) -- . 成员选择(对象) 对象.成员名 -- ...

  4. 开发常用图标png、ico 图标下载

    推荐几个不错的下载地址: 1.http://www.easyicon.net/ 2.http://588ku.com/sucai/ 3.http://www.iconpng.com 可直接下载png等 ...

  5. 【Pyrosim案例】01:空气流动

    1 案例说明 Pyrosim是一款FDS前后处理软件.以一个非常简单的案例来描述Pyrosim的工作流程.本案例计算域中包含一个空气入口,一个环境出口. 案例主要演示以下内容: 创建Vents 增加切 ...

  6. Dubbo学习之简单环境搭建

    Dubbo服务的发展和作用: 首先,看下一般网站架构随着业务的发展,逻辑越来越复杂,数据量越来越大,交互越来越多之后的常规方案演进历程. 其次,当服务越来越多之后,我们需要做哪些服务治理? 最后,是d ...

  7. Spring基础

    一.Spring作用:管理项目中各种业务Bean(service类.Dao类.Action类),实例化类,属性赋值 二.Spring IOC(Inversion of Control )控制反转,也被 ...

  8. vi安装Vundle+YouCompleteMe+注释快捷'scrooloose/nerdcommenter'

    Vundle is short for Vim bundle and is a Vim plugin manager. 从git上下载vundle $ git clone https://github ...

  9. 部署 DevStack - 每天5分钟玩转 OpenStack(17)

    本节按照以下步骤部署 DevStack 实验环境,包括控制节点和计算节点 创建虚拟机 按照物理资源需求创建 devstack-controller 和 devstak-compute 虚拟机 安装操作 ...

  10. [LeetCode] Word Search II 词语搜索之二

    Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...