EasyDarwin流媒體雲平台:EasyCamera開源攝像機接入海康威視攝像機實時視頻


本文轉自EasyDarwin團隊成員Alex的博客:http://blog.csdn.net/cai6811376/article/details/52755298

EasyCamera接收雲平台實時視頻請求命令,會向EasyDarwin流媒體服務器進行推流操作。那么EasyCamera是如何通過海康攝像機SDK獲取到媒體流的呢?

我們繼續看海康攝像機SDK

這里寫圖片描述

這里使用NET_DVR_RealPlay_V40/NET_DVR_StopRealPlay接口控制實時視頻。

在獲取實時視頻調用之前,我們需要知道攝像機目前的參數配置,比如FPS,碼率等等。

這里寫圖片描述

//參數獲取
NET_DVR_COMPRESSIONCFG_V30 struCompressionCfg;
memset(&struCompressionCfg, 0, sizeof(struCompressionCfg));
DWORD dwReturned = 0;
EASY_MEDIA_INFO_T mediainfo;
memset(&mediainfo, 0x00, sizeof(EASY_MEDIA_INFO_T));
mediainfo.u32VideoCodec = EASY_SDK_VIDEO_CODEC_H264;
mediainfo.u32AudioChannel = 1;
if (!NET_DVR_GetDVRConfig(m_u32Handle, NET_DVR_GET_COMPRESSCFG_V30, 1, &struCompressionCfg, sizeof(NET_DVR_COMPRESSIONCFG_V30), &dwReturned))
{
    printf("can't get config!\n");

    mediainfo.u32VideoFps = 25;
    mediainfo.u32AudioCodec = EASY_SDK_AUDIO_CODEC_G711A; 
    mediainfo.u32AudioSamplerate = 8000;
}
else
{
    mediainfo.u32VideoFps = getFrameRateFromHKSDK(struCompressionCfg.struNormHighRecordPara.dwVideoFrameRate);
    mediainfo.u32AudioCodec = getAudioCodecFromHKSDK(struCompressionCfg.struNormHighRecordPara.byAudioEncType);
    mediainfo.u32AudioSamplerate = getAudioSimpleRateFromHKSDK(struCompressionCfg.struNormHighRecordPara.byAudioSamplingRate);
}
//實時視頻調用
NET_DVR_PREVIEWINFO struPlayInfo = { 0 };
struPlayInfo.hPlayWnd = NULL; //需要 SDK 解碼時句柄設為有效值,僅取流不解碼時可設為空
struPlayInfo.lChannel = 1; //預覽通道號
struPlayInfo.dwStreamType = 0; //0-主碼流, 1-子碼流, 2-碼流 3, 3-碼流 4,以此類推
struPlayInfo.dwLinkMode = 0; //0- TCP 方式, 1- UDP 方式, 2- 多播方式, 3- RTP 方式, 4-RTP/RTSP, 5-RSTP/HTTP
struPlayInfo.bBlocked = 1; //0- 非阻塞取流, 1- 阻塞取流

streamHandle = NET_DVR_RealPlay_V40(m_u32Handle, &struPlayInfo, myStreamProc, this);
if (streamHandle < 0)
{
    qtss_printf("NET_DVR_RealPlay_V40 Fail\n");
    LONG error = NET_DVR_GetLastError();
    return QTSS_RequestFailed;
}
//數據回調
QTSS_Error EasyCameraSource::PushFrame(unsigned char* frame, int len, DWORD dataType)
{
    OSMutexLocker locker(&fStreamingMutex);
    if (fPusherHandle == NULL) return QTSS_Unimplemented;

    if (dataType == NET_DVR_STREAMDATA)
    {       
        if (len > 0)
        {
            unsigned char *h264Buf = NULL;
            int h264Len = 0;
            BOOL isVideo;
            GetH246FromPS(frame, len, &h264Buf, h264Len, isVideo);
            if (isVideo)
            {
                if (h264Buf)
                {
                    /*printf("size:%04d\t[0]:0x%08X\t[1]:0x%08X\t[2]:0x%08X\t[3]:0x%08X\t[4]:0x%08X \n", h264Len, h264Buf[0], h264Buf[1], h264Buf[2], h264Buf[3], h264Buf[4]);*/

                    if (h264Buf[0] == 0 && h264Buf[1] == 0 && h264Buf[2] == 0 && h264Buf[3] == 1)
                    {
                        if (fPusherBuffOffset > 0)
                        {
                            EASY_AV_Frame avFrameVideo;
                            memset(&avFrameVideo, 0x00, sizeof(EASY_AV_Frame));
                            avFrameVideo.u32AVFrameLen = fPusherBuffOffset;
                            avFrameVideo.pBuffer = (unsigned char*)fPusherBuff;
                            bool isKeyFrame = IsIFrame(fPusherBuff);
                            avFrameVideo.u32VFrameType = isKeyFrame ? EASY_SDK_VIDEO_FRAME_I : EASY_SDK_VIDEO_FRAME_P;
                            avFrameVideo.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;
                            //avFrameVideo.u32TimestampSec = pstruAV->u32AVFramePTS / 1000;
                            //avFrameVideo.u32TimestampUsec = (pstruAV->u32AVFramePTS % 1000) * 1000;
                            Easy_U32 ret = EasyPusher_PushFrame(fPusherHandle, &avFrameVideo);
                            //printf("-- Pushing: Frame %s Result %d \n", isKeyFrame ? "I" : "P", ret);
                            fPusherBuffOffset = 0;                          
                        }
                        memcpy(fPusherBuff, h264Buf, h264Len);
                        fPusherBuffOffset += h264Len;
                    }
                    else
                    {
                        if (fPusherBuffOffset > 0)
                        {
                            memcpy(fPusherBuff + fPusherBuffOffset, h264Buf, h264Len);
                            fPusherBuffOffset += h264Len;
                        }
                    }
                }
                if (h264Buf)
                {
                    delete[] h264Buf;
                    h264Buf = NULL;
                }
            }
        }
    }
    else if (dataType == NET_DVR_AUDIOSTREAMDATA)
    {
        if (len > 0)
        {
            EASY_AV_Frame avFrameAudio;
            memset(&avFrameAudio, 0x00, sizeof(EASY_AV_Frame));
            avFrameAudio.u32AVFrameLen = len;
            avFrameAudio.pBuffer = (unsigned char*)frame;
            avFrameAudio.u32AVFrameFlag = EASY_SDK_AUDIO_FRAME_FLAG;
            //avFrameAudio.u32TimestampSec = pstruAV->u32AVFramePTS / 1000;
            //avFrameAudio.u32TimestampUsec = (pstruAV->u32AVFramePTS % 1000) * 1000;
            EasyPusher_PushFrame(fPusherHandle, &avFrameAudio);
        }
    }

    return Easy_NoErr;
}

源碼及視頻教程

源碼地址:https://github.com/EasyDarwin/EasyDarwin/tree/master/EasyCamera-HK

視頻教程地址:[http://edu.csdn.net/course/detail/3029

](http://edu.csdn.net/course/detail/3029)

獲取更多信息

郵件:support@easydarwin.org

WEB:www.EasyDarwin.org

Copyright © EasyDarwin.org 2012-2016

EasyDarwin


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM