Easypusher接口推送RTP数据
来源:互联网 发布:淘宝找优惠券怎么赚钱 编辑:程序博客网 时间:2024/05/22 03:43
最近在整合asterisk系统的视频通话录像功能,开始使用mp4v2库直接在asterisk系统中进行mp4视频文件的生成,测试发现性能上存在瓶颈,只能做到50路(双向即100个mp4文件)左右的并发通话的mp4文件生成,初步分析问题主要在写文件上,鉴于此,希望能把RTP流送出到别的服务中进行录制。在网上查找了相关的流媒体服务,发现easydarwin比较适合我们当前的应用场景,准备使用其作为我们的流媒体服务器使用,把对接过程所遇到的问题进行记录,希望对有这方面应用的XDJM有一定的帮助。
一、环境说明:
1、EasyDarwin版本:Server: EasyDarwin/7.0.5 (Build/16.0518; Platform/Win32; Release/EasyDarwin; State/Development; )
下载地址:https://github.com/EasyDarwin/EasyDarwin/releases
2、Easypusher静态库版本:v1.2.16.1105
静态库下载地址:https://github.com/EasyDarwin/EasyPusher
3、Asterisk版本:Asterisk 1.8.20.1 built (自行到官网下载一个能用的版本应该都行)
4、
二、源码:
isActivated = EasyPusher_Activate(KEY);/* 目前用到.a库的话,需要临时授权*/
switch(isActivated)
{
case EASY_ACTIVATE_INVALID_KEY:
ast_log(LOG_DEBUG, "KEY is EASY_ACTIVATE_INVALID_KEY!\n");
break;
case EASY_ACTIVATE_TIME_ERR:
ast_log(LOG_DEBUG, "KEY is EASY_ACTIVATE_TIME_ERR!\n");
break;
case EASY_ACTIVATE_PROCESS_NAME_LEN_ERR:
ast_log(LOG_DEBUG, "KEY is EASY_ACTIVATE_PROCESS_NAME_LEN_ERR!\n");
break;
case EASY_ACTIVATE_PROCESS_NAME_ERR:
ast_log(LOG_DEBUG, "KEY is EASY_ACTIVATE_PROCESS_NAME_ERR!\n");
break;
case EASY_ACTIVATE_VALIDITY_PERIOD_ERR:
ast_log(LOG_DEBUG, "KEY is EASY_ACTIVATE_VALIDITY_PERIOD_ERR!\n");
break;
case EASY_ACTIVATE_SUCCESS:
ast_log(LOG_DEBUG, "KEY is EASY_ACTIVATE_SUCCESS!\n");
break;
}
if(EASY_ACTIVATE_SUCCESS != isActivated)
{
ast_log(LOG_ERROR, "EasyPusher_Activate : NOT EASY_ACTIVATE_SUCCESS\n");
//return -1;
}
memset(&fSourceMediaInfo, 0x00, sizeof(EASY_MEDIA_INFO_T));
fSourceMediaInfo.u32VideoCodec = EASY_SDK_VIDEO_CODEC_H264;// fSourceMediaInfo.u32VideoFps = 25; //
/*711语音处理*/
fSourceMediaInfo.u32AudioCodec = 0x10007;//EASY_SDK_AUDIO_CODEC_G711A;
fSourceMediaInfo.u32AudioSamplerate = 8000;
fSourceMediaInfo.u32AudioChannel = 1;
fPusherHandle = EasyPusher_Create();
fPusherBuff = malloc(2048*1024);
If (NULL == fPusherBuff )
Return -1;
memset(fPusherBuff, 0, 2048*1024);
EasyPusher_SetEventCallback(fPusherHandle, __EasyPusher_Callback, 0, NULL);
EasyPusher_StartStream(fPusherHandle, ConfigIP, atoi(ConfigPort), ConfigName, "admin", "admin", &fSourceMediaInfo, 2048, 0);//2M缓冲区
ast_log(LOG_WARNING, "*** live streaming url:rtsp://%s:%d/%s ***\n", ConfigIP, atoi(ConfigPort), ConfigName);
bfile=fopen("/Data/h264test.264", "at+");/*调试用,写h264裸文件*/
{
now = ast_tvnow();
if( (f->frametype == AST_FRAME_VOICE) && spsflag )// spsflag: 先写入视频数据
{
EASY_AV_Frame avoiceFrame;
if(f->subclass.codec & AST_FORMAT_ALAW)// 例子里只处理ALAW语音,实际看接口,还支持ULAW、G726、AAC
{
//ast_log(LOG_WARNING, "AST_FORMAT_ALAW f->datalen[%d]\n", f->datalen);
memset(&avoiceFrame, 0x00, sizeof(EASY_AV_Frame));
avoiceFrame.u32AVFrameLen = f->datalen ;
avoiceFrame.pBuffer =AST_FRAME_GET_BUFFER(f) ;/* RTP包中的771裸数据,即RTP包中的PAYLOAD数据*/
avoiceFrame.u32AVFrameFlag = EASY_SDK_AUDIO_FRAME_FLAG;
avoiceFrame.u32TimestampSec =now.tv_sec;
avoiceFrame.u32TimestampUsec = now.tv_usec;
EasyPusher_PushFrame(fPusherHandle, &avoiceFrame);
}
}
else if (f->frametype == AST_FRAME_VIDEO) //写入视频数据
{
if (f->subclass.codec & AST_FORMAT_H264)
{
EASY_AV_Frame avideoFrame;
unsigned char *frame = NULL;
unsigned char ttype ;
unsigned char h264_hdr[4] = {0};
frame = AST_FRAME_GET_BUFFER(f);/* RTP包中的h264裸数据,即RTP包中的PAYLOAD数据*/
ttype = (unsigned char)frame[0] & 0x1F;
memset(&avideoFrame, 0x00, sizeof(EASY_AV_Frame));
avideoFrame.u32TimestampSec = now.tv_sec;
avideoFrame.u32TimestampUsec = now.tv_usec;
h264_hdr[3] |= 0x1;
/* 只有是SPS和P帧才去调用API发送;否则会出现easydarwin保存成文件后,播放不出来的问题(直播不存在问题),具体原因不明确*/
if ((0x7 == ttype) || (0x1 == ttype))
{
spsflag += 1;
if (spsflag >1)
{
fwrite(h264_hdr, 4, 1, bfile);
fwrite(AST_FRAME_GET_BUFFER(f), 1, f->datalen, bfile);
ttype = (unsigned char)fPusherBuff[4] & 0x1F;
avideoFrame.u32VFrameType = (ttype==0x07)?EASY_SDK_VIDEO_FRAME_I:EASY_SDK_VIDEO_FRAME_P;
avideoFrame.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;
avideoFrame.u32AVFrameLen = fPusherBuffOffset;
avideoFrame.pBuffer = fPusherBuff;
spsflag = 1;
EasyPusher_PushFrame(fPusherHandle, &avideoFrame);
fPusherBuffOffset = 0;
memset(fPusherBuff, 0, 2048*1024);
memcpy(fPusherBuff+fPusherBuffOffset, h264_hdr, 4);
fPusherBuffOffset += 4;
memcpy(fPusherBuff+fPusherBuffOffset , AST_FRAME_GET_BUFFER(f), f->datalen);
fPusherBuffOffset += f->datalen;
}
else
{
/*调试用,写h264裸文件*/
fwrite(h264_hdr, 4, 1, bfile);
fwrite(AST_FRAME_GET_BUFFER(f), 1, f->datalen, bfile);
memcpy(fPusherBuff+fPusherBuffOffset, h264_hdr, 4);
fPusherBuffOffset += 4;
memcpy(fPusherBuff+fPusherBuffOffset , AST_FRAME_GET_BUFFER(f), f->datalen);
fPusherBuffOffset += f->datalen;
}
}
else
{
fwrite(h264_hdr, 4, 1, bfile);/*调试用,写h264裸文件*/
fwrite(AST_FRAME_GET_BUFFER(f), 1, f->datalen, bfile);
memcpy(fPusherBuff+fPusherBuffOffset, h264_hdr, 4);
fPusherBuffOffset += 4;
memcpy(fPusherBuff+fPusherBuffOffset , AST_FRAME_GET_BUFFER(f), f->datalen);
fPusherBuffOffset += f->datalen;
}
}
}
}
三、参考:
1、利用EasyRTSPClient工具检查摄像机RTSP流不能播放原因以及排查音视频数据无法播放问题:http://blog.csdn.net/xiejiashu/article/details/53105103
2、H264裸数据推送参考:https://github.com/EasyDarwin/EasyPusher 解压后的EasyPusher_File目录
四、感谢:
非常感谢在调测试过程中,Babosa大神给予的指点,具体问题可以在EasyDarwin开源流媒体服务器QQ群中提出:496258327(群)
五、后续:
后续会针对并发性能做个测试,有新进展的话贴出分享受给大家
- Easypusher接口推送RTP数据
- EasyPusher如何推送纯音频RTSP流媒体数据
- EasyPusher Android实时推送当前屏幕画面
- Android UVC外接摄像头推送-EasyPusher
- live555 播放视频 play 不能推送rtp数据
- EasyPusher RTSP直播之RTP数据包格式解析
- 基于EasyDarwin EasyPusher实现Android手机直播推送功能
- C#调用EasyPusher推送到EasyDarwin实现视频流中转
- EasyPusher Android工程RTSP流媒体推送简析
- EasyPusher进行Android UVC外接摄像头直播推送实现方法
- EasyPusher手机直播推送是如何实现后台直播推送的
- EasyPusher/EasyDarwin支持H.265 RTSP/RTP直播推流与分发播放
- RTP转CTP 接口
- EasyPusher:基于live555的DarwinInjector实现的RTSP直播推送程序
- EasyPusher安卓Android手机直播推送之MediaCodec 硬编码H264格式
- EasyPusher安卓Android手机直播推送之MediaCodec 硬编码H264格式
- EasyPusher安卓Android手机直播推送之RTSP流媒体协议流程
- EasyPusher安卓Android手机直播推送之MediaCodec 硬编码H264格式
- 实际工作用到的:同店换房时计算老房间费用
- codevs 1201 最小数和最大数
- 【OAuth2.0网页授权】根据access_token和openId获取用户基本信息(Senparc.Weixin.MP.dll)
- C++中类的继承访问特性
- ORB特征提取与匹配
- Easypusher接口推送RTP数据
- 剑指offer 面试题8 旋转数组的最小值 java版答案
- Android解决多个Fragment切换时布局重新实例化问题
- 多文件组织词法分析
- 初学者该如何选择编程语言呢?
- 【Android Studio安装配置教程】二、配置
- 线段树初步
- 【HDU】-1005-Number Sequence(数学,规律)
- EXCEL大批量导入2007版本的实现(100W可执行)