分享

安防网络摄像机推送到RTMP流媒体服务器方案

 WindySky 2018-03-05


RTMP流媒体服务器一般只接收RTMP格式的推流。目前市场上有一些自带RTMP推流的摄像机和编码器,可以直接在其配置里面配置推送到RTMP流媒体服务器上。但是大部分的安防网络摄像机还不带推流功能,对于这种摄像机只能通过自己动手开发出获取摄像机实时视频流并封装成RTMP格式推送给流媒体服务器了。
获取摄像机实时视频流的方式可以调用摄像机的SDK,也可以通过拉取摄像机的RTSP实时流来获取。对于调用SDK获取视频流的方式因为不同厂家、不同型号的设备SDK都不同,所以这种方式获取流不够通用。这样就建议使用拉取摄像机RTSP流,然后转成RTMP推送给RTMP流媒体服务器,可以适应基本所有的网络摄像机。

拉取摄像机RTSP流

这里使用EasyRTSPClient库拉取RTSP流,非常简单易用,接口如下:

/*
    _channelId:     通道号,暂时不用
    _channelPtr:    通道对应对象,暂时不用
    _frameType:     EASY_SDK_VIDEO_FRAME_FLAG/EASY_SDK_AUDIO_FRAME_FLAG/EASY_SDK_EVENT_FRAME_FLAG/...   
    _pBuf:          回调的数据部分,具体用法看Demo
    _frameInfo:     帧结构数据
*/
typedef int (Easy_APICALL *RTSPSourceCallBack)( int _channelId, void *_channelPtr, int _frameType, char *pBuf, RTSP_FRAME_INFO* _frameInfo);

#ifdef __cplusplus
extern "C"
{
#endif
    /* 获取最后一次错误的错误码 */
    Easy_API int Easy_APICALL EasyRTSP_GetErrCode(Easy_RTSP_Handle handle);

    /* 激活 */
#ifdef ANDROID
    Easy_API int Easy_APICALL EasyRTSP_Activate(char *license, char* userPtr);
#else
    Easy_API int Easy_APICALL EasyRTSP_Activate(char *license);
#endif

    /* 创建RTSPClient句柄  返回0表示成功,返回非0表示失败 */
    Easy_API int Easy_APICALL EasyRTSP_Init(Easy_RTSP_Handle *handle);

    /* 释放RTSPClient 参数为RTSPClient句柄 */
    Easy_API int Easy_APICALL EasyRTSP_Deinit(Easy_RTSP_Handle *handle);

    /* 设置数据回调 */
    Easy_API int Easy_APICALL EasyRTSP_SetCallback(Easy_RTSP_Handle handle, RTSPSourceCallBack _callback);

    /* 打开网络流 */
    Easy_API int Easy_APICALL EasyRTSP_OpenStream(Easy_RTSP_Handle handle, int _channelid, char *_url, EASY_RTP_CONNECT_TYPE _connType, unsigned int _mediaType, char *_username, char *_password, void *userPtr, int _reconn/*1000表示长连接,即如果网络断开自动重连, 其它值为连接次数*/, int outRtpPacket/*默认为0,即回调输出完整的帧, 如果为1,则输出RTP包*/, int heartbeatType/*0x00:不发送心跳 0x01:OPTIONS 0x02:GET_PARAMETER*/, int _verbosity/*日志打印输出等级,0表示不输出*/);

    /* 关闭网络流 */
    Easy_API int Easy_APICALL EasyRTSP_CloseStream(Easy_RTSP_Handle handle);

#ifdef __cplusplus
}
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

各个平台调用Demo参考https://github.com/EasyDSS/EasyRTSPClient。EasyRTSPClient拉取RTSP流,输出实时的视频H264流和音频流。

调用流程

推送RTMP流给流媒体服务器

通过EasyRTSPClient库已经可以获取摄像机实时的视频和音频流, 再通过调用EasyRTMP库可以直接将这些数据自带封装成RTMP格式推送给服务器。

typedef struct __EASY_AV_Frame
{
    Easy_U32    u32AVFrameFlag;     /* 帧标志  视频 or 音频 */
    Easy_U32    u32AVFrameLen;      /* 帧的长度 */
    Easy_U32    u32VFrameType;      /* 视频的类型,I帧或P帧 */
    Easy_U8     *pBuffer;           /* 数据 */
    Easy_U32    u32TimestampSec;    /* 时间戳(秒)*/
    Easy_U32    u32TimestampUsec;   /* 时间戳(微秒) */
}EASY_AV_Frame;

/* 推送事件类型定义 */
typedef enum __EASY_RTMP_STATE_T
{
    EASY_RTMP_STATE_CONNECTING   =   1,     /* 连接中 */
    EASY_RTMP_STATE_CONNECTED,              /* 连接成功 */
    EASY_RTMP_STATE_CONNECT_FAILED,         /* 连接失败 */
    EASY_RTMP_STATE_CONNECT_ABORT,          /* 连接异常中断 */
    EASY_RTMP_STATE_PUSHING,                /* 推流中 */
    EASY_RTMP_STATE_DISCONNECTED,           /* 断开连接 */
    EASY_RTMP_STATE_ERROR
}EASY_RTMP_STATE_T;

/*
    _frameType:     EASY_SDK_VIDEO_FRAME_FLAG/EASY_SDK_AUDIO_FRAME_FLAG/EASY_SDK_EVENT_FRAME_FLAG/...   
    _pBuf:          回调的数据部分,具体用法看Demo
    _frameInfo:     帧结构数据
    _userPtr:       用户自定义数据
*/
typedef int (*EasyRTMPCallBack)(int _frameType, char *pBuf, EASY_RTMP_STATE_T _state, void *_userPtr);

#ifdef __cplusplus
extern "C" 
{
#endif
    /* 激活EasyRTMP */
#ifdef ANDROID
    EasyRTMP_API Easy_I32 Easy_APICALL EasyRTMP_Activate(char *license, char* userPtr);
#else
    EasyRTMP_API Easy_I32 Easy_APICALL EasyRTMP_Activate(char *license);
#endif

    /* 创建RTMP推送Session 返回推送句柄 */
    EasyRTMP_API Easy_RTMP_Handle Easy_APICALL EasyRTMP_Create(void);

    /* 设置数据回调 */
    EasyRTMP_API Easy_I32 Easy_APICALL EasyRTMP_SetCallback(Easy_RTMP_Handle handle, EasyRTMPCallBack _callback, void * _userptr);

    /* 创建RTMP推送的参数信息 */
    EasyRTMP_API Easy_I32 Easy_APICALL Easy_APICALL EasyRTMP_InitMetadata(Easy_RTMP_Handle handle, EASY_MEDIA_INFO_T*  pstruStreamInfo, Easy_U32 bufferKSize);

    /* 连接RTMP服务器 */
    EasyRTMP_API Easy_Bool Easy_APICALL EasyRTMP_Connect(Easy_RTMP_Handle handle, const char *url);

    /* 推送H264或AAC流 */
    EasyRTMP_API Easy_U32 Easy_APICALL EasyRTMP_SendPacket(Easy_RTMP_Handle handle, EASY_AV_Frame* frame);

    /* 停止RTMP推送,释放句柄 */
    EasyRTMP_API void Easy_APICALL EasyRTMP_Release(Easy_RTMP_Handle handle);

#ifdef __cplusplus
};
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

在EasyRTSPClient的回调函数中将实时数据通过EasyRTMP库的EasyRTMP_SendPacket接口推送出去即可。EasyRTMP SDK在https://github.com/EasyDSS/EasyRTMP。参考其中的EasyRTMP_RTSP例子,就是实现的拉取一路摄像机RTSP视频流并以RTMP推送出去的Demo。需要同时拉取多路视频并推送的Demo可以参考https://github.com/jinlong0813/RTMPLive

总结

EasyRTSPClient与EasyRTMP SDK都是支持Windows、Linux、Android、iOS多个平台的,可以实现在各个平台上推送RTMP给流媒体服务器。两个SDK都避开了RTSP及RTMP等格式的繁琐流程,直接简单调用接口就可以轻松实现流媒体直播推送。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多