> For the complete documentation index, see [llms.txt](https://polyv.gitbook.io/document/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://polyv.gitbook.io/document/docs/vod/pc_player.md).

# Pc Player

* [功能使用](#功能使用)
  * [SDK 名词含义及功能说明](#sdk-名词含义及功能说明)
  * [SDK 全局函数](#sdk-全局函数)
  * [SDK 防录制功能](#sdk-防录制功能)
  * [SDK 下载器](#sdk-下载器)
  * [SDK 播放器](#sdk-播放器)
  * [SDK 注意事项](#sdk-注意事项)

本文档提供了使用 C++SDK 的操作步骤及代码示例，通过本文您可以快速了解如何使用 SDK 提供的功能。您也可以通过 Demo 中的示例进行了解和自有业务开发。

## SDK 名词含义及功能说明

* 参见 **`plv-player-def.h`**

## SDK 全局函数

1. 设置日志，日志过滤项。
2. 设置观众信息（用于后台数据追踪）。
3. 设置相关参数（硬解开关，网络请求类型等）。
4. 初始化（userid, key）。
5. 退出析构。

```cpp
std::count << "the sdk version:" << PLVGetSdkVersion() << std::endl;
// 设置日志信息,路径须使用utf8
PLVSetSdkLogMessageCallback(true,[](LOG_FILTER_TYPE, const char*, void*){}, nullptr);
PLVSetSdkLogLevel(LOG_FILTER_INFO);
int ret = PLVSetSdkLogFile("C:/log/sdk.log");
std::count << "the log file result:" << ret << std::endl;
// 设置 viewer 信息，用于定位播放质量问题，在线播放下可以通过后台来查看，建议调用此接口设置信息
// 最新 vrm12/vrm13 下必须设置，否则播放会报错
std::string viewerId = "业务id";// 唯一值
std::string viewerName = "业务nick";
std::string viewerAvatar= "业务Avatar";
PLVSetSdkViewerInfo(viewerId.c_str(), viewerName.c_str(), viewerAvatar.c_str());
//初始化SDK,建议不要传入secretKey与appSecret,相关信息由业务服务器获取后传给客户端
PLVAccountInfo accountInfo;
accountInfo.userId = "xxxx";
ret = PLVInitSdkLibrary(&accountInfo);
std::cout << "init sdk result:" << ret << std::endl;
//释放SDK
PLVReleaseSdkLibrary();

//以下为播放相关全局设置,详见文档信息
PLVSetSdkLocalRememberPlay(true);
PLVSetSdkKeepLastFrame(true);
PLVSetSdkHwdecEnable(false);
PLVSetSdkVideoOutputDevice(VIDEO_OUTPUT_GPU, nullptr);
PLVSetSdkSeed("xxxxxxx");
//以下为下载相关全局设置,详见文档信息
PLVSetSdkRetryAttempts();

// 获取错误描述
auto desc = PLVGetSdkErrorDescription(ret);
std::cout<< "the error info: << desc << std::endl;
```

## SDK 防录制功能

防录制功能的说明，必须 SDK 初始化之后才能使用，操作步骤及功能示例如下：

```cpp
// 注意通知回调都是子线程，如果更新 ui 及操作 api 都需要 post 到主线程
class Record{
public:
    Record(void){
        // 软件录制通知或者破解注入通知
        PLVSetDetectSoftwareRecordingHandler(true, []（SOFTWARE_RECORDING_NOTIFY_TYPE type, const char* softwares, void* data）{
            // 有插件注入通知，可能有软件在录制你的播放界面，可以在业务上做处理
            // PostMessage
        }, userdata);
        
        // 硬件设备变动的回调通知, 此回调可以用于防止 HDMI 硬件录制, 业务侧可以根据回调类型进行播放器是否禁播操作
        PLVSetDetectHardwareRecordingHandler(true, [](DEVICE_CHANGED_TYPE type, const char* device, void* data){
            // HDMI 设备有变动，请根据 type 类型判断，可能是 HDMI 设备在录制你的屏幕
            // PostMessage
        }, userdata);
    }
    // 软件防录制
    int SetPreventSoftwareRecording(void* window, bool enable){
        return PLVSetPreventSoftwareRecording(window, enable);
    }
    int GetPreventSoftwareRecording(void* window, bool* enable){
        return PLVGetPreventSoftwareRecording(window, enable);
    }
    
};
```

## SDK 下载器

视频下载的操作步骤及功能示例如下：

```cpp
// 注意通知回调都是子线程，如果更新 ui 及操作 api 都需要 post 到主线程
class Download{
private:
    PLVDownloadPtr downolader = nullptr;
public:
    Download(void){
        // 创建下载器
        downolader = PLVDownloadCreate();
        
        // 设置错误回调通知
        PLVDownloadSetErrorHandler(downolader, [](const char* vid, int code, void* data) {
            // 错误通知 code 为错误码
            // PostMessage
        }, userdata);
        // 设置下载进度回调通知
        PLVDownloadSetProgressHandler(downolader, [](const char* vid, long long receivedBytes, long long totalBytes, void* data) {
            // 下载进度
            // PostMessage
        }, userdata);
        // 设置下载结果回调通知
        PLVDownloadSetResultHandler(downolader, [](const char* vid, int rate, int code, void* data) {
            // 下载结果
            // PostMessage
        }, userdata);
    }
    ~Download(void){
        PLVDownloadDestroy(downolader);
        downolader = nullptr;
    }
    // 设置下载信息，操作前必须先调用此接口
    int SetInfo(const char* vid, const char* path, int rate){
        return PLVDownloadSetInfo(downolader, vid, path, rate);
    }
    // 开始下载
    // autoDownRate 是否自动降清晰度，false 如果没有这个清晰度则返回错误码
    int Start(const char* token, bool autoDownRate){
        return PLVDownloadStart(downolader, token, autoDownRate);
    }
    // 结束下载，退出线程
    int Stop(void){
        return PLVDownloadStop(downolader);
    }
    // 暂停下载，不退出线程，可以快速切换下载状态
    int Pause(bool pause){
        return PLVDownloadPause(downolader);
    }
    // 删除下载文件
    int Delete(void){
        return PLVDownloadDelete(downolader);
    }  
    // 取消所有回调设置
    int Reset(void){
        return PLVDownloadResetHandler(downolader);
    }
};
```

## SDK 播放器

视频播放的操作步骤及功能示例如下：

```cpp
// 注意通知回调都是子线程，如果更新 ui 及操作 api 都需要 post 到主线程
class Player{
private:
    PLVPlayer mediaPlayer = nullptr;
public:
    Player((void*)window){
        // 创建播放器
        mediaPlayer = PLVPlayerCreate(window);
        
        // 设置播放器的播放状态通知
        PLVPlayerSetStateHandler(mediaPlayer, [](const char* vid, int state, void* data) {
            // 播放器的状态，state 参见 PLAYER_MEDIA_STATE
            // PostMessage();
        }, userdata);
        // 设置视频的属性回调通知
        PLVPlayerSetPropertyHandler(mediaPlayer, [](const char* vid, int property, int format, const char* value, void* data) {
            // 播放器的属性值
            // PostMessage();
        }, userdata);
        // 设置码率清晰度变化通知 （只有输入的码率不存在，自动降值才会触发此通知）
        PLVPlayerSetRateChangeHandler(mediaPlayer, [](const char* vid, int inputBitRate, int realBitRate, void* data) {
            // 真实的清晰度，比如目标清晰度为超清，但不存在此清晰度，会自动降值为 realBitRate
            // PostMessage();
        }, userdata);
        // 设置播放器播放进度回调通知
        PLVPlayerSetProgressHandler(mediaPlayer, [](const char* vid, int millisecond, void* data) {
            // 播放位置
            // PostMessage();
        }, userdata);
        // 设置扬声器设备有热插拔的变动通知
        PLVPlayerSetAudioDeviceHandler(mediaPlayer, [](int audioDeviceCount, void* data) {
            // 扬声器设备变动，此为设备热插拔变动通知，可以 post 到主线程再调用 ReloadAudio();
            // PostMessage();
        }, userdata);
    }
    ~Player(void){
        PLVPlayerDestroy(mediaPlayer);
        mediaPlayer = nullptr;
    }
    
    // 设置跑马灯
    int SetOSD(bool enable, const PLVOsdConfigInfo* config){
        return PLVPlayerSetOSDConfig(mediaPlayer, enable, config);
    }
    int GetOSD(PLVOsdConfigInfo& config){
        return PLVPlayerGetOSDConfig(config);
    }
    // 设置 LOGO text
    int SetLogo(bool enable, const PLVLogoTextInfo* config);
    int GetLogo(PLVLogoTextInfo& config);
    // 设置缓存，可以不设置，播放器会有默认值
    int SetCache(bool enable, int maxCacheBytes, int maxCacheSeconds);
    int GetCache(int* maxCacheBytes, int* maxCacheSeconds);
    // 播放前要先设置 vid
    int SetInfo(const char* vid, const char* path, int rate);
    // 播放，token 外部获取，seekMillisecond 为要跳转到播放位置，sync 由于会先请求 vid 的信息，会有 http 请求，如果网络好请使用 true 同步，否则可以用 false
    int Play(const char* token, int seekMillisecond, bool autoDownRate, bool playWithToken, bool sync);
    // 本地播放
    int PlayLocal(int seekMillisecond, bool autoDownRate);
    // 本地加载，不播放
    int LoadLocal(int seekMillisecond, bool autoDownRate);
    int Pause(bool pause);
    int Stop(void);
    int SetMute(bool mute);
    // 跳转，由于视频文件都是经过后台编码过，关键帧会被优化，跳转会不准确。可以对比 mp4 与 m3u8，差别会比较大，mp4 拖动很准，m3u8 跳动很大。
    int SetSeek(int millisecond);
    // 跳转到结束，由于 m3u8 跳转不准，有需要跳转到尾部的请使用此接口
    int SeekToEnd(void);
    int SetVolume(int volume);
    // 声音增益，最大可到 1000
    int SetVolumeMax(int volume);
    // 倍数播放
    int SetSpeed(double speed);
    // 截图，注意使用 utf8
    int Screenshot(const char* filename);
       
    // 扬声器热插拔相关
    int GetAudioDeviceCount();
    int GetAudioDeviceInfo(int index, char deviceId[PLV_MAX_DEVICE_ID_LENGTH], char deviceName[PLV_MAX_DEVICE_ID_LENGTH]);
    int GetCurrentAudioDevice(char deviceId[PLV_MAX_DEVICE_ID_LENGTH]);
    int SetCurrentAudioDevice(const char deviceId[PLV_MAX_DEVICE_ID_LENGTH]);
};
```

## SDK 注意事项

1. 所有接口与路径相关，都必须使用 utf8 编码。
2. 所有回调通知，都不能在里面更新界面或者调用其它 api，更新界面必须 post 到 ui 线程，调用 api 必须在其它线程操作。
