zoukankan      html  css  js  c++  java
  • 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...
    ");
        else if (_state == EASY_PUSH_STATE_CONNECTED)           printf("Connected
    ");
        else if (_state == EASY_PUSH_STATE_CONNECT_FAILED)      printf("Connect failed
    ");
        else if (_state == EASY_PUSH_STATE_CONNECT_ABORT)       printf("Connect abort
    ");
        else if (_state == EASY_PUSH_STATE_PUSHING)             printf("P->");
        else if (_state == EASY_PUSH_STATE_DISCONNECTED)        printf("Disconnect.
    ");
    
        return 0;
    }
    
    int main()
    {
        char szIP[16] = {0};
        Easy_Pusher_Handle pusherId = 0;
        EASY_MEDIA_INFO_T   mediainfo;
    
        int buf_size = 1024*512;
        char *pbuf = (char *) malloc(buf_size);
        FILE *fES = NULL;
        int position = 0;
        int iFrameNo = 0;
    
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2,2), &wsaData);
    
        memset(&mediainfo, 0x00, sizeof(EASY_MEDIA_INFO_T));
        mediainfo.u32VideoCodec =   0x1C;
    
        fES = fopen("./EasyDarwin.264", "rb");
        if (NULL == fES)        return 0;
    
        pusherId = EasyPusher_Create();
    
        EasyPusher_SetEventCallback(pusherId, __EasyPusher_Callback, 0, NULL);
    
        EasyPusher_StartStream(pusherId, "127.0.0.1", 554, "live.sdp", "admin", "admin", &mediainfo, 512);
        //printf("*** live streaming url:rtsp://115.29.139.20:554/live.sdp ***
    ");
    
        while (1)
        {
            int nReadBytes = fread(pbuf+position, 1, 1, fES);
            if (nReadBytes < 1)
            {
                if (feof(fES))
                {
                    position = 0;
                    fseek(fES, 0, SEEK_SET);
                    continue;
                }
                break;
            }
    
            position ++;
    
            if (position > 5)
            {
                unsigned char naltype = ( (unsigned char)pbuf[position-1] & 0x1F);
    
                if ( (unsigned char)pbuf[position-5]== 0x00 && 
                        (unsigned char)pbuf[position-4]== 0x00 && 
                        (unsigned char)pbuf[position-3] == 0x00 &&
                        (unsigned char)pbuf[position-2] == 0x01 &&
                        //(((unsigned char)pbuf[position-1] == 0x61) ||
                        //((unsigned char)pbuf[position-1] == 0x67) ) )
                        (naltype==0x07||naltype==0x01) )
                {
                    int framesize = position - 5;
                    EASY_AV_Frame   avFrame;
    
                    naltype = (unsigned char)pbuf[4] & 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(30);
    
                    memmove(pbuf, pbuf+position-5, 5);
                    position = 5;
    
                    iFrameNo ++;
    
                    //if (iFrameNo > 100000) break;
                    //break;
                }
            }
        }
    
        _TRACE("Press Enter exit...
    ");
        getchar();
        EasyPusher_StopStream(pusherId);
        EasyPusher_Release(pusherId);
    
    
    
    
    
        WSACleanup();
        return 0;
    }

    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 = 0;
    Easy_Pusher_Handle pusherHandle = 0;
    
    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 == 0 )
                    return 0;
    
                if(pstruAV->u32AVFrameLen > 5)
                {
                    unsigned char* pbuf = (unsigned char*)(pu8Buffer+sizeof(HI_S_AVFrame));
                    unsigned char naltype = ( (unsigned char)pbuf[4] & 0x1F);
    
                    if ( (unsigned char)pbuf[0]== 0x00 && 
                            (unsigned char)pbuf[1]== 0x00 && 
                            (unsigned char)pbuf[2] == 0x00 &&
                            (unsigned char)pbuf[3] == 0x01 &&
                            (naltype==0x07 || naltype==0x01) )
                    {
                        EASY_AV_Frame  avFrame;
    
                        naltype = (unsigned char)pbuf[4] & 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 
    ", 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 
    ", 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...
    ");
        else if (_state == EASY_PUSH_STATE_CONNECTED)           printf("Connected
    ");
        else if (_state == EASY_PUSH_STATE_CONNECT_FAILED)      printf("Connect failed
    ");
        else if (_state == EASY_PUSH_STATE_CONNECT_ABORT)       printf("Connect abort
    ");
        //else if (_state == EASY_PUSH_STATE_PUSHING)             printf("P->");
        else if (_state == EASY_PUSH_STATE_DISCONNECTED)        printf("Disconnect.
    ");
    
        return 0;
    }
    
    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 -1;
        }
        
        //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 = 0;
            return -1;
        }    
        
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2,2), &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, 0, NULL);
    
        EasyPusher_StartStream(pusherHandle, SHOST, SPORT, "live.sdp", "admin", "admin", &mediainfo, 512);
        printf("*** live streaming url:rtsp://%s:%d/live.sdp ***
    ", SHOST, SPORT);
    
        while(1)
        {
            Sleep(10);    
        };
    
        EasyPusher_StopStream(pusherHandle);
        EasyPusher_Release(pusherHandle);
        pusherHandle = 0;
       
        HI_NET_DEV_StopStream(u32Handle);
        HI_NET_DEV_Logout(u32Handle);
        
        HI_NET_DEV_DeInit();
    
        return 0;
    }

    3) demo运行

    先启动EasyDarwin服务器,然后启动EasyPusher,这里推送H264文件做测试

    4)总结

    重点:获取数据帧,发送数据帧,查找数据帧帧头。

    end

  • 相关阅读:
    Redis的发布订阅
    Redis的事物
    Redis的持久化
    Redis配置文件详解
    Redis五大数据类型
    Redis安装
    DP练习题回顾
    基环树浅谈
    Tarjan算法浅谈
    拓展欧拉定理浅谈
  • 原文地址:https://www.cnblogs.com/dong1/p/6014572.html
Copyright © 2011-2022 走看看