基础能力使用
在 快速开始 中,我们完成了qplayer2播放器的创建\播放\销毁,本文介绍如何使用qplayer2的播放能力
播放
创建播放数据
QMedia::QMediaModelBuilder* pmodel_builder = new QMedia::QMediaModelBuilder;
//添加播放地址
pmodel_builder->add_stream_element(user_type, url_type, quality, url, is_selected, referer, back_up_url, render_type);
//添加字幕地址
pmodel_builder->add_subtitle_element(subtitle_name, subtitle_url,subtitle_is_selected);
//创建 QMediaModel
//is_live 是否是直播。true 直播,false 点播
//reconstruct_time_line 是否重构时间轴,true 重构,false 不重构
QMedia::QMediaModel* pmodel = pmodel_builder->build(is_live, reconstruct_time_line);
add_stream_element 属性说明
属性名 | 属性说明 |
---|---|
userType | 用户自定义Type,目前预留,可以填空字符串 |
url | 资源地址 |
urlType | 媒体的资源属性 只包含视频/只包含音频/同时有视频音频 |
quality | 清晰度 |
isSelected | 是否起播时播放该流 |
backupUrl | 备用地址 |
referer | http/https 协议的地址 支持该属性 |
renderType | 视频的渲染类型 |
hlsDrmKey | 私有DRM解密的key,用在私有hls加密视频播放的场景中 |
mp4DrmKey | mp4 drm 的解密 key 用于 CENC-AES-CTR 加密的视频播放场景中 |
mp4QNDrmComKey | mp4 七牛私有 drm 的解密 comkey 用于七牛私有 mp4 加密的视频播放场景中 |
mp4QNDrmFileKey | mp4 七牛私有 drm 的解密 filekey 用于七牛私有 mp4 加密的视频播放场景中 |
MP4 加密
目前 QPlayer2 支持七牛私有加密以及显式的 CENC-AES-CTR 加密,暂不支持隐式加密。CENC-AES-CTR 的初始化向量(IV) 由加密工具随机生成并存储在加密后的 MP4 文件中,QPlayer2 读取 MP4 文件的 IV 和QMediaModel 存储的 mp4DrmKey 进行解密。
播放 mp4 加密视频
QMedia::QMediaModelBuilder* pmodel_builder = new QMedia::QMediaModelBuilder;
//添加 CENC-AES-CTR 加密视频播放地址
pmodel_builder->add_stream_element_mp4_drm(user_type, url_type, quality, url, is_selected, referer, back_up_url,mp4_drm_key, render_type);
//添加 hls 加密视频播放地址
pmodel_builder->add_stream_element_hls_drm(user_type, url_type, quality, url, is_selected, referer, back_up_url,hls_drm, render_type);
//添加七牛私有 MP4 加密视频播放地址
pmodel_builder->add_stream_element_qn_mp4_drm(user_type, url_type, quality, url, is_selected, referer, back_up_url,mp4_qn_drm_com_key,mp4_qn_drm_file_key, render_type);
//添加字幕地址
pmodel_builder->add_subtitle_element(subtitle_name, subtitle_url,subtitle_is_selected);
//创建 QMediaModel
//is_live 是否是直播。true 直播,false 点播
//reconstruct_time_line 是否重构时间轴,true 重构,false 不重构
QMedia::QMediaModel* pmodel = pmodel_builder->build(is_live, reconstruct_time_line);
对 MP4 文件进行 CENC-AES-CTR 加密
可以选择 ffmpeg 对一个 MP4 进行加密。加密命令如下:
ffmpeg -i test2.mp4 -vcodec copy -acodec copy -encryption_scheme cenc-aes-ctr -encryption_key c7e16c4403654b85847037383f0c2db3 -encryption_kid a7e61c373e219033c21091fa607bf3b8 encrypted_IV_test.mp4
命令说明
test2.mp4 为输入文件
encrypted_IV_test.mp4 为输出文件
-vcodec copy 和 -acodec copy :指定视频流和音频流的编码方式为原始流的拷贝,即不进行重新编码,保持与原始文件相同的编码格式。
-encryption_scheme cenc-aes-ctr :设置加密方案为 CENC-AES-CTR,即采用 CTR 模式进行加密。
-encryption_key c7e16c4403654b85847037383f0c2db3 指定加密所使用的密钥,即解密所使用的 key。这里的c7e16c4403654b85847037383f0c2db3 是一个示例密钥,您可以替换为您自己的密钥,格式要求为:16字节的16进制数据。
-encryption_kid a7e61c373e219033c21091fa607bf3b8:指定加密所使用的密钥标识符(KID)。这里的 a7e61c373e219033c21091fa607bf3b8 是一个示例 KID,您可以替换为您自己的密钥标识符, 格式要求为:16字节的16进制数据。
加密后可通过ffplay 4.4 版本进行播放验证,播放正常即可。命令如下:
ffplay encrypted_IV_test.mp4 -decryption_key c7e16c4403654b85847037383f0c2db3
视频URL类型枚举
enum class QUrlType : uint32_t {
QAUDIO_AND_VIDEO = 0,
//仅包含音频
QAUDIO = 1,
//仅包含视频
QVIDEO = 2,
//无
NONE = 3
};
播放媒体资源
/// <summary>
/// 播放音视频资源
/// </summary>
/// <param name="pmedia_model"> 音视频资源 </param>
/// <param name="start_pos"> 起播时间戳 毫秒 </param>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->play_media_model(pmodel, 0);
播放错误监听
添加监听前实现接口 QIPlayerMediaNetworkListener 。当视频起播时,如果遇到网络等问题原因,导致没有和服务器建立链接,那么会导致视频播放失败,总共会有3次重试机会,3次都失败的情况下会回调onOpenFailed方法。
当视频已经起播后,在中途遇到网络等问题原因,进入buffer, 那么内核会一直重试,直到再次连接上服务端继续播放,或者用户通过接口停止播放该视频,在重试的过程中 onReconnectStart / onReconnectEnd 会被回调,那么可以监控回调的次数来做业务层的结束播放的策略,当然在正常播放的情况下,这两个方法也是会被回调的,所以最好结合buffer的回调数据一起使用。
/// <summary>
/// 开始重连
/// </summary>
/// <param name="user_type"> 重连 url 的 userType </param>
/// <param name="url_type">重连 url 的 urlType </param>
/// <param name="url"> 重连的 url </param>
/// <param name="retry_time"> 重连 url 的次数 </param>
void on_reconnect_start(const std::string & user_type, QMedia::QUrlType url_type, const std::string & url, int retry_time) override;
/// <summary>
/// 重连结束
/// </summary>
/// <param name="user_type"> 重连 url 的 userType </param>
/// <param name="url_type"> 重连 url 的 urlType </param>
/// <param name="url"> 重连的 url </param>
/// <param name="retry_time"></param>
/// <param name="error"> 重连 url 的次数 </param>
void on_reconnect_end(const std::string & user_type, QMedia::QUrlType url_type, const std::string & url, int retry_time, QMedia::QOpenError error) override;
/// <summary>
/// 打开失败
/// </summary>
/// <param name="user_type"> 打开失败 url 的 userType </param>
/// <param name="url_type"> 打开失败 url 的 urlType </param>
/// <param name="url"> 打开失败的 url </param>
/// <param name="error"> 打开失败 url 的 错误码 </param>
void on_open_failed(const std::string & user_type, QMedia::QUrlType url_type, const std::string & url, QMedia::QOpenError error) override;
void on_reconnect_start(const std::string &user_type, QMedia::QUrlType url_type, const std::string& url, int retry_time){
}
void on_reconnect_end(const std::string &user_type, QMedia::QUrlType url_type, const std::string& url, int retry_time, QMedia::QOpenError error) {
}
void on_open_failed(const std::string &user_type, QMedia::QUrlType url_type, const std::string& url, QMedia::QOpenError error){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_media_network_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_media_network_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_media_network_listeners();
播放错误码枚举
enum class QPLAYER_API QOpenError : int64_t {
UNKNOW = 10000,
NONE = 0,
IOERROR = -5,
INTERRUPT = -1414092869,
URL_INVALID = -875574520,
FORMAT_INVALID = -1094995529
};
暂停播放
/// <summary>
/// 暂停渲染
/// </summary>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->pause_render();
恢复播放
/// <summary>
/// 在暂停渲染状态下 恢复渲染
/// </summary>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->resume_render();
停止当前视频播放
/// <summary>
/// 停止当前视频播放
/// </summary>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->stop();
鉴权
鉴权功能介绍见鉴权相关文档
强制网络鉴权
调用该接口时,会强制进行网络鉴权
/// <summary>
/// 下一次鉴权强制通过网络鉴权
/// </summary>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->force_authentication_from_network();
鉴权监听
添加监听前实现接口 QIPlayerAuthenticationListener 协议。
/// <summary>
/// 鉴权失败
/// </summary>
/// <param name="error"> 鉴权失败错误码 </param>
void on_authentication_failed(QMedia::QAuthenticationErrorType error) override;
/// <summary>
/// 鉴权成功
/// </summary>
void on_authentication_success() override;
void on_authentication_failed(QMedia::QAuthenticationErrorType error){
}
void on_authentication_success(){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_authentication_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_authentication_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_authentication_listeners();
鉴权错误码枚举
enum class QPLAYER_API QAuthenticationErrorType : uint32_t {
NONE = 0, //鉴权出错
NO_BASE_AUTH = 1, //缺少基础功能权限
NO_VR_AUTH = 2, //缺少 VR 功能权限
NO_BLIND_AUTH = 3, //缺少色盲功能权限
NO_SEI_AUTH = 4, //缺少 SEI 功能权限
NO_SRT_AUTH = 5 //缺少 SRT 功能权限
};
切换视频进度
参数为要定位的position 单位毫秒
/// <summary>
/// seek
/// </summary>
/// <param name="position"> seek 的位置 单位 ms </param>
/// <returns></returns>
mpPlayerWindow->get_control_handler()->seek(100);
切换视频进度结果监听
添加监听前实现接口 QIPlayerSeekListener
/// <summary>
/// seek 成功回调
/// </summary>
void on_seek_success() override;
/// <summary>
/// seek 失败回调
/// </summary>
void on_seek_failed() override;
void on_seek_success() {
}
void on_seek_failed() {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_seek_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_seek_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_seek_listeners();
视频解码方式
目前支持的解码方式有:软解、硬解、自动,一般情况下,使用自动,内核会根据手机的硬件情况,要播放的视频资源编码格式等信息,挑选合适的解码方式进行解码,各个解码方式的优劣情况如下
软解: 解码较慢,但是兼容性好,适用于所有手机
硬解:解码性能高,但是有一定兼容性,比如某些视频资源的编码格式,硬解芯片不支持。并且相对于软解,首帧的速度慢。
设置优先选择哪种解码方式
设置完成后下一次播放生效.
最终的解码方式可能不是设置的,在设置的解码方式不能正确解码时,内核会进行降级,选择其他能正确解码的方式
/// <summary>
/// 设置解码方式
/// </summary>
/// <param name="type"> 解码方式 </param>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->set_decode_type(QMedia::QPlayerSetting::QPlayerDecoder::QPLAYER_DECODER_SETTING_AUTO);
优先选择的解码方式枚举
该枚举主要用于设置解码方式
enum class QPLAYER_API QPlayerDecoder : uint16_t
{
//自动选择
QPLAYER_DECODER_SETTING_AUTO = 0,
//硬解优先
QPLAYER_DECODER_SETTING_HARDWARE_PRIORITY = 1,
//软解优先
QPLAYER_DECODER_SETTING_SOFT_PRIORITY = 2,
};
播放器视频解码监听相关
添加监听前实现接口 QIPlayerVideoDecodeListender 协议。
/// <summary>
/// 播放器解码类型回调
/// </summary>
/// <param name="type"> 解码类型 </param>
void on_video_decode_by_type(QMedia::QDecoderType type) override;
/// <summary>
/// 解码失败回调
/// </summary>
/// <param name="retry"> 是否降级重试成功 true 是 false 否 </param>
void on_decode_failed(bool retry) override;
/// <summary>
/// 如果当前视频解码所在设备或者 sdk 不支持,则回调该函数
/// </summary>
/// <param name="codec_id"> 视频解码的 id </param>
void on_not_support_codec_format(int codec_id) override;
void on_video_decode_by_type(QMedia::QDecoderType type) {
}
void on_decode_failed(bool retry) {
}
void on_not_support_codec_format(int codec_id) {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_video_decode_type_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_video_decode_type_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_video_decode_type_listeners();
解码方式枚举
该枚举主要用于监听返回的解码方式
enum class QPLAYER_API QDecoderType : uint32_t {
NONE = 0,
SOFTWARE = 1,
HARDWARE = 31
};
设置起播方式
下一次播放生效
/// <summary>
/// 设置起播方式
/// </summary>
/// <param name="action"> 起播方式 </param>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->set_start_action(QMedia::QPlayerSetting::QPlayerStart::QPLAYER_START_SETTING_PLAYING);
起播方式枚举
enum class QPlayerStart : uint16_t {
//起播播放
QPLAYER_START_SETTING_PLAYING = 0,
//起播暂停在首帧
QPLAYER_START_SETTING_PAUSE = 1,
};
设置 seek 方式
下一次播放生效
/// <summary>
/// 设置seek方式
/// </summary>
/// <param name="mode"> seek方式 </param>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->set_seek_mode(QMedia::QPlayerSetting::QPlayerSeek::QPLAYER_SEEK_SETTING_NORMAL);
seek方式枚举
enum class QPlayerSeek : uint16_t {
//关键帧seek,每次seek 都seek到离目标位置向前的最近的一个关键帧,耗时少
QPLAYER_SEEK_SETTING_NORMAL = 0,
//精准seek,耗时比关键帧seek多,且耗时和视频的gop间隔的大小成正比
QPLAYER_SEEK_SETTING_ACCURATE = 1
};
播放器状态
在整个播放器实例生命周期中,播放会在不同的状态中切换,用户可以通过监听播放器状态,实现上层业务逻辑,
比如在视频播放完时,展示其他视频的推荐页,那么只需监听播放器状态回调,待回调的状态是COMPLETED,则展示推荐页
播放器状态枚举
enum class QPLAYER_API QPlayerState : uint32_t {
NONE = 0,//初始状态
INIT = 1,//播放器开始创建各种对象 没有对应的state 创建完对象就上报这个状态
PREPARE = 2,//开始拉视频数据解码变换等,重新换地址后,都走这个状态
PLAYING = 4,//播放中
PAUSED_RENDER = 6,//用户暂停
COMPLETED = 7,//播放完成
SEEKING = 8, //SEEK
STOPPED = 9,//播放器停止中
MISTAKE = 10,//播放出错(是否需要分 可恢复 和 不可恢复 )
END = 11,//播放器释放各种对象完成
MEDIA_ITEM_PREPARE = 12, //开始拉视频数据解码变换等,重新换地址后,都走这个状态 针对Media Item的play 方式
RELEASE = 13 //播放器结束,且释放各类资源
};
播放器状态变更监听相关
添加监听前需要签订QIPlayerStateChangeListener协议。
/// <summary>
/// 当前的播放状态发生改变时回调
/// </summary>
/// <param name="state"> 当前的播放状态 </param>
void on_state_changed(QMedia::QPlayerState state) override;
void on_state_changed(QMedia::QPlayerState state) {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_state_change_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_state_change_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_state_change_listeners();
播放速度
播放速度的调整范围建议在0.25-2.0之间,这样会有一个比较好的效果
设置播放速度
参数为倍速值
/// <summary>
/// 设置播放速度
/// </summary>
/// <param name="speed"> 需要设置的倍速 </param>
/// <returns> true: 调用成功 false: 调用失败 </returns>
mpPlayerWindow->get_control_handler()->set_speed(0.5);
速度变更监听相关
添加监听前实现接口 QIPlayerSpeedListener
/// <summary>
/// 播放速度改变回调
/// </summary>
/// <param name="speed"> 当前的播放速度 </param>
void on_speed_changed(float speed) override;
void on_speed_changed(float speed) {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_speed_change_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_speed_change_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_speed_change_listeners();
清晰度
QPlayer2 提供的清晰度能力是无缝切换清晰度方案,在切换过程中,画面是连续的画面,不会出现类似跳帧的情况。
使用无缝切换清晰度功能,必须在 mediaModel 中配置多路清晰度,如果使用非 immediately 方式(即异步方式)时,同时只能有一次切换会话存在,会话结束后,才能切下一次
切换视频清晰度
/// <summary>
/// 切换清晰度,针对一个视频由多路url流组成的情况下,可以按找流来进行清晰度切换,
/// 比如一个视频由2路url组成,一路视频,一路音频,那么可以只切换音频路的url达到音频的清晰度切换,也可以
/// 只切换视频路的url达到视频的清晰度切换。
/// </summary>
/// <param name="user_type"> 要切换的url流的userType </param>
/// <param name="url_type"> 要切换的url流的urlType </param>
/// <param name="quality_index"> 要切换到哪一路清晰度 </param>
/// <param name="immediately"> true: 立即切换,直播情况下
mpPlayerWindow->get_control_handler()->switch_quality(pinner_ele->get_user_type(), pinner_ele->get_url_type(), 1080, true);
播放器清晰度相关监听
添加监听前实现接口 QIPlayerQualityListener
/// <summary>
/// 开始切换清晰度
/// </summary>
/// <param name="user_type"> 切换清晰度的 URL 的 userType </param>
/// <param name="url_type"> 切换清晰度的 URL 的 urlType </param>
/// <param name="old_quality"> 切换清晰度前的清晰度 </param>
/// <param name="new_quality"> 切换清晰度后的清晰度 </param>
void on_quality_switch_start(const std::string & user_type, QMedia::QUrlType url_type, int old_quality, int new_quality) override;
/// <summary>
/// 清晰度切换完成
/// </summary>
/// <param name="user_type"> 切换清晰度的 URL 的 userType </param>
/// <param name="url_type"> 切换清晰度的 URL 的 urlType </param>
/// <param name="old_quality"> 切换清晰度前的清晰度 </param>
/// <param name="new_quality"> 切换清晰度后的清晰度 </param>
void on_quality_switch_complete(const std::string & user_type, QMedia::QUrlType url_type, int old_quality, int new_quality) override;
/// <summary>
/// 清晰度切换取消
/// </summary>
/// <param name="user_type"> 切换清晰度的 URL 的 userType </param>
/// <param name="url_type"> 切换清晰度的 URL 的 urlType </param>
/// <param name="old_quality"> 切换清晰度前的清晰度 </param>
/// <param name="new_quality"> 切换清晰度后的清晰度 </param>
void on_quality_switch_canceled(const std::string & user_type, QMedia::QUrlType url_type, int old_quality, int new_quality) override;
/// <summary>
/// 清晰度切换失败
/// </summary>
/// <param name="user_type"> 切换清晰度的 URL 的 userType </param>
/// <param name="url_type"> 切换清晰度的 URL 的 urlType </param>
/// <param name="old_quality"> 切换清晰度前的清晰度 </param>
/// <param name="new_quality"> 切换清晰度后的清晰度 </param>
void on_quality_switch_failed(const std::string & user_type, QMedia::QUrlType url_type, int old_quality, int new_quality) override;
/// <summary>
/// 目前仅支持同时有一个清晰度切换事件,如果前一个切换还未完成,再次切换清晰度,则会回调该函数
/// </summary>
/// <param name="user_type"> 切换清晰度的 URL 的 userType </param>
/// <param name="url_type"> 切换清晰度的 URL 的 urlType </param>
void on_quality_switch_retry_later(const std::string & user_type, QMedia::QUrlType url_type) override;
void on_quality_switch_start(const std::string & user_type, QMedia::QUrlType url_type, int old_quality, int new_quality) {
}
void on_quality_switch_complete(const std::string & user_type, QMedia::QUrlType url_type, int old_quality, int new_quality) {
}
void on_quality_switch_canceled(const std::string & user_type, QMedia::QUrlType url_type, int old_quality, int new_quality) {
}
void on_quality_switch_failed(const std::string & user_type, QMedia::QUrlType url_type, int old_quality, int new_quality) {
}
void on_quality_switch_retry_later(const std::string & user_type, QMedia::QUrlType url_type) {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_quality_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_quality_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_quality_listeners();
直播支持多路清晰度切换
无缝切换清晰度方案需要配置以下三个条件
- 首先切换的模式要选择立即切换即:immediately=true
- 服务端配置PTS透传,
- 对应的清晰度要做主动转码设置
如果无法满足以上3个条件,那么建议用最基础的能力来实现清晰度切换,即每个清晰度都是一个media model,切换时,调用playMediaModel来播放新的清晰度流。
视频宽高改变监听
在视频首帧渲染时,会调用该回调,告诉上层当前的视频宽高是多少,如果在这个这个视频播放的生命周期中,宽高改变,那么还会再次调用该回调.
添加监听前实现接口 QIPlayerVideoFrameSizeChangeListener。
/// <summary>
/// 推流端视频长宽变化回调
/// </summary>
/// <param name="width"> 宽度 </param>
/// <param name="height"> 高度 </param>
void on_video_frame_size_changed(int width, int height) override;
void on_video_frame_size_changed(int width, int height){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_video_frame_size_change_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_video_frame_size_change_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_video_frame_size_change_listeners();
播放进度监听
添加监听前实现接口 QIPlayerProgressListener
只有在点播的时候 duration 和 progress 才有意义,直播的话这两个值没有参考意义
/// <summary>
/// 进度变更回调
/// </summary>
/// <param name="progress"> 当前进度 单位:毫秒 </param>
/// <param name="duration"> 当前视频总时长 单位: 毫秒 </param>
void on_progress_changed(int64_t progress, int64_t duration) override;
void on_progress_changed(int64_t progress, int64_t duration) {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_progress_change_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_progress_change_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_progress_change_listeners();
实时帧率
实时帧率监听
添加监听前实现接口 QIPlayerFPSListener
/// <summary>
/// fps 改变回调
/// </summary>
/// <param name="fps"> fps 帧率 </param>
void on_fps_changed(long fps) override;
void on_fps_changed(long fps) {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_fps_change_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_fps_change_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_fps_change_listeners();
像素格式或者音频sample格式不支持的监听
添加监听前实现接口 QIPlayerFormatListener
/// <summary>
/// 当前有 format 不支持,视频无法播放
/// </summary>
void on_format_not_support() override;
void on_format_not_support() {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_format_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_format_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_format_listeners();
缓冲拉流监听
添加监听前实现接口 QIPlayerDownloadListener
/// <summary>
/// 下载数据变化回调
/// </summary>
/// <param name="download_speed"> 下载速度 </param>
/// <param name="buffer_pos"> 缓冲进度 </param>
void on_download_changed(int64_t download_speed, int64_t buffer_pos) override;
void on_download_changed(int64_t download_speed, int64_t buffer_pos){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_download_change_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_download_change_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_download_change_listeners();
播放器操作不允许执行监听
添加监听前实现接口 QIPlayerCommandNotAllowListener 。在某些状态下,一些操作将不被执行,通过该监听回调上来通知
/// <summary>
/// 操作不被允许的回调
/// </summary>
/// <param name="command_name"> 操作名称 </param>
/// <param name="state"> 操作被检测时播放器的状态 </param>
void on_command_not_allow(const std::string& command_name, QMedia::QPlayerState state) override;
void on_command_not_allow(const std::string& command_name, QMedia::QPlayerState state){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_command_not_allow_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_command_not_allow_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_command_not_allow_listeners();
buffering 监听
添加监听前实现接口 QIPlayerBufferingListener
/// <summary>
/// buffering 开始通知
/// </summary>
void on_buffering_start() override;
/// <summary>
/// buffering 结束通知
/// </summary>
void on_buffering_end() override;
void on_buffering_start(){
}
void on_buffering_end(){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_buffering_change_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_buffering_change_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_buffering_change_listeners();
静音播放
控制播放器静音,且该静音非系统的声音设置,仅仅只是把播放器设置为静音
设置静音播放
mpPlayerWindow->get_control_handler()->set_mute(false);
静音播放相关监听
添加监听前实现接口 QIPlayerAudioListener
/// <summary>
/// 静音状态改变回调
/// </summary>
/// <param name="is_mute"> 是否静音 true 静音 false 非静音 </param>
void on_mute_changed(bool is_mute) override;
void on_mute_changed(bool is_mute){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_audio_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_audio_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_audio_listeners();
截图
调用截图接口,就会回调截图时的video画面,并以jpeg的格式返回
mpPlayerWindow->get_control_handler()->shoot_video();
截图图片类型枚举
enum class QPLAYER_API QShootVideoType : uint32_t {
NONE = 0,
JEPG = 1
};
截图相关监听
添加监听前实现接口 QIPlayerShootVideoListener
/// <summary>
/// 截图成功回调
/// </summary>
/// <param name="image_data"> 图片数据 </param>
/// <param name="size"> 图片数据的长度 </param>
/// <param name="width"> 图片的宽度 </param>
/// <param name="height"> 图片的高度 </param>
/// <param name="type"> 图片类型 </param>
void on_shoot_video_success(const std::unique_ptr<uint8_t[]>& image_data, uint64_t size, int width, int height, QMedia::QShootVideoType type) override;
/// <summary>
/// 截图失败回调
/// </summary>
void on_shoot_video_failed() override;
void on_shoot_video_success(const std::unique_ptr<uint8_t[]>& image_data, uint64_t size, int width, int height, QMedia::QShootVideoType type){
}
void on_shoot_video_failed(){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_shoot_video_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_shoot_video_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_shoot_video_listeners();
码率
实时码率监听
添加监听前实现接口 QIPlayerBiteRateListener
/// <summary>
/// 码率变化回调
/// </summary>
/// <param name="bit_rate"> 码率 单位:bps </param>
void on_bite_rate_changed(int bit_rate) override;
void on_bite_rate_changed(int bit_rate) {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_bite_rate_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_bite_rate_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_bite_rate_listeners();
SEI 数据回调
用户自定义数据可以带在H264或者H265的编码帧里,用于实现一些基于时间轴的业务场景。
开启该功能后,如果视频资源内带有SEI数据 会通过监听接口抛给业务层。
该功能需要单独开通,具体可以联系技术支持咨询。
开启 SEI
mpPlayerWindow->get_control_handler()->set_sei_enable(true);
SEI 数据监听
添加监听前实现接口 QIPlayerSEIDataListener
/// <summary>
/// SEI 数据回调,且回调时机为 SEI 数据所在帧的时间
/// </summary>
/// <param name="data"> SEI 数据 </param>
/// <param name="size"> SEI 数据的长度 </param>
void on_sei_data(const std::unique_ptr<uint8_t[]>& data, uint64_t size) override;
void on_sei_data(const std::unique_ptr<uint8_t[]>& data, uint64_t size){
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_sei_data_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_sei_data_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_sei_data_listeners();
渲染相关监听
添加监听前实现接口 QIPlayerRenderListener
/// <summary>
/// 首帧耗时回调
/// </summary>
/// <param name="elapsed_time"> 从 play_media_model 开始到首帧渲染出来的总耗时 单位:毫秒 </param>
void on_first_frame_rendered(int64_t elapsed_time) override;
void on_first_frame_rendered(int64_t elapsed_time){
}
//添加监听
mpPlayerWindow->get_render_handler()->add_render_listener(this);
//移除监听
mpPlayerWindow->get_render_handler()->remove_render_listener(this);
//移除所有监听
mpPlayerWindow->get_render_handler()->remove_all_render_listeners();
视频数据上抛相关监听
添加监听前实现接口 QIPlayerVideoDataListener
/// 视频数据上抛回调
/// </summary>
/// <param name="width"> 视频宽度 </param>
/// <param name="height"> 视频高度 </param>
/// <param name="video_type"> 视频类型 </param>
/// <param name="buffer"> 视频数据 </param>
/// <param name="size"> 视频数据长度 </param>
void on_video_data(int width, int height, QMedia::QVideoType video_type, const std::unique_ptr<uint8_t[]>& buffer, uint64_t size) override;
void on_video_data(int width, int height, QMedia::QVideoType video_type, const std::unique_ptr<uint8_t[]>& buffer, uint64_t size){
}
//添加监听
mpPlayerWindow->get_render_handler()->add_player_video_data_listener(this);
//移除监听
mpPlayerWindow->get_render_handler()->remove_player_video_data_listener(this);
//移除所有监听
mpPlayerWindow->get_render_handler()->remove_all_player_video_data_listeners();
音频数据上抛相关监听
添加监听前实现接口 QIPlayerAudioDataListener
/// 音频数据回调
/// </summary>
/// <param name="sample_rate"> 采样率 </param>
/// <param name="format"> 格式 </param>
/// <param name="channel_num"> 通道数 </param>
/// <param name="channel_layout"> 声道 </param>
/// <param name="audio_data"> 音频数据 </param>
/// <param name="size">数据大小</param>
void on_audio_data(int sample_rate, QMedia::QSampleFormat format, int channel_num, QMedia::QChannelLayout channel_layout, const std::unique_ptr<uint8_t[]>& audio_data, uint64_t size) override;
void on_audio_data(int sample_rate, QMedia::QSampleFormat format, int channel_num, QMedia::QChannelLayout channel_layout, const std::unique_ptr<uint8_t[]>& audio_data, uint64_t size){
}
//添加监听
mpPlayerWindow->get_render_handler()->add_player_audio_data_listener(this);
//移除监听
mpPlayerWindow->get_render_handler()->remove_player_audio_data_listener(this);
//移除所有监听
mpPlayerWindow->get_render_handler()->remove_all_player_audio_data_listeners();
设置视频渲染比例
mpPlayerWindow->get_render_handler()->set_render_ratio(QMedia::QPlayerSetting::QPlayerRenderRatio::QPLAYER_RATIO_SETTING_AUTO);
视频比例枚举
enum class QPlayerRenderRatio : uint16_t {
//自动
QPLAYER_RATIO_SETTING_AUTO = 1,
//拉升
QPLAYER_RATIO_SETTING_STRETCH = 2,
//铺满
QPLAYER_RATIO_SETTING_FULL_SCREEN = 3,
//16:9
QPLAYER_RATIO_SETTING_16_9 = 4,
//4:3
QPLAYER_RATIO_SETTING_4_3 = 5
};
设置色觉优化
mpPlayerWindow->get_render_handler()->set_blind_type(QMedia::QPlayerSetting::QPlayerBlind::QPLAYER_BLIND_SETTING_NONE);
色觉优化枚举
enum class QPlayerBlind : uint16_t {
//无
QPLAYER_BLIND_SETTING_NONE = 0,
//红色盲
QPLAYER_BLIND_SETTING_RED = 1,
//绿色盲
QPLAYER_BLIND_SETTING_GREEN = 2,
//蓝色盲
QPLAYER_BLIND_SETTING_BLUE = 3
};
字幕
字幕数据设置
//添加字幕地址
pmodel_builder->add_subtitle_element(subtitle_name, subtitle_url,subtitle_is_selected);
设置是否开启字幕
mpPlayerWindow->get_control_handler()->set_subtitle_enable(false);
设置字幕名称
mpPlayerWindow->get_control_handler()->set_subtitle("English");
字幕监听
添加监听前实现接口 QIPlayerSubtitleListener
/// <summary>
/// 字幕文本回调
/// </summary>
/// <param name="text"> 当前字幕的文本 </param>
void on_subtitle_text_changed(const std::string & text) override;
/// <summary>
/// 字幕切换回调
/// </summary>
/// <param name="name"> 当前的字幕名称 </param>
void on_subtitle_name_changed(const std::string & name) override;
/// <summary>
/// 字幕开启状态改变回调
/// </summary>
/// <param name="enable"> 当前字幕是否开启 true 开启 false 关闭 </param>
void on_subtitle_enable(bool enable) override;
/// <summary>
/// 字幕加载结果回调
/// </summary>
/// <param name="name"> 字幕名称 </param>
/// <param name="result"> 字幕加载结果 true 成功 false 失败 </param>
void on_subtitle_loaded(const std::string & name, bool result) override;
/// <summary>
/// 字幕解码结果回调
/// </summary>
/// <param name="name"> 字幕名称 </param>
/// <param name="result"> 字幕解码结果 true 成功 false 失败 </param>
void on_subtitle_decoded(const std::string & name, bool result) override;
void on_subtitle_text_changed(const std::string & text) {
}
void on_subtitle_name_changed(const std::string & name) {
}
void on_subtitle_enable(bool enable) {
}
void on_subtitle_loaded(const std::string & name, bool result) {
}
void on_subtitle_decoded(const std::string & name, bool result) {
}
//添加监听
mpPlayerWindow->get_control_handler()->add_player_subtitle_listener(this);
//移除监听
mpPlayerWindow->get_control_handler()->remove_player_subtitle_listener(this);
//移除所有监听
mpPlayerWindow->get_control_handler()->remove_all_player_subtitle_listeners();