zoukankan      html  css  js  c++  java
  • EasyRTMP实现将RTSP流转换成RTMP流实现RTSP直播转RTMP直播的功能

    本文转自EasyDarwin开源团队Kim的博客:http://blog.csdn.net/jinlong0603/article/details/52951311

    EasyRTMP

    EasyRTMP封装了RTMP协议,提供了一套非常简单易用的接口调用SDK,Github上有多个基于EasyRTMP SDK的Demo。Git地址:https://github.com/EasyDarwin/EasyRTMP, Demo中EasyRTMP_RTSP项目是将RTSP流获取到本地进行RTMP推送,可进行RTMP直播。

    RTSP视频源进行RTMP直播

    目前安防项目上,基本都是RTSP流,无法接入RTMP服务器。
    EasyRTMP_RTSP Demo中通过libEasyRTSPClient库将RTSP数据流获取到本地,再讲获取来的音视频数据送给libEasyRTMP进行RTMP推送。如果获取来的数据不是AAC格式,而是G711、G726、PCM等格式,可以使用EasyDarwin团队提供的开源的EasyAACEncoder将音频数据转换成AAC格式再推送。这样可以实现将RTSP视频源实时的进行RTMP协议直播。

    /* NVSource从RTSPClient获取数据后回调给上层 */
    int Easy_APICALL __RTSPSourceCallBack( int _chid, void *_chPtr, int _mediatype, char *pbuf, RTSP_FRAME_INFO *frameinfo)
    {
        if (NULL != frameinfo)
        {
            if (frameinfo->height==1088)        frameinfo->height=1080;
            else if (frameinfo->height==544)    frameinfo->height=540;
        }
        Easy_Bool bRet = 0;
        int iRet = 0;
    
        //目前只处理视频
        if (_mediatype == EASY_SDK_VIDEO_FRAME_FLAG)
        {
            if(frameinfo && frameinfo->length)
            {
                if( frameinfo->type == EASY_SDK_VIDEO_FRAME_I)
                {
                    if(g_rtmpPusher.rtmpHandle == 0)
                    {
                        g_rtmpPusher.rtmpHandle = EasyRTMP_Create();
    
                        bRet = EasyRTMP_Connect(g_rtmpPusher.rtmpHandle, SRTMP);
                        if (!bRet)
                        {
                            printf("Fail to EasyRTMP_Connect ...
    ");
                        }
    
                        EASY_MEDIA_INFO_T mediaInfo;
                        memset(&mediaInfo, 0, sizeof(EASY_MEDIA_INFO_T));
                        mediaInfo.u32VideoFps = 25;
                        mediaInfo.u32AudioSamplerate = 8000;
                        iRet = EasyRTMP_InitMetadata(g_rtmpPusher.rtmpHandle, &mediaInfo, 1024);
                        if (iRet < 0)
                        {
                            printf("Fail to InitMetadata ...
    ");
                        }
                    }
    
                    EASY_AV_Frame avFrame;
                    memset(&avFrame, 0, sizeof(EASY_AV_Frame));
                    avFrame.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;
                    avFrame.u32AVFrameLen = frameinfo->length;
                    avFrame.pBuffer = (unsigned char*)pbuf;
                    avFrame.u32VFrameType = EASY_SDK_VIDEO_FRAME_I;
                    avFrame.u32TimestampSec = frameinfo->timestamp_sec;
                    avFrame.u32TimestampUsec = frameinfo->timestamp_usec;
    
                    iRet = EasyRTMP_SendPacket(g_rtmpPusher.rtmpHandle, &avFrame);
                    if (iRet < 0)
                    {
                        printf("Fail to EasyRTMP_SendH264Packet(I-frame) ...
    ");
                    }
                    else
                    {
                        printf("I");
                    }
                }
                else
                {
                    if(g_rtmpPusher.rtmpHandle)
                    {
                        EASY_AV_Frame avFrame;
                        memset(&avFrame, 0, sizeof(EASY_AV_Frame));
                        avFrame.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;
                        avFrame.u32AVFrameLen = frameinfo->length-4;
                        avFrame.pBuffer = (unsigned char*)pbuf+4;
                        avFrame.u32VFrameType = EASY_SDK_VIDEO_FRAME_P;
                        avFrame.u32TimestampSec = frameinfo->timestamp_sec;
                        avFrame.u32TimestampUsec = frameinfo->timestamp_usec;
                        iRet = EasyRTMP_SendPacket(g_rtmpPusher.rtmpHandle, &avFrame);
                        if (iRet < 0)
                        {
                            printf("Fail to EasyRTMP_SendH264Packet(P-frame) ...
    ");
                        }
                        else
                        {
                            printf("P");
                        }
                    }
                }               
            }   
        }
        else if (_mediatype == EASY_SDK_AUDIO_FRAME_FLAG)
        {
            EASY_AV_Frame   avFrame;
            memset(&avFrame, 0x00, sizeof(EASY_AV_Frame));
            avFrame.u32AVFrameFlag = EASY_SDK_AUDIO_FRAME_FLAG;
            avFrame.u32TimestampSec = frameinfo->timestamp_sec;
            avFrame.u32TimestampUsec = frameinfo->timestamp_usec;
    
            if(frameinfo->codec == EASY_SDK_AUDIO_CODEC_AAC)
            {
                avFrame.pBuffer = (Easy_U8*)(pbuf);
                avFrame.u32AVFrameLen  = frameinfo->length; 
                printf("*");
                iRet = EasyRTMP_SendPacket(g_rtmpPusher.rtmpHandle, &avFrame);
            }
            else if ((frameinfo->codec == EASY_SDK_AUDIO_CODEC_G711A) || (frameinfo->codec == EASY_SDK_AUDIO_CODEC_G711U) || (frameinfo->codec == EASY_SDK_AUDIO_CODEC_G726))
            {
                if(EasyInitAACEncoder(frameinfo) == 0)
                {
                    memset(g_rtmpPusher.m_pAACEncBufer, 0, 64*1024);
                    unsigned int iAACBufferLen = 0;
    
                    if(Easy_AACEncoder_Encode(g_rtmpPusher.m_pAACEncoderHandle, (unsigned char*)pbuf,  frameinfo->length, g_rtmpPusher.m_pAACEncBufer, &iAACBufferLen) > 0)
                    {
                        printf("*");
                        avFrame.pBuffer = (Easy_U8*)(g_rtmpPusher.m_pAACEncBufer);
                        avFrame.u32AVFrameLen  = iAACBufferLen; 
                        iRet = EasyRTMP_SendPacket(g_rtmpPusher.rtmpHandle, &avFrame);
                    }
                }
            }
        }
    
        return 0;
    }
    

    获取更多信息

    邮件:support@easydarwin.org

    WEB:www.EasyDarwin.org

    Copyright © EasyDarwin.org 2012-2016

    EasyDarwin

  • 相关阅读:
    visual studio 2015 Opencv 3.4.0配置
    读漫谈架构博文有感
    代码阅读方法与实践阅读笔记06
    代码阅读方法与实践阅读笔记05
    apache https 伪静态
    今天网站后台登录页面需要生成一个二维码,然后在手机app上扫描这个二维码,实现网站登录的效果及其解决方案如下
    架设lamp服务器后,发现未按照 Apache xsendfile模块,
    linux下bom头导致的php调用php接口 返回的json字符串 无法转成 数组,即json字符串无法解码的问题
    什么是OAuth授权?
    以application/json 方式提交 然后用在php中读取原始数据流的方式获取 在json_encode
  • 原文地址:https://www.cnblogs.com/babosa/p/6012063.html
Copyright © 2011-2022 走看看