跳转至

LightPlay(Native)

LightPlay DRM 为芒果TV基于ChinaDRM标准自研的DRM解决方案,优点为轻量、低成本。

支持平台

LightPlay Native底层接口使用C语言开发,支持跨平台集成,目前已支持Android、IOS、Windows等多平台。 当需要直接对接底层接口获取LightPlay DRM能力时,可选用该方案。

API调用流程图

image

API定义

MGTV_CDRMC_Initialize

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_Initialize int 0-正常,1-调用时状态不对 芒果DRM SDK初始化 全局仅需调用一次

MGTV_CDRMC_Terminate

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_Initialize int 0-正常,1-调用时状态不对 芒果DRM SDK终止 全局仅需调用一次

MGTV_CDRMC_IsProvisioned

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_IsProvisioned int 0-否,1-是 是否已获取证书

MGTV_CDRMC_GetProvisionRequest

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_GetProvisionRequest provisionRequest-申请的一段用于接收证书内容的内存,一般定义为MAX_PROVISION_REQUEST_LEN (2 * 1024),provisionRequestLen-0 provisionRequestLen 实际的返回证书数据大小 int 0-否,1-是 获取证书所需请求数据

MGTV_CDRMC_ProcessProvisionResponse

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_ProcessProvisionResponse provisionResponse-证书响应内容,provisionResponseLen-证书响应数据长度 int 0-否,1-是 设置请求证书响应数据

MGTV_CDRMC_OpenSession

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_OpenSession sessionHandle-传入为NULL,传出时填充DRM会话句柄地址 sessionHandle int 0-成功,<0-失败 打开DRM会话

MGTV_CDRMC_CloseSession

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_CloseSession sessionHandle-待关闭的会话句柄 int 0-成功,<0-失败 关闭DRM会话

MGTV_CDRMC_GetLicenseRequest

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_GetLicenseRequest sessionHandle-会话句柄 ,drmInfo-预留,drmInfoLen-预留,licenseRequest-许可证请求数据,输入时预申请REQ_DEST_BUF_SIZE=8192内存空间 ,licenseRequestLen-内存长度 licenseRequest-许可证数据,licenseRequestLen-实际许可证长度 int 0-成功,<0-失败 获取许可证请求数据

MGTV_CDRMC_ProcessLicenseResponse

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_ProcessLicenseResponse sessionHandle-会话句柄 ,respInfo-许可证数据,respInfoLen-许可证长度 int 0-成功,<0-失败 塞入许可证响应数据

MGTV_CDRMC_Decrypt_MASK

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_Decrypt_MASK out_data-解密数据, in_data-加密数据,buf_size-数据长度,keyid, keyid_size-keyid长度,start_pos-开始解密位置 int 0-成功,<0-失败 MASK解密,目前主要用于音频FM业务场景解密

MGTV_CDRMC_Symmetric_Decrypt_HandleNew

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_Symmetric_Decrypt_HandleNew sessionHandle-会话句柄,drm_type 协商定义的加密标识字符串(举例sm4-ctr)
keyid-密钥id,keyid_size 密钥id长度,iv,iv_size MGTV_CDRMR_CipherHandle 等于0表示创建失败,大于0创建成功 目前用于IPTV项目

MGTV_CDRMC_Symmetric_Decrypt_HandleFree

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_Symmetric_Decrypt_HandleFree sessionHandle-会话句柄 释放对称解密句柄

MGTV_CDRMC_Symmetric_Decrypt_Process

函数名字 输入参数 输出参数 返回值 函数功能 函数说明
MGTV_CDRMC_Symmetric_Decrypt_Process sessionHandle-会话句柄,in_data-输入加密数据,in_size-输入数据长度,out_data-输出解密数据,out_size-输出数据长度(出参), is_final-是否为结尾数据 对称解密处理过程

头文件

/**
 * @brief 芒果DRM SDK初始化(全局仅需调用一次)
 * 
 * @return int 0-正常,1-调用时状态不对
 */
int MGTV_CDRMC_Initialize(void);

/**
 * @brief 芒果DRM SDK终止(全局仅需调用一次)
 * 
 * @return int 0-正常
 */
int MGTV_CDRMC_Terminate(void);

int MGTV_CDRMC_GetDeviceId(char *deviceId, unsigned int *deviceIdLen);

/**
 * @brief 是否已获取证书
 * 
 * @return int 0-否,1-是
 */
int MGTV_CDRMC_IsProvisioned();

/**
 * @brief 获取证书所需请求数据
 * 
 * #define MAX_PROVISION_REQUEST_LEN (2 * 1024)
 * unsigned int len = 0;
 * unsigned char request[MAX_PROVISION_REQUEST_LEN];
 * memset(request, 0, sizeof(request));
 * int ret = MGTV_CDRMC_GetProvisionRequest(request, &len);
 * if (ret == MGTV_CDRMC_ERROR_OK || len > 0) 
 * {
 *      //后续使用该数据作为POST body请求证书服务接口
 * }
 * 
 * @param provisionRequest 
 * @param provisionRequestLen 传入时为0,传出时为实际的数据大小
 * @return int 
 */
int MGTV_CDRMC_GetProvisionRequest(unsigned char *provisionRequest,
                                    unsigned int *provisionRequestLen);

/**
 * @brief 设置请求证书响应数据
 * 
 * @param provisionResponse 
 * @param provisionResponseLen 
 * @return int 
 */
int MGTV_CDRMC_ProcessProvisionResponse(const unsigned char *provisionResponse, 
                                            unsigned int provisionResponseLen);

/**
 * @brief 打开DRM会话
 * 
 * MGTV_CDRMC_SessionHandle sessionHandle = NULL;
 * int ret = MGTV_CDRMC_OpenSession(&sessionHandle);
 * if (ret != MGTV_CDRMC_ERROR_OK)
 * {
 *    //打开DRM会话失败
 * }
 * 
 * return sessionHandle;//需要保存起来,待后续使用
 * 
 * @param sessionHandle 传入为NULL,传出时填充句柄地址
 * @return int 
 */
int MGTV_CDRMC_OpenSession(MGTV_CDRMC_SessionHandle *sessionHandle);

/**
 * @brief 关闭DRM会话
 * 
 * @param sessionHandle 传入句柄地址
 * @return int 
 */
int MGTV_CDRMC_CloseSession(MGTV_CDRMC_SessionHandle sessionHandle);

/**
 * @brief 获取许可证请求数据
 * 
 * #define REQ_DEST_BUF_SIZE 8192  
 *   
 * MGTV_CDRMC_SessionHandle handler = (MGTV_CDRMC_SessionHandle)sessionHandle;
 * unsigned char licenseRequest[REQ_DEST_BUF_SIZE];
 * unsigned int licenseRequestLen = sizeof(licenseRequest);
 * memset(licenseRequest, 0, REQ_DEST_BUF_SIZE);
 * 
 * int ret = MGTV_CDRMC_GetLicenseRequest(handler, NULL, 0, licenseRequest, &licenseRequestLen);
 * if (ret == MGTV_CDRMC_ERROR_OK || licenseRequestLen > 0)
 * {
 *    //后续使用该数据POST body请求许可证服务器
 * }
 * 
 * @param sessionHandle 
 * @param drmInfo 
 * @param drmInfoLen 
 * @param licenseRequest 
 * @param licenseRequestLen 
 * @return int 
 */
int MGTV_CDRMC_GetLicenseRequest(MGTV_CDRMC_SessionHandle sessionHandle, unsigned char *drmInfo, 
                                unsigned int drmInfoLen, unsigned char *licenseRequest, unsigned int *licenseRequestLen);

/**
 * @brief 塞入许可证响应数据
 * 
 * @param sessionHandle 
 * @param respInfo 
 * @param respInfoLen 
 * @return int 
 */
int MGTV_CDRMC_ProcessLicenseResponse(MGTV_CDRMC_SessionHandle sessionHandle, unsigned char *respInfo, unsigned int respInfoLen);

/**
 * @brief 塞入许可证响应数据(暂不对外)
 * 
 * @param sessionHandle sessionHandle
 * @param respInfo license server response info
 * @param respInfoLen info len
 * @param drmType drm type
 * @return int 
 */
int MGTV_CDRMC_ProcessLicenseResponseEx(MGTV_CDRMC_SessionHandle sessionHandle, unsigned char *respInfo, unsigned int respInfoLen, int drmType);

int MGTV_CDRMC_CheckRightsStatus(MGTV_CDRMC_SessionHandle sessionHandle, unsigned char *drmInfo, unsigned int drmInfoLen,
                            MGTV_CDRMC_Rights_Status *rightsStatus);

/**
 * @brief MASK解密,目前主要用于音频FM业务场景解密
 * 
 * @param out_data 
 * @param in_data 
 * @param buf_size 
 * @param keyid 
 * @param keyid_size 
 * @param start_pos 
 * @return int 
 */
int MGTV_CDRMC_Decrypt_MASK(unsigned char *out_data, const unsigned char *in_data,
                               int buf_size, const unsigned char *keyid, int keyid_size, int start_pos);


/**
 * @brief 创建对称解密句柄
 * 
 * @param sessionHandle 
 * @param drm_type 协商定义的加密标识字符串,举例sm4-ctr
 * @param keyid 密钥id
 * @param keyid_size 密钥id长度
 * @param iv 
 * @param iv_size 
 * @return MGTV_CDRMR_CipherHandle 小于等于0表示创建失败,大于0创建成功
 */
MGTV_CDRMR_CipherHandle MGTV_CDRMC_Symmetric_Decrypt_HandleNew(MGTV_CDRMC_SessionHandle sessionHandle, const unsigned char *drm_type, const unsigned char *keyid,
                                                               int keyid_size, unsigned char *iv, int iv_size);

/**
 * @brief 释放对称解密句柄
 * 
 * @param pCipherHandle 
 */
void MGTV_CDRMC_Symmetric_Decrypt_HandleFree(MGTV_CDRMR_CipherHandle pCipherHandle);

/**
 * @brief 对称解密处理过程
 * 
 * @param pCipherHandle 解密句柄
 * @param in_data 输入加密数据
 * @param in_size 输入数据长度
 * @param out_data 输出解密数据
 * @param out_size 输出数据长度(出参)
 * @param is_final 是否为结尾数据
 * @return int 小于0-解密错误,大于或等于0-解密成功,并返回解密长度 
 */
int MGTV_CDRMC_Symmetric_Decrypt_Process(MGTV_CDRMR_CipherHandle pCipherHandle, const unsigned char *in_data, int in_size,
                                         unsigned char *out_data, int* out_size, int is_final);