开发指南

1 开发准备

开始前请确保下述前提条件已准备就绪:

解压后 SDK 包的 libs 文件夹中,包含了 dll 库文件和头文件,文件列表如下:

libs
├── base.dll
├── cos.dll
├── engine.dll
├── itrd.dll
├── libgcc_s_dw2-1.dll
├── libiconv-2.dll
├── pthreadGC-3.dll
├── SDL2.dll
├── avcodec-57.dll
├── avfilter-6.dll
├── avformat-57.dll
├── avutil-55.dll
├── swresample-2.dll
├── swscale-4.dll
├── NELivePlayer.dll
├── NELivePlayer.lib
├── include
│   ├── nelp_api.h
│   ├── nelp_define.h
│   ├── nelp_type.h
└──

总体接口约定
SDK 提供的API C类型接口,分别提供 win32 的动态库 NELivePlayer.dll及其对应的导入库 NELivePlayer.lib 方便开发者动态加载或者加载 SDK 库文件。 App 开发者只需要引用 SDK 包里 sdk\include 目录下的头文件即可。关于API类或者函数的定义,可以查看API 文档。

2 集成 SDK

本文介绍sdk接入的整个流程,可在网易云视频官网下载最新的播放器Windows Demo,来查看更多的实现细节。

2.1 导入头文件和库文件

(1)导入库文件
将 SDK 相关的 dll 文件放到App 的运行目录下。SDK 基于vs2013 开发,如果App 没有对应的运行时库文件(msvcp120.dllmsvcr120.dll),请将其放到App 的运行目录下。

(2)引用头文件
由于nelp_api.h里面会引用nelp_type.hnelp_define.h两个头文件,所以开发者只需导入nelp_api.h即可,但是三个头文件需要放在同一目录下,如下所示:

#include "nelp_api.h"

2.2 实现播放功能

(1)创建播放器实例
先通过调用 Nelp_Create(const char *paLogPath, NELP_OUT _HNLPSERVICE *phNLPService)创建播放器实例。
其中:
paLogPath: 为日志文件的输出路径。如果设为NULL则默认保存到当前的工作目录下。
phNLPService: 为创建成功的播放器实例。

示例代码

_HNLPSERVICE m_hNelpService;
if (NELP_OK != Nelp_Create("E:\\log", &m_hNelpService)) {
    // 创建失败
}
else {
    // 创建成功
}

(2) 注册获取消息的回调
注意:在 Nelp_PrepareToPlay 前调用。 播放器SDK在整个播放过程中会有一些状态消息的回调,开发者需要调用 Nelp_RegisterMessageCB(_HNLPSERVICE hNLPService, P_NELP_MESSAGE_CB pMessageCB)接口进行注册才能收到相应的消息回调。
其中:
phNLPService: 为创建成功的播放器实例。
pMessageCB: 为接收消息的回调,用户需要自己实现该回调来接收相应的消息,消息类型参见API文档。

示例代码

    void getMessage(ST_NELP_MESSAGE msg);
    Nelp_RegisterMessageCB(m_hNelpService, getMessage);

    void getMessage(ST_NELP_MESSAGE msg) {
        switch (msg.iWhat) {
        case NELP_MSG_ERROR:
            break;
        case NELP_MSG_PREPARED:
            break;
        case NELP_MSG_VIDEO_SIZE_CHANGED:
            break;
        case NELP_MSG_BUFFERING_START:
            break;
        case NELP_MSG_BUFFERING_END:
            break;
        case NELP_MSG_COMPLETED:
            break;
        case NELP_MSG_VIDEO_RENDERING_START:
            break;
        case NELP_MSG_AUDIO_RENDERING_START:
            break;
        case NELP_MSG_PLAYBACK_STATE_CHANGED:
            break;
        case NELP_MSG_AUDIO_DEVICE_OPEN_FAILED:
            break;
        case NELP_MSG_SEEK_COMPLETED:
            break;
        case NELP_MSG_VIDEO_PARSE_ERROR:
            break;
        default:
            break;
        }
    }

各种消息类型的具体含义参见API文档

(3) 注册接收资源释放成功消息的回调
注意:在 Nelp_PrepareToPlay 前调用。 播放器退出播放需要调用Nelp_Shutdown接口来释放相关的资源,资源释放的过程是异步的,释放结束后会上报资源释放成功的消息,开发者需要调用 Nelp_RegisterResourceReleaseSuccessCB(_HNLPSERVICE hNLPService, P_NELP_RESOURCE_RELEASE_SUCCESS_CB pReleaseCB)接口进行注册才能收到该消息。
其中:
phNLPService: 为创建成功的播放器实例。
pReleaseCB: 为接收资源释放成功消息的回调,用户需要自己实现该回调来接收相应的消息。

示例代码

    void resourceReleaseSuccess();
    Nelp_RegisterResourceReleaseSuccessCB(m_hNelpService, resouceReleaseSuccess);

    void resourceReleaseSuccess() {
        // 资源释放成功了
    }

注意:如果退出后还需要重新开启播放的话,需要等到资源释放结束的消息后才能开始下一次播放,防止内存泄漏。

(4) 注册接收视频数据的回调
注意:在 Nelp_PrepareToPlay 前调用,若不需要得到视频数据则该步骤忽略。
播放器sdk支持解码后的视频数据的回调,若开发者需要得到解码后的视频数据来进行显示或者处理,则可以调用 Nelp_RegisterGetVideoFrameCB(_HNLPSERVICE hNLPService, bool bIsRender, EN_NELP_MEDIA_FORMAT eMFormat, NELP_OUT P_NELP_VIDEO_FRAME_CB pVideoFrameCB)接口来进行注册。
其中:
phNLPService: 为创建成功的播放器实例。
bIsRender: 为是否用sdk内置显示模块显示的标记。TRUE为显示,FALSE为不显示
eMFormat: 为回调的视频数据的格式
pVideoFrameCB: 为获取视频数据的回调

示例代码

    void getVideoFrame(ST_NELP_FRAME *frame);
    bool use_sdk_render = TRUE;
    if (use_sdk_render) {
        // 使用sdk内置显示模块进行显示,回调的视频数据格式是YUV420
        Nelp_ Nelp_RegisterGetVideoFrameCB(m_hNelpService, TRUE, EN_YUV420, getVideoFrame);
    }
    else {
        // 不使用sdk内置显示模块进行显示,回调的视频数据格式是YUV420
        Nelp_ Nelp_RegisterGetVideoFrameCB(m_hNelpService, FALSE, EN_YUV420, getVideoFrame);
    }

    void getVideoFrame(ST_NELP_FRAME *frame) {
        switch (frame->enMFormat) {
            case EN_ARGB8888:
                // ARGB8888 数据格式
                break;
            case EN_YUV420:
                // YUV420 数据格式
                break;
            default:
                break;
        }
    }

(5) 设置视频播放窗口
注意:在 Nelp_PrepareToPlay 前调用,若开发者有自己的视频显示模块,则可以不用调用该接口。sdk提供了视频数据的回调(步骤4),开发者可以拿到回调的视频数据用于显示。
播放器sdk内置了视频显示模块,开发者需要将显示窗口和sdk底层的视频显示模块关联起来。用户可以调用 Nelp_SetDisplay(_HNLPSERVICE hNLPService, void *windowSurface, int iRenderWindWidth, int iRenderWindHeight)来进行关联,关联成功后,就可以进行拉流播放。
其中:
phNLPService: 为创建成功的播放器实例。
windowSurface: 为显示窗口控件的句柄。
iRenderWindWidth: 为显示窗口控件的宽度
iRenderWindHeight: 为显示窗口控件的高度

示例代码

    HWND wnd;
    CWnd *pWnd = (CWnd *)GetDlgItem(IDC_RENDER);
    wnd = pWnd->GetSafeHwnd();

    if (NELP_OK != Nelp_SetDisPlay(m_hNelpService, wnd, 640, 480)) {
        return; // 设置不成功
    }

(6) 初始化播放参数,包括设置播放地址,缓冲模式等
注意:在 Nelp_PrepareToPlay 前调用。
上述操作完成后,需要初始化播放所需的相关参数,如播放地址,缓冲模式,是否拉流成功后自动播放等。开发者可以调用Nelp_InitParam(_HNLPSERVICE hNLPService, ST_NELP_PARAM *pstParam)接口进行初始化设置。

其中:
phNLPService: 为创建成功的播放器实例。
pstParam: 为相关参数的结构体变量。

示例代码

    ST_NELP_PARAM *pstNelpParam = (ST_NELP_PARAM *)malloc(sizeof(ST_NELP_PARAM));

    typedef enum en_NELP_STREAM_TYPE {
        en_LIVESTREAMING, // 直播流
        en_ONDEMAND       // 点播流
    } EN_NELP_STREAM_TYPE;

    char *url = "http://xxx.xxx.xxx.xxx/xxx.flv"; // 播放地址
    EN_NELP_STREAM_TYPE m_streamType; // 流类型,直播还是点播

    m_streamType = en_LIVESTREAMING; // 为直播流,该处为示例代码,开发者需要根据实际情况进行设置

    if (pstNelpParam != NULL) {
        pstNelpParam->paPlayUrl = url;
        pstNelpParam->bAutoPlay = TRUE; // 拉流成功后自动播放,设置成FALSE后,需要调用Nelp_Start接口进行播放
        if (m_streamType == en_LIVESTREAMING) { // 直播流
            pstNelpParam->enBufferStategy = EN_NELP_LOW_DELAY; // 采用直播低延时模式
        }
        else if (m_streamType == en_ONDEMAND) { // 点播流
            pstNelpParam->enBufferStategy = EN_NELP_ANTI_JITTER; // 采用点播抗抖动模式
        }
    }

    // 初始化相关参数
    if (NELP_OK != Nelp_InitParam(m_hNelpService, pstNelpParam)) {
        // 初始化失败
        free(pstNelpParam);
        return;
    }

    free(pstNelpParam);

(7) 预处理播放
上述所有步骤完成后就可以调用 Nelp_PrepareToPlay(_HNLPSERVICE hNLPService)接口进行预处理播放了,该接口主要做了各个模块的线程创建,开始拉流,解析,解码等一系列操作。
其中:
phNLPService: 为创建成功的播放器实例。

示例代码

    Nelp_PrepareToPlay(m_hNelpService);

预处理完成后会收到NELP_MSG_PREPARED的消息,具体见(步骤2)和API文档。若预处理过程中出现拉流失败,播放出错等问题,则会收到NELP_MSG_ERROR的消息

若在(步骤5)中设置了自动播放,则在预处理完成后会自动播放,不需要调用Nelp_Start接口,否则需要调用Nelp_Start接口进行播放。

(8) 开始播放
如(步骤7)所述,若bAutoPlay 设置成FALSE,则在调用 Nelp_PrepareToPlay 接口后,需要调用 Nelp_Start(_HNLPSERVICE hNLPService) 进行播放。
其中:
phNLPService: 为创建成功的播放器实例。

示例代码

    Nelp_Start(m_hNelpService);

注意:该接口可用于预处理完成后的播放,也可以用于暂停后的恢复播放。

2.3 播放控制

(1) 暂停播放
在播放过程中若需要暂停播放,可以调用 Nelp_Pause(_HNLPSERVICE hNLPService) 接口来暂停当前的播放。
其中:
phNLPService: 为创建成功的播放器实例。

示例代码

    Nelp_Pause(m_hNelpService);

暂停后调用Nelp_Start()方法即可恢复播放

注意:直播过程中不能暂停,暂停功能只适用于点播

(2) 拖动播放
在播放过程中需要拖动进度条到某一时间点播放可以调用 Nelp_SeekTo(_HNLPSERVICE hNLPService, long lTime) 接口进行设置。
其中:
phNLPService: 为创建成功的播放器实例。
lTime: 为指定的播放时间点(单位秒:s)。

示例代码

    Nelp_SeekTo(m_hNelpService, 300);

注意:该接口一定要在收到 NELP_MSG_PREPARED 消息后才可以调用。该功能只适用于点播

(3) 静音功能
在播放过程中需要静音,则可以调用 Nelp_SetMute(_HNLPSERVICE hNLPService, bool bIsMute)接口进行设置。
其中:
phNLPService: 为创建成功的播放器实例。
bIsMute: 为是否静音的标识,TRUE:开启静音 FALSE:静音恢复。

示例代码

    bool bIsMute = TRUE;
    if (bIsMute) {
           // 开启静音
        Nelp_SetMute(m_hNelpService, TRUE);
    }
    else {
        // 静音恢复
        Nelp_SetMute(m_hNelpService, FALSE);
    }

注意:该接口一定要在收到 NELP_MSG_PREPARED 消息后才可以调用。

(4) 音量调节
在播放过程中可以调用 Nelp_SetVolume(_HNLPSERVICE hNLPService, float fVolume)接口进行音量调节。
其中:
phNLPService: 为创建成功的播放器实例。
fVolume: 为设置的音量大小(范围:0.0 ~ 1.0 0.0:静音 1.0:最大)。

示例代码

    Nelp_SetVolume(m_hNelpService, 0.8);

注意:该接口一定要在收到 NELP_MSG_PREPARED 消息后才可以调用。

(5) 获取文件总时长
对于点播视频文件可以调用Nelp_GetDuration(_HNLPSERVICE hNLPService)接口来获取点播文件的总时长。返回的是文件的总时长,单位秒:s。
其中:
phNLPService: 为创建成功的播放器实例。

示例代码

    long lDuration = Nelp_GetDuration(m_hNelpService); 
    if (lDuration < 0) {
        // 获取失败;
    }

注意:该接口一定要在收到 NELP_MSG_PREPARED 消息后才可以调用。该功能只适用于点播

(6) 获取当前播放的时间点
在播放过程中可以调用Nelp_GetCurrentPlaybackTime(_HNLPSERVICE hNLPService)接口来获取当前播放的时间点。返回的是当前播放的时间点,单位秒:s。
其中:
phNLPService: 为创建成功的播放器实例。

示例代码

    long lCurrentPos = Nelp_GetCurrentPlaybackTime(m_hNelpService); 
    if (lCurrentPos < 0) {
        // 获取失败;
    }

注意:该接口一定要在收到 NELP_MSG_PREPARED 消息后才可以调用。

(7) 获取当前可播放的时间点
对于点播视频文件可以调用Nelp_GetPlayableDuration(_HNLPSERVICE hNLPService)接口来获取当前可播放的时间点。即已缓存的位置。返回的是当前可播放的时间点,单位秒:s。
其中:
phNLPService: 为创建成功的播放器实例。

示例代码

    long lPlayablePos = Nelp_GetPlayableDuration(m_hNelpService); 
    if (lPlayablePos < 0) {
        // 获取失败;
    }

注意:该接口一定要在收到 NELP_MSG_PREPARED 消息后才可以调用。该功能只适用于点播

(8) 获取当前播放器的状态
在播放过程中,开发者可以调用 Nelp_GetPlaybackState(_HNLPSERVICE hNLPService)接口来获取当前播放器的状态,具体的状态值参见API文档。

其中:
phNLPService: 为创建成功的播放器实例。

示例代码

    EN_NELP_PLAYBACK_STATE playState = Nelp_GetPlaybackState(m_hNelpService);
    if (playState == EN_NELP_GET_PLAYBACK_STATE_FAILED) {
        // 获取状态失败
    }

(9) 截图功能
在播放过程中,可以调用 Nelp_GetSnapshot(_HNLPSERVICE hNLPService, EN_NELP_PICTURE_FORMAT ePFormat)接口进行截图。返回的是截图后的结果。
其中:
phNLPService: 为创建成功的播放器实例。 ePFormat: 为返回的图片格式,具体参见API文档。

示例代码

    ST_NELP_PICTURE *sPicture = NULL;
    sPicture = Nelp_GetSnapshot(m_hNelpService, EN_PIC_ARGB8888); // 返回的是ARGB8888格式的图片类型

注意:该接口一定要在收到 NELP_MSG_PREPARED 消息后才可以调用。

(9) 获取SDK版本号
示例代码

     char *paSdkVersion;
     Nelp_GetSDKVersion(&paSdkVersion);

(10) 退出播放
退出播放需要调用Nelp_Shutdown(_HNLPSERVICE hNLPService)接口,并将播放器实例置为空。 示例代码

     Nelp_Shutdown(m_hNelpService);
     m_hNelpService = NULL;

退出成功会收到资源释放成功的回调,见2.2中的步骤(3)。

注意:若在播放过程中切换URL或者频繁进出,在后续进入的过程中,一定要等到资源释放成功的回调,否则可能会导致播放失败。

3 SDK 打包说明

开发者在打包自己的应用时,应确保将以下 SDK 相关文件打包进去。

4 API说明

有关API的详细说明,可参见下面的在线文档。

网易云视频播放器NELivePlayer Windows SDK API详细文档