乐趣区

关于c++:SkeyeLive开源流媒体同屏直播软件源码功能框架解析

SkeyeLive 是 OpenSKEYE 开源流媒体团队开发的一款功能丰富的开源 PC 端流媒体推流拉流直播软件我的项目,目前反对 Windows、Android 版本,后续将反对 ios 版本,其中 Windows 版本的 SkeyeLive 反对多种源接入,包含 Windows 摄像头、麦克风、RTSP 摄像机、屏幕桌面等,采集后通过 x264 编码、SkeyePusher 推送到 OpenSKEYE 流媒体服务器进行转发,同时 SkeyeLive 还反对通过 SkeyeRTSPClient 拉取 OpenSKEYE 直播流,进行显示、播放,十分稳固、易用,用户能够基于 SkeyeLive 我的项目,开发相似于课堂直播、视频对讲等我的项目!

性能解说

一、程序框架
SkeyeLive 次要包含三个模块:采集、推送和直播,次要性能封装治理类 Class CSourceManager 中实现,接口非常简单,各模块别离提供开始和完结接口函数,不便界面调用;
界面调用接口:

    // 开始捕捉(采集)
    int StartCapture(SOURCE_TYPE eSourceType, int nCamId, int nAudioId, HWND hCapWnd, char* szURL, int nVideoWidth, int nVideoHeight, int nFps=, int nBitRate);
    // 进行采集
    void StopCapture();

    // 开始推流
    int StartPush(char* ServerIp, int nPushPort, char* sPushName, int nPushBufSize = 1024);
    // 进行推流
    void StopPush();
    
    // 开始播放
    int StartPlay(char* szURL, HWND hShowWnd);
    // 进行播放
    void StopPlay();

1、采集模块
采集分为本地音视频采集和 RTSP 流采集
本地音视频次要通过 DShow 进行采集,函数如下:

int CSourceManager::StartDSCapture(int nCamId, int nAudioId,HWND hShowWnd,int nVideoWidth, int nVideoHeight, int nFps, int nBitRate)

该函数次要实现本地音视频采集和音视频编码器的初始化(详见 SkeyeLive 源码),须要留神的是这里的参数设置:
(1) 本地采集的视频宽高和 x264 编码器的宽高需统一,数据格式倡议设为 YUY2(程序中默认为“YUY2″), 因为在 DShow 的数据采集线程中须要进行编码前的格局转换(YUY2->I420), 如果格局不对立,这里将要重写转换函数;
(2) 本地音频采样率默认为 16000,这个设置在 SkeyePusher 中体现最佳,其余采样率还有待测试;
(3) 其余设置请参照 DEVICE_CONFIG_INFO 构造和 Encoder_Config_Info 构造的具体阐明;

仔细的童鞋应该曾经发现 RTSP 流采集和流播放采纳的是同一个类 Class SkeyeLiveManager 实现,如下:

    // 接管网络 RTSP 流进行推流
    SkeyeLiveManager m_netStreamCapture;
    // 接管 OpenSKEYE 推出的 RTSP 流进行播放
    SkeyeLiveManager m_netStreamPlayer;

这个类封装了 libSkeyeLive 库提供的接口,不便调用;这个库集成在 SkeyeLive 源码中,也是 SkeyeLive 的外围;她次要实现了从网络接管 RTSP 流进行解析,获取 H264 编码数据和 AAC 编码数据别离进行解码并出现和播放,当然,作为 Capturer 而言,咱们只须要用她获取到编码数据即可。


2、推送模块
推送则显得异样简略,间接调用原生态的 SkeyePusher 接口,即可实现:

// 开始推流
int CSourceManager::StartPush(char* ServerIp, int nPushPort, char* sPushName, int nPushBufSize)
{
    // 创立推送器指针
    m_sPushInfo.pusherHandle = SkeyePusher_Create();
    strcpy(m_sPushInfo.pushServerAddr,  ServerIp);
    m_sPushInfo.pushServerPort = nPushPort;
    strcpy(m_sPushInfo.sdpName, sPushName);
    Skeye_U32 nRet = 0;
    if (NULL != m_sPushInfo.pusherHandle)
    {
        // 设置推送回调,能够获取推送器反馈的信息
        SkeyePusher_SetEventCallback(m_sPushInfo.pusherHandle, __SkeyePusher_Callback, 0, NULL);
        // 开启流推送
        Skeye_U32 nRet = SkeyePusher_StartStream(m_sPushInfo.pusherHandle , 
            ServerIp, nPushPort, sPushName, "admin", "admin", (Skeye_MEDIA_INFO_T*)&m_mediainfo, nPushBufSize, 0);//512-2048
        if(nRet>=0)
        {m_bPushing = TRUE;}
        else
        {StopPush();
        }
    }
    return nRet;
}
// 进行推流
void CSourceManager::StopPush()
{
    //Close Pusher
    if (NULL != m_sPushInfo.pusherHandle)
    {SkeyePusher_StopStream(m_sPushInfo.pusherHandle);
        SkeyePusher_Release(m_sPushInfo.pusherHandle);
        m_sPushInfo.pusherHandle = NULL;
    }
    m_bPushing = FALSE;
    m_bAVSync = FALSE;
}

惟一须要留神的是推送标记 m_bPushing,这个标记将在数据回调函数中起到真正的推送开关的作用(严格的说在 StartPush 中也应该调用 m_bPushing 判断是否推送曾经进行)。


3、直播模块
直播在采集模块中采集网络流时提到过,也是间接调用类 Class SkeyeLiveManager 接口实现:

// 开始播放
int CSourceManager::StartPlay(char* szURL, HWND hShowWnd)
{m_sPlayInfo.rtspSourceId = m_netStreamPlayer.Start(szURL, hShowWnd, DISPLAY_FORMAT_RGB24_GDI, 0x01, "","");
    m_netStreamPlayer.Config(3, TRUE, TRUE);
    return m_sPlayInfo.rtspSourceId ;
}
// 进行播放
void CSourceManager::StopPlay()
{m_netStreamPlayer.Close();
}

源码下载:https://gitee.com/visual-open…

退出移动版