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这个牛逼的项目! 来 ...
随机推荐
- ASP.NET MVC 初体验
MVC系列文章终于开始了,前段时间公司项目结束后一直在封装一个html+ashx+js+easyui的权限系统,最近差不多也完成了,迟些时候会分享源码给大家.当然这个MVC系列结束后如果时间允许还会另 ...
- Masonry和FDTemplateLayoutCell 结合使用示例Demo
我们知道,界面布局可以用Storyboard或Xib结合Autolayout实现,如果用纯代码布局,比较热门的有Masonry.SDAutoLayout,下面的简单demo,采用纯代码布局,实现不定高 ...
- RHEL6和RHEL7恢复root用户密码
一.RHEL6恢复root密码 将系统重启,出现如下界面按上下键选择会停住,并输入e键 选中下图红框选项,再输入e键 再输入1,进入单用户模式 输入b进行启动 修改密码,然后重启 二.RHEL7恢 ...
- Strust OGNL详解
首先了解下OGNL的概念: OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的 ...
- python_接口开发
一.GET和POST请求from flask import Flask,jsonifydata = { 'name':'Jerry', 'sex':'男', 'age':'18'}app = Flas ...
- [LeetCode] Reconstruct Original Digits from English 从英文中重建数字
Given a non-empty string containing an out-of-order English representation of digits 0-9, output the ...
- [LeetCode] Moving Average from Data Stream 从数据流中移动平均值
Given a stream of integers and a window size, calculate the moving average of all integers in the sl ...
- 从点云到网格(三)Poisson重建
Possion重建是Kazhdan等2006年提出的网格重建方法[1].Possion重建的输入是点云及其法向量,输出是三维网格.Poisson有公开的源代码[2].PCL中也有Poisson的实现. ...
- IT培训行业揭秘(一)
最近一个多月来,身边有很多朋友问我,我家孩子明年就要大学毕业了,现在工作还没有着落,最近孩子回家经常和我说,他们学校最近来了很多IT培训班,让同学们参加培训,然后各个培训班动辄拿出往届他们的培训学生赚 ...
- Gulp 入门
1. 安装 Node 环境 参考 http://www.cnblogs.com/zichi/p/4627728.html,注意一起安装 npm 工具,并把路径保存到环境变量中(安装过程中会有提醒) 安 ...