一、组件简介
·首帧秒开:首帧时间是短视频类应用核心指标之一,直接影响用户的观看体验。短视频组件通过预播放、预下载、播放器复用和精准流量控制等技术,实现极速首帧、滑动丝滑的优质播放体验,从而提升用户播放量和停留时长。
·优异的性能:通过播放器复用和加载策略的优化,在保证极佳流畅度的同时,始终让内存和 CPU 消耗保持在较低的水平。
·快速集成:组件对复杂的播放操作进行了封装,提供默认的播放 UI,同时支持 FileId 和 URL 播放,可低成本快速集成到你的项目中。
二、效果对比
从下方示例视频你可以看到在接入短视频最佳策略前后的对比差异。
·优化前有明显的首帧卡顿感。
·优化后播放流畅丝滑,优化后启播平均时长达到10毫秒 – 30毫秒。
| 未优化短视频 | 优化后短视频 |
| | |
三、TUIPlayerKit 下载
TUIPlayerKit SDK 和 Demo 可 单击这里 下载。
五、1. 依赖库
TUIPlayerShortVideo 依赖的 SDK 有:
·TUIPlayerCore
·TXLiteAVSDK ≥ 11.4
·SDWebImage
·Masonry
六、2. 环境要求
·系统版本:≥ iOS 9.0
·开发环境:≥ Xcode 14.0 ( 推荐使用最新版本)
七、3. 集成 TUIPlayerCore
解压下载的 TUIPlayerKit 资源包,将 TUIPlayerCore.xcframework 组件 SDK 添加到你项目中 Xcode Project 的合适位置并选择合适的 target,同时勾选 Do Not Embed 。
八、4. 集成 TUIPlayerShortVideo
解压下载的 TUIPlayerKit 资源包,将 TUIPlayerShortVideo.xcframework 组件 SDK 添加到你项目中 Xcode Project 的合适位置并选择合适的 target,同时勾选 Do Not Embed 。
九、5. 集成 TXLiteAVSDK
TXLiteAVSDK 集成方法请参见 TXLiteAVSDK 集成指引。
十、6. 集成 SDWebImage
SDWebImage 的下载和集成请参见 GitHub 指引。
十一、7. 集成 Masonry
Masonry 的下载和集成请参见 GitHub 指引。
十二、8. Pod 方式集成
如果你的项目支持 pod,那么也可以通过我们提供的 spec 文件集成,如下:
pod 'TUIPlayerShortVideo' ,:path => '../../../SDK/TUIPlayerShortVideoSDK/'pod 'TUIPlayerCore' ,:path => '../../../SDK/TUIPlayerCoreSDK/'
十五、1.1. 配置播放器高级版 License
使用 TUIPlayer Kit 组件需要使用移动端播放器高级版 License,你可参见 移动端播放器 License 指引获取。若你已获取对应 License,可前往 腾讯云视立方控制台 > License 管理 > 移动端 License 获取对应 LicenseURL 和 LicenseKey。如果没有申请移动端播放器高级版 License,将会出现视频播放失败、黑屏等现象。
调用相关功能之前,在你的项目中配置 License。引用 TUIPlayerCore 模块建议在 – [AppDelegate application:didFinishLaunchingWithOptions:] 中,做如下配置:
NSString * const licenceURL = @"<获取到的licenseUrl>";NSString * const licenceKey = @"<获取到的key>";[TXLiveBase setLicenceURL:licenceUrl key:licenceKey];[[TXLiveBase sharedInstance] setDelegate:self];
十六、1.2. 播放
初始化 TUIShortVideoView,举例如下:
- (TUIShortVideoView *)videoView { if (!_videoView) { ///设置自定义UI TUIPlayerShortVideoUIManager *uiManager = [[TUIPlayerShortVideoUIManager alloc] init]; [uiManager setControlViewClass: TUIPlayerShortVideoControlView.class]; [uiManager setControlViewClass: TUIPSControlLiveView.class viewType:TUI_ITEM_VIEW_TYPE_LIVE]; [uiManager setControlViewClass: TUIPSControlCustomView.class viewType:TUI_ITEM_VIEW_TYPE_CUSTOM]; [uiManager setLoadingView:[[TUIPSDLoadingView alloc] init]]; _videoView = [[TUIShortVideoView alloc] initWithUIManager:uiManager]; _videoView.delegate = self; _videoView.customCallbackDelegate = self; //_videoView.isAutoPlay = NO; // Set your playback strategy TUIPlayerVodStrategyModel *model = [[TUIPlayerVodStrategyModel alloc] init]; model.mPreloadConcurrentCount = 1; model.preDownloadSize = 1; model.enableAutoBitrate = NO; model.isLastPrePlay = YES; // live strategy TUIPlayerLiveStrategyModel *liveStrategyModel = [[TUIPlayerLiveStrategyModel alloc] init]; liveStrategyModel.isLastPrePlay = YES; [_videoView setShortVideoLiveStrategyModel:liveStrategyModel]; } return _videoView;}
将 TUIShortVideoView 的实例添加到你想呈现的 View 上,参见如下代码:
videoView.frame = self.view.bounds;[self.view addSubview:self.videoView];
然后添加你的视频数组:
TUIPlayerVideoModel *model1 = [[TUIPlayerVideoModel alloc] init]; ///视频数据TUIPlayerLiveModel *model2 = [[TUIPlayerLiveModel alloc] init]; ///直播数据TUIPlayerDataModel *model3 = [[TUIPlayerDataModel alloc] init]; ///自定义数据/// 这里根据你的业务情况,自行决定每一页的数据量NSArray *videos1 = @[model1,model2,model3];[self.videoView setShortVideoModels:videos1];
第一组视频播放完之后你还需要在 TUIShortVideoViewDelegate 的代理方法内继续拼入你的第二组视频数据:
TUIPlayerVideoModel *model1 = [[TUIPlayerVideoModel alloc] init]; ///视频数据TUIPlayerLiveModel *model2 = [[TUIPlayerLiveModel alloc] init]; ///直播数据TUIPlayerDataModel *model3 = [[TUIPlayerDataModel alloc] init]; ///自定义数据/// 这里根据你的业务情况,自行决定每一页的数据量NSArray *videos2 = @[model1,model2,model3];-(void)onReachLast { ///这里你可以做数据index索引记录,继续拼入你的第 3 4 5 6….组数据 [self.videoView appendShortVideoModels:videos2];}
十七、1.3. TUIShortVideoView
TUIShortVideoView 主要接口如下:
| 参数名称 | 含义 |
| isAutoPlay | 首次加载是否自动播放第一个视频,默认 YES。 |
| videos | 只读属性,获取当前存在于视频列表中的数据。 |
| currentVideoModel | 当前正在播放的视频模型。 |
| currentVideoIndex | 当前正在播放的视频索引。 |
| currentPlayerStatus | 当前播放器的播放状态。 |
| isPlaying | 当前播放器是否正在播放。 |
| delegate | 代理。 |
| refreshControl | 设置下拉刷新控件。 |
| initWithUIManager | 初始化(带自定义 UI)。 |
| setShortVideoStrategyModel | 设置直播播放策略。 |
| setShortVideoLiveStrategyModel | 设置直播播放策略。 |
| setShortVideoModels | 首次设置数据源。 |
| appendShortVideoModels | 追加视频数据源。 |
| removeAllVideoModels | 删除所有视频数据。 |
| setPlaymode | 视频播放模式,单个循环或列表循环,默认前者。 |
| pause | 暂停。 |
| resume | 继续播放。 |
| destoryPlayer | 销毁播放器。 |
| didScrollToCellWithIndex | 跳到指定索引的视频。 |
| startLoading | 展示 loading 图。 |
| stopLoading | 隐藏 loading 图。 |
| currentPlayerSupportedBitrates | 当前正在播放的视频支持的码率。 |
| bitrateIndex | 获取当前正在播放的码率索引。 |
| switchResolution:index: | 切换分辨率。 |
| pausePreload | 暂停预加载。 |
| resumePreload | 恢复预加载。 |
| getDataManager | 获取数据管理器。 |
| getVodStrategyManager | 获取点播策略管理器。 |
| getLiveStrategyManager | 获取直播策略管理器。 |
| setPlayRate: | 设置当前播放器倍速(2.1.0.28版本新增)。 |
TUIShortVideoViewDelegate 主要接口如下:
| 参数名称 | 含义 |
| scrollViewDidScrollContentOffset: | 列表滑动中回调内容的偏移量。 |
| scrollViewDidEndDeceleratingIndex:videoModel: | 手动滑动停止回调当前索引和数据模型。 |
| scrollToVideoIndex:videoModel: | 手动/代码滑动回调将要播放的索引和数据模型。 |
| onReachLast | 需要加载下一页回调,回调时机跟 TUIPlayerVodStrategyModel/mPreloadConcurrentCount 相关。 例如:mPreloadConcurrentCount=3时,此方法会在视频组的倒数第三个回调提醒加载新的一页数据。 |
| currentVideo:statusChanged: | 视频播放器状态回调。 |
| currentVideo:currentTime:totalTime:progress: | 视频播放器进度回调。 |
| onNetStatus:withParam: | 视频播放器网络状态回调。 |
| videoPreLoadStateWithModel: | 视频预加载回调。 |
| shortVideoView:willDefocusVideo:context: | 即将反聚焦视频。 |
| shortVideoView:didEndScrollingAnimationWithIndex:videoModel: | 自动滚动停止回调(2.1.0.44版本新增)。 |
| shortVideoView:playerDidReady:videoModel: | 播放器 ready 回调(加载前),可做播放器配置(2.1.0.44版本新增)。 |
| shortVideoView:widgetFrameForVideoModel:containerSize: | 获取外部指定的播放器 widget 位置信息(已废弃)。 |
| shortVideoView:widgetFrameWithParam: | 获取外部指定的播放器 widget 位置信息,在播放器拉取到视频分辨率后调用(2.2.0版本支持)。 |
十八、2. 全局配置
你可以通过 TUIPlayerConfig 模型在 TUIPlayerCore 里设置一些全局配置。
TUIPlayerConfig 主要参数参见下表:
| 参数名称 | 含义 |
| enableLog | 是否允许打印日志,默认 NO。 |
然后通过 TUIPlayerCore 进行全局配置:
TUIPlayerConfig *config = [TUIPlayerConfig new];config.enableLog = YES;[[TUIPlayerCore shareInstance] setPlayerConfig:config];
20、3.1. 点播播放策略设置
你可以通过 TUIPlayerVodStrategyModel 模型配置点播的播放策略。
TUIPlayerVodStrategyModel 主要参数参见下表:
| 参数名称 | 含义 |
| mPreloadConcurrentCount | 视频缓存个数,默认3。 |
| mPreloadBufferSizeInMB | 预播放大小,单位 MB,默认0.5MB。 |
| preferredResolution | 偏好分辨率,默认720 * 1280。 |
| progressInterval | 进度条回调间隔时长,单位毫秒,默认500ms。 |
| renderMode | 画布填充样式,默认图像适应屏幕,保持画面完整。 |
| extInfoMap | 额外参数,预留。 |
| enableAutoBitrate | 是否开启自适应码率,默认 NO。 |
| mediaType | 设置媒资类型。 |
| maxBufferSize | 最大预加载大小,单位 MB ,默认10MB,此设置会影响 playableDuration,设置越大,提前缓存的越多。 |
| mResumeModel | 续播模式,默认 TUI_RESUM_MODEL_NONE。 |
| preDownloadSize | 预下载大小,单位 MB,默认1MB。 |
| enableAccurateSeek | 是否精确 seek,默认 YES。开启精确后 seek,seek 的时间平均多出 200ms。 |
| audioNormalization | 音量均衡响度范围:-70~0(LUFS)。此配置需要 LiteAVSDK 11.7 及以上版本支持。 以下几种常量供参考使用:关:AUDIO_NORMALIZATION_OFF (TXVodPlayConfig.h)开(标准响度):AUDIO_NORMALIZATION_STANDARD (TXVodPlayConfig.h)开(低响度):AUDIO_NORMALIZATION_LOW (TXVodPlayConfig.h)开(高响度):AUDIO_NORMALIZATION_HIGH (TXVodPlayConfig.h)默认值为 AUDIO_NORMALIZATION_OFF。 |
| isLastPrePlay | 是否保留上一个预播放,默认 NO。 |
| superResolutionType | 超分类型,默认0。注意:开启超分需要先集成超分插件,否则无效。详情参见 终端极速高清。 |
| subtitleRenderModel | 字幕样式。 |
| headers | 自定义 HTTP Headers。 |
然后进行播放器策略配置:
TUIPlayerStrategyModel *model = [[TUIPlayerStrategyModel alloc] init];model.mPreloadConcurrentCount = 1;model.preDownloadSize = 1;model.enableAutoBitrate = NO;model.mRenderMode = TUI_RENDER_MODE_FILL_SCREEN;model.mResumeModel = TUI_RESUM_MODEL_LAST;[_videoView setShortVideoStrategyModel:model];
21、3.2. 直播播放策略设置
你可以通过 TUIPlayerLiveStrategyModel 模型配置直播的播放策略。
TUIPlayerLiveStrategyModel 主要参数参见下表:
| 参数名称 | 含义 |
| isLastPrePlay | 是否保留上一个预播放,默认 NO。 |
| mRenderMode | 画布填充样式,默认 V2TXLiveFillModeFill。 |
| enablePictureInPicture | YES:开启画中画功能。NO:关闭画中画功能。默认值:NO。 |
| volume | 播放器音量,取值范围0 – 100。默认值:100。 |
| maxAutoAdjustCacheTime | 播放器缓存自动调整的最大时间,单位秒,取值需要大于0,默认值:5。 |
| minAutoAdjustCacheTime | 播放器缓存自动调整的最小时间,单位秒,取值需要大于0,默认值为1。 |
| isShowDebugView | 是否显示播放器状态信息的调试浮层,默认值:NO。 |
然后进行播放器策略配置:
TUIPlayerLiveStrategyModel *liveStrategyModel = [[TUIPlayerLiveStrategyModel alloc] init];[_videoView setShortVideoLiveStrategyModel:liveStrategyModel];
22、3.3. 动态策略调整
点播和直播的策略均支持动态的调整,步骤如下:
3.3.1. 通过 TUIShortVideoView 获取直播&点播策略管理类。
TUIPlayerVodStrategyManager *VodStrategyManager = [_videoView getVodStrategyManager];TUIPlayerVodStrategyManager *LiveStrategyManager = [_videoView getLiveStrategyManager];
3.3.2. 通过 VodStrategyManager 和 LiveStrategyManager 调整播放策略。
[VodStrategyManager setRenderMode:TUI_RENDER_MODE_FILL_EDGE];[LiveStrategyManager setRenderMode:V2TXLiveFillModeFill];
24、4.1. 数据模型
TUIShortVideoView 的原始数据模型包括:
| 参数说明 | 含义 |
| TUIPlayerDataModel | 基本的数据类型。 |
| TUIPlayerVideoModel | 点播数据类型,继承于 TUIPlayerDataModel。 |
| TUIPlayerLiveModel | 直播数据类型,继承于 TUIPlayerDataModel。 |
TUIPlayerDataModel
| 参数说明 | 含义 |
| modelType | 模型类型。 |
| extInfo | 点播数据类型。 |
| onExtInfoChangedBlock | 直播数据类型。 |
| extInfoChangeNotify | 通知 extInfo 数据发生改变。 |
| asVodModel | 强转为 TUIPlayerVideoModel 类型。 |
| asLiveModel | 强转为 TUIPlayerLiveModel 类型。 |
TUIPlayerVideoModel
| 参数说明 | 含义 |
| videoUrl | 视频 Url 地址。 |
| coverPictureUrl | 封面图。 |
| duration | 视频时长。 |
| appId | appid |
| fileId | 视频的 fileId。 |
| pSign | 签名字串。 |
| subtitles | 字幕信息。 |
| config | 视频的单独配置,详情请看 TUIPlayerVideoConfig。 |
TUIPlayerLiveModel
| 参数说明 | 含义 |
| liveUrl | 直播 Url |
| coverPictureUrl | 封面图 |
25、4.2. 模型的构建
构建一组点播数据模型:
TUIPlayerVideoModel *model = [[TUIPlayerVideoModel alloc] init];model.videoUrl = @"xxxx";model.coverPictureUrl = @"xxxx";model.duration = @"xxxx";model.appId = @"xxxx";model.fileId = @"xxxx";model.pSign = @"xxxx";NSDictionary *extr = @{ @"name":@"@Mars", @"titile":@"This is a vod broadcast interface", @"des":@"This is a vod broadcast interface"};model.extInfo = extr;[modelArray addObject:model];
构建一组直播数据模型:
TUIPlayerLiveModel *model = [[TUIPlayerLiveModel alloc] init];model.liveUrl = @"xxxx";model.coverPictureUrl = @"xxxx";NSDictionary *extr = @{ @"name":@"@Mars", @"liveTitile":@"This is a live broadcast interface", @"liveDes":@"This is a live broadcast interface"};model.extInfo = extr;
构建一组其他类型的数据模型:
/// 1 轮播图TUIPlayerDataModel *model = [[TUIPlayerDataModel alloc] init];NSDictionary *extr = @{ @"images":@"xxxx", @"url":@"https://cloud.tencent.com", @"titile":@"This is a picture carousel display interface", @"des":@"This is a picture carousel display interface", @"name":@"@Mars", @"type":@"imageCycle"};model.extInfo = extr;[modelArray insertObject:model atIndex:1];/// 2 图文广告TUIPlayerDataModel *model1 = [[TUIPlayerDataModel alloc] init];NSDictionary *extr1 = @{ @"adUrl":@"https://cloud.tencent.com", @"adUrl":@"https://cloud.tencent.com/document/product", @"adTitile":@"This is a web display interface", @"adDes":@"This is a web display interface", @"name":@"@Mars", @"type":@"ad"};model1.extInfo = extr1;[modelArray insertObject:model1 atIndex:1];
26、4.3. 数据的动态调整
TUIShortVideoView 提供了可供外部操作数据的数据管理类 TUIShortVideoDataManager,其作用主要是对当前播放器列表内的数据做基本增删改查等操作,参见如下演示代码:
///1、删除索引1处的数据和视图[[self.videoView getDataManager] removeData:1];///2、添加一组数据到索引9处TUIPlayerVideoModel *model = [[TUIPlayerVideoModel alloc] init];model.viewType = TUI_ITEM_VIEW_TYPE_CUSTOM;[[self.videoView getDataManager] addData:model index:9];
更详细的接口说明如下:
| 参数名称 | 含义 |
| removeData | 按索引移除数据。 |
| removeRangeData | 按范围移除数据。 |
| removeDataByIndex | 按索引数组移除数据。 |
| addData:index | 按索引添加数据。 |
| addRangeData:startIndex | 按模型数组从某个索引处添加数据。 |
| replaceData:index | 按索引替换数据。 |
| replaceRangeData:startIndex | 按模型数组从某个索引处替换数据。 |
| getDataByPageIndex | 读取某个索引处的数据。 |
| getCurrentDataCount | 获取当前播放列表内的数据总数。 |
| getCurrentIndex | 获取当前播放界面的数据索引。 |
| getCurrentModel | 获取当前播放界面的数据模型。 |
注意:说明:
28、5.1. 层级结构
TUIPlayerShortVideo 的层级结构大致如下:
分为显示层和控制层,两者是以堆叠的方式结合。
·显示层负责内容展示,点播,直播,广告推广页面等,这层是 SDK 内部管理。
·控制层负责交互,点赞,评论等,这层交给用户去实现高度的自定义。
29、5.2. TUIPlayerShortVideoUIManager
你可以通过 TUIPlayerShortVideoUIManager 的接口 和 面向协议控制层界面去实现你的自定义 UI。 参见如下代码:
TUIPlayerShortVideoUIManager *uiManager = [[TUIPlayerShortVideoUIManager alloc] init];[uiManager setControlViewClass: TUIPSControlView.class];[uiManager setLoadingView:[[TUIPSLoadingView alloc] init]];[uiManager setBackgroundView:[UIView new]];_videoView = [[TUIShortVideoView alloc] initWithUIManager:uiManager];
上面的代码通过 TUIPlayerShortVideoUIManager 自定义了名为 TUIPSControlView 的视频控制层(进度条,时间等),以及名为 TUIPSLoadingView 的 loading 加载控件。
TUIPlayerShortVideoUIManager 的接口参见下表:
| 参数名称 | 含义 |
| setLoadingView | 设置加载图。 |
| setBackgroundView | 设置背景图。 |
| setErrorView | 设置错误界面。 |
| setControlViewClass | 设置视频控制层* @param ViewClass 控制层类,ViewClass 是你封装好的视频控制 View,包含如进度条,时间 label 等控件 * 它将被整体覆盖在视频窗口上,大小与视频窗口一致。 |
| setControlViewClass :viewType |
设置不同类型的视频控制层。 |
| getLoadingView | 获取加载图 View 实例。 |
| getBackgroundView | 获取背景图 View 实例。 |
| getErrorView | 获取错误界面 View 实例。 |
| getControlViewClass | 获取视频控制界面 View 类。 |
| getControlViewClassWithViewType | 获取不同类型视频控制界面类。 |
播放层目前支持的类型有两种:
·TUI_ITEM_VIEW_TYPE_VOD ///视频
·TUI_ITEM_VIEW_TYPE_LIVE ///直播
·TUI_ITEM_VIEW_TYPE_CUSTOM /// 自定义类型(例如广告页面)
相应的控制层的协议也支持两种:
·TUIPlayerShortVideoControl ///视频控制层协议
·TUIPlayerShortVideoLiveControl ///直播控制层协议
·TUIPlayerShortVideoCustomControl ///自定义控制层协议
注意:说明:
注意:所有非点播和直播的界面,均以 TUI_ITEM_VIEW_TYPE_VOD 和 TUIPlayerShortVideoCustomControl 去呈现,Custom 是一个大类,具体的细分需要用户在此白板上自行定义,如上文 TUIPlayerDataModel 模型构建提到的,可以通过 extInfo/type 或者 extInfo 下别的字段去做更细粒度的划分。
TUIPlayerShortVideoControl 协议具体接口说明如下:
| 参数说明 | 含义 |
| delegate | 一个反向代理,用于控制层与播放层的交互。 |
| model | 当前播放的视频模型。 |
| currentPlayerStatus | 当前播放器的播放状态。 |
| showCenterView | 显示中心 view。 |
| hideCenterView | 隐藏中心 view。 |
| showLoadingView | 显示 loading 图。 |
| hiddenLoadingView | 隐藏 loading 图。 |
| setDurationTime | 总的视频时长。 |
| setCurrentTime | 当前的播放时长。 |
| setProgress | 进度条的进度。 |
| showSlider | 显示进度条。 |
| hideSlider | 隐藏进度条。 |
| reloadControlData | 触发视图刷新。 |
| getPlayer | 获取播放器对象。 |
| onPlayEvent | 获取播放器事件。 |
| getVideoLayerRect | 获取视频渲染区域的变化。 |
| getVideoWidget | 获取视频渲染图层对象。 |
| onPlayer:subtitleData: | 播放器回调字幕,外部可自行渲染字幕信息。 |
TUIPlayerShortVideoLiveControl 协议具体接口说明如下:
| 参数说明 | 含义 |
| delegate | 一个反向代理,用于控制层与播放层的交互。 |
| model | 当前播放数据模型。 |
| reloadControlData | 触发视图刷新。 |
| getPlayer | 获取播放器对象。 |
| getVideoLayerRect | 获取视频图层区域。 |
| getVideoWidget | 获取视频渲染图层。 |
TUIPlayerShortVideoCustomControl 协议具体接口说明如下:
| 参数说明 | 含义 |
| delegate | 一个反向代理,用于控制层与播放层的交互。 |
| model | 当前播放数据模型。 |
| reloadControlData | 触发视图刷新。 |
注意:传入的自定义控制层 View 需要遵守相关的协议,否则将会编译失败。
30、5.3. 示例
| 类型 | 点播 | 直播 | Custom(轮播图) | Custom(图文广告) |
| 样例 | | | | |
5.3.1. 定义不同的样式下的 UI 样式
点播样式(TUIPlayerShortVideoControl)
@interface TUIPSControlView : UIView<TUIPlayerShortVideoControl>@property (nonatomic, strong) TUIPlayerVideoModel *videoModel;@end@implementation TUIPSControlView-(instancetype)initWithFrame:(CGRect)frame { if ([super initWithFrame:frame]){ /// UI布局代码 } return self;}-(void)setModel:(TUIPlayerVideoModel *)model { _model = model; /// 数据}@end
直播样式(TUIPlayerShortVideoLiveControl)
@interface TUIPSControlLiveView : UIView<TUIPlayerShortVideoLiveControl>@property (nonatomic, strong) TUIPlayerLiveModel *videoModel;@end@implementation TUIPSControlLiveView-(instancetype)initWithFrame:(CGRect)frame { if ([super initWithFrame:frame]){ /// UI布局代码 } return self;}-(void)setModel:(TUIPlayerLiveModel *)model { _model = model; /// 数据}@end
轮播图&图文广告等其他样式(TUIPlayerShortVideoCustomControl)
@interface TUIPSControlCustomView : UIView<TUIPlayerShortVideoCustomControl>@property (nonatomic, strong) TUIPlayerDataModel *videoModel;@end@implementation TUIPSControlCustomView-(instancetype)initWithFrame:(CGRect)frame { if ([super initWithFrame:frame]){ /// UI布局代码 } return self;}-(void)setModel:(TUIPlayerDataModel *)model { _model = model; /// 数据 NSDictionary *dic = model.extInfo; NSString *adTitile = [dic objectForKey:@"adTitile"]; NSString *adDes = [dic objectForKey:@"adDes"]; NSString *adUrl = [dic objectForKey:@"adUrl"]; NSString *name = [dic objectForKey:@"name"]; NSString *type = [dic objectForKey:@"type"]; if ([type isEqualToString:@"ad"]) { ///图文广告 self.webView.hidden = NO; self.cycleScrollView.hidden = YES; self.desLabel.textColor = [UIColor blackColor]; self.nameLabel.textColor = [UIColor blackColor]; [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:adUrl]]]; } else if ([type isEqualToString:@"imageCycle"]) { ///轮播图 self.webView.hidden = YES; self.cycleScrollView.hidden = NO; self.desLabel.textColor = [UIColor whiteColor]; self.nameLabel.textColor = [UIColor whiteColor]; NSString *imagesStr = [dic objectForKey:@"images"]; NSArray *imagesArray = [imagesStr componentsSeparatedByString:@"<:>"]; self.cycleScrollView.imageURLStringsGroup = imagesArray; }}@end
5.3.2. 将创建好的样式通过 TUIPlayerShortVideoUIManager 注册
TUIPlayerShortVideoUIManager *uiManager = [[TUIPlayerShortVideoUIManager alloc] init];[uiManager setControlViewClass: TUIPSControlView.class viewType:TUI_ITEM_VIEW_TYPE_VOD];[uiManager setControlViewClass: TUIPSControlLiveView.class viewType:TUI_ITEM_VIEW_TYPE_LIVE];[uiManager setControlViewClass: TUIPSControlCustomView.class viewType:TUI_ITEM_VIEW_TYPE_CUSTOM];
5.3.2. 通过 TUIPlayerShortVideoUIManager 初始化 TUIShortVideoView
_videoView = [[TUIShortVideoView alloc] initWithUIManager:uiManager];
5.3.3. 通过 setShortVideoStrategyModel 和 setShortVideoLiveStrategyModel 设置点播和直播的相关策略
// Set your playback strategy TUIPlayerVodStrategyModel *model = [[TUIPlayerVodStrategyModel alloc] init]; model.mPreloadConcurrentCount = 1; model.preDownloadSize = 1; model.enableAutoBitrate = NO; [_videoView setShortVideoStrategyModel:model]; // live strategy TUIPlayerLiveStrategyModel *liveStrategyModel = [[TUIPlayerLiveStrategyModel alloc] init]; liveStrategyModel.isLastPrePlay = YES; [_videoView setShortVideoLiveStrategyModel:liveStrategyModel];
5.3.4. UI 与数据的关系
TUIPSControlView & TUIPSControlLiveView & TUIPSControlCustomView 可以理解为预置模板,初始化 TUIShortVideoView 的时候已经预置好了各种类型的模板,当滑动到相对应的数据类型的时候,即会显示当前模板。
| 类型 | 数据模型 | UI 模板 |
| 点播 | TUIPlayerVideoModel | TUIPSControlView |
| 直播 | TUIPlayerLiveModel | TUIPSControlLiveView |
| 自定义类型(轮播图,图文广告等) | TUIPlayerDataModel | TUIPSControlCustomView |
·UI 模板是提前预置的。
·UI 样式的显示则根据相对应的数据类型的驱动。
5.3.4. UI 模板与 TUIShortVideoView 的交互
自定义 UI 模板通过对应的协议与 TUIShortVideoView 实现交互 TUIShortVideoView 向 TUIPSControlView & TUIPSControlLiveView & TUIPSControlCustomView 传递消息通过 TUIPlayerShortVideoControl &TUIPlayerShortVideoLiveControl &TUIPlayerShortVideoCustomControl 的协议方法。
点播:
-(void)setModel:(TUIPlayerVideoModel *)model { if ([_model observationInfo]) { [_model removeObserver:self forKeyPath:@"preloadState"]; } _model = model; [model addObserver:self forKeyPath:@"preloadState" options:NSKeyValueObservingOptionNew context:nil]; NSDictionary *dic = model.extInfo; NSString *iconUrl = [dic objectForKey:@"iconUrl"]; NSString *advertise = [dic objectForKey:@"advertise"]; NSString *name = [dic objectForKey:@"name"]; NSString *title = [dic objectForKey:@"title"]; NSString *topic = [dic objectForKey:@"topic"]; self.iconImageView.image = [UIImage imageNamed:iconUrl]; [self.adButton setTitle:advertise forState:UIControlStateNormal]; self.nameLabel.text= name; self.themeLabel.text = topic; self.desLabel.text = title; [self updatePreloadState]; [self updateLickCount]; model.onExtInfoChangedBlock = ^(id _Nonnull extInfo) { [self updateLickCount]; };}
直播:
-(void)setModel:(TUIPlayerLiveModel *)model { _model = model; NSDictionary *dic = model.extInfo; NSString *adTitile = [dic objectForKey:@"liveTitile"]; NSString *adDes = [dic objectForKey:@"liveDes"]; NSString *name = [dic objectForKey:@"name"]; self.nameLabel.text = name; self.desLabel.text = adTitile;}
Custom(轮播图 ,图文等):
-(void)setModel:(TUIPlayerDataModel *)model { _model = model; NSDictionary *dic = model.extInfo; NSString *adTitile = [dic objectForKey:@"adTitile"]; NSString *adDes = [dic objectForKey:@"adDes"]; NSString *adUrl = [dic objectForKey:@"adUrl"]; NSString *name = [dic objectForKey:@"name"]; NSString *type = [dic objectForKey:@"type"]; self.desLabel.text = adTitile; self.nameLabel.text = name; if ([type isEqualToString:@"web"]) { self.webView.hidden = NO; self.cycleScrollView.hidden = YES; self.desLabel.textColor = [UIColor blackColor]; self.nameLabel.textColor = [UIColor blackColor]; [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:adUrl]]]; } else if ([type isEqualToString:@"imageCycle"]) { self.webView.hidden = YES; self.cycleScrollView.hidden = NO; self.desLabel.textColor = [UIColor whiteColor]; self.nameLabel.textColor = [UIColor whiteColor]; NSString *imagesStr = [dic objectForKey:@"images"]; NSArray *imagesArray = [imagesStr componentsSeparatedByString:@"<:>"]; self.cycleScrollView.imageURLStringsGroup = imagesArray; }}
TUIPSControlView & TUIPSControlLiveView & TUIPSControlCustomView 向 TUIShortVideoView 传递消息则通过 TUIPlayerShortVideoControl &TUIPlayerShortVideoLiveControl &TUIPlayerShortVideoCustomControl 的 delegate。
点播:
@protocol TUIPlayerShortVideoControlDelegate <NSObject>/** * 暂停 */- (void)pause;/** * 继续播放 */- (void)resume;/** * 滑动滚动条的处理 * @param time 滑动的距离 */- (void)seekToTime:(float)time;/** * 是否正在播放 */- (BOOL)isPlaying;/** * 重置视频播放容器 * – 用于视频播放容器被移除后需要重置的场景 */- (void)resetVideoWeigetContainer;@optional/** * 自定义回调事件 */- (void)customCallbackEvent:(id)info;@end/////调用if (self.delegate && [self.delegate respondsToSelector:@selector(pause)]) { [self.delegate pause];}
直播:
@protocol TUIPlayerShortVideoLiveControlDelegate <NSObject>/** * 暂停 */- (void)pause;/** * 继续播放 */- (void)resume;/** * 重置视频播放容器 * – 用于视频播放容器被移除后需要重置的场景 */- (void)resetVideoWeigetContainer;@optional/** * 自定义回调事件 */- (void)customCallbackEvent:(id)info;@end/////调用if (self.delegate && [self.delegate respondsToSelector:@selector(pause)]) { [self.delegate pause];}
Custom(轮播图 ,图文等):
@protocol TUIPlayerShortVideoCustomControlDelegate <NSObject>@optional/** * 自定义回调事件 */- (void)customCallbackEvent:(id)info;@end/////调用if (self.delegate && [self.delegate respondsToSelector:@selector(customCallbackEvent:)]) { [self.delegate customCallbackEvent:@"test"];}
注意:说明:
注意:完整示例请看 Demo。
31、6. 外挂字幕
短视频列表可以为每个视频添加字幕。
6.1. 创建字幕
// 创建字幕对象TUIPlayerSubtitleModel *subTitleModel = [[TUIPlayerSubtitleModel alloc] init];subTitleModel.url = @"subtitle URL";subTitleModel.name = @"subtitle name";subTitleModel.mimeType = TUI_VOD_PLAYER_MIMETYPE_TEXT_SRT;// 设置给视频模型TUIPlayerVideoModel *videoModel = [[TUIPlayerVideoModel alloc] init];videoModel.subtitles = @[subTitleModel];
6.2. 选择字幕
// 1. 在-[id<TUIPlayerShortVideoControl> getPlayer:]接口判断播放器状态,处于Prepared、Playing或Paused时选择字幕- (void)getPlayer:(TUITXVodPlayer *)player { if (player.status == TUITXVodPlayerStatusPrepared || player.status == TUITXVodPlayerStatusPlaying || player.status == TUITXVodPlayerStatusPaused) { NSArray<TXTrackInfo *> *subtitleTrackInfo = [player.player getSubtitleTrackInfo]; if (subtitleTrackInfo.count) { [player.player selectTrack:subtitleTrackInfo.firstObject.trackIndex]; } }}// 2. 在-[id<TUIPlayerShortVideoControl> onPlayEvent:event:withParam:]接口监听VOD_PLAY_EVT_VOD_PLAY_PREPARED事件来选择字幕- (void)onPlayEvent:(TUITXVodPlayer *)player event:(int)EvtID withParam:(NSDictionary *)param { switch (EvtID) { case VOD_PLAY_EVT_VOD_PLAY_PREPARED: { NSArray<TXTrackInfo *> *subtitleTrackInfo = [player.player getSubtitleTrackInfo]; if (subtitleTrackInfo.count) { [player.player selectTrack:subtitleTrackInfo.firstObject.trackIndex]; } } break; default: break; }}
6.3. 字幕样式
TUI 提供了调整字幕渲染位置、字体大小和颜色等渲染相关接口。
// 1. 创建字幕样式对象TXPlayerSubtitleRenderModel *subtitleRenderModel = [[TXPlayerSubtitleRenderModel alloc] init];subtitleRenderModel.canvasWidth = 1920; // 字幕渲染画布宽度subtitleRenderModel.canvasHeight = 1080; // 字幕渲染画布高度subtitleRenderModel.fontSize = 30; // 字体大小subtitleRenderModel.fontColor = 0xFFFF0000; // 字体颜色// 2. 赋值到策略ModelTUIPlayerVodStrategyModel *strategyModel = [[TUIPlayerVodStrategyModel alloc] init]; // 点播策略Model对象strategyModel.subtitleRenderModel = subtitleRenderModel;// 3. 赋值到ShortVideoView[self.shortVideoView setShortVideoStrategyModel:strategyModel];
注意:说明:
注意:字幕功能需集成 TXLiteAVSDK_Player_Premium 高级版本。
32、7. 画中画
TUI 提供了 APP 退后台自动进入画中画模式下播放的功能。同时根据设置的 TUIPlayMode 参数决定当前集播放结束的后续操作,包括暂停播放、循环播放和自动切换下一集。
注意:画中画暂不支持直播。
7.1. 基础配置
需升级短视频组建至2.2.0及以上版本,同时需集成播放器 SDK 13.2 及以上版本。引入 bundle 资源 后 开通 APP 后台播放权限。
7.2. 接口描述
自动画中画接口:
/** * 自动启动 Picture In Picture 是否允许(自动启动画中画控制开关) * @param enabled 自动启动画中画功能是否允许,YES 表示允许 NO 表示不允许,默认为NO * @discussion 仅支持点播视频,暂不支持直播 */- (void)setAutoPictureInPictureEnabled:(BOOL)enabled;
画中画回调接口:
/** * @brief 回调播放器画中画状态 * @param shortVideoView 短视频View * @param pipState 画中画状态 * @param param 额外参数 * @discussion 默认为全屏大小 */- (void)shortVideoView:(TUIShortVideoView *)shortVideoView pictureInPictureStateDidChange:(TX_VOD_PLAYER_PIP_STATE)pipState param:(NSDictionary<TUIPlayerContext, id> *)param;/** * @brief 画中画状态下是否切换到下一集 * @param shortVideoView 短视频View * @param videoModel 视频信息 * @discussion 仅在画中画状态下,且loopMode为TUIPlayModeListLoop时使用 */- (BOOL)shortVideoView:(TUIShortVideoView *)shortVideoView shouldContinueWithModel:(__kindof TUIPlayerDataModel *)videoModel;
34、业务通知消息到页面图层
TUI 提供了消息接口供用户把数据实时通知到当前图层,可以通过数据操作对象获取到视频对象之后,进行通知,示例如下:
/// 获取数据管理器TUIShortVideoDataManager *dataManager = [self.videoView getDataManager];///获取数据模型TUIPlayerDataModel *model = [dataManager getDataByPageIndex:1];///修改数据模型model.extInfo = @{@"key":@"value"}///通知数据模型发生改变[model extInfoChangeNotify];
随后在 UI 控制层的 onExtInfoChanged 回调中会收到该通知,从而对当前页面进行 UI 修改,示例如下:
model.onExtInfoChangedBlock = ^(id _Nonnull extInfo) { [self updateLickCount];};
注意:此功能只对 extInfo 字段有效。
35、点播设置音量均衡
播放器支持在播放音频时自动调整音量,使得所有音频的音量保持一致。这可以避免某些音频过于响亮或过于安静的问题,提供更好的听觉体验。
通过设置音量均衡,响度范围:-70~0 (LUFS),同时支持自定义数值。
注意:播放器高级版 11.7 版本开始支持。
/// 音量均衡 .响度范围:-70~0(LUFS)。此配置需要LiteAVSDK 11.7 及以上版本支持。/// 以下几种常量供参考使用/// 关:AUDIO_NORMALIZATION_OFF (TXVodPlayConfig.h)/// 开(标准响度):AUDIO_NORMALIZATION_STANDARD (TXVodPlayConfig.h)/// 开(低响度):AUDIO_NORMALIZATION_LOW (TXVodPlayConfig.h)/// 开(高响度):AUDIO_NORMALIZATION_HIGH (TXVodPlayConfig.h)/// 默认值为AUDIO_NORMALIZATION_OFF。TUIPlayerVodStrategyModel *model = [[TUIPlayerVodStrategyModel alloc] init];model.audioNormalization = AUDIO_NORMALIZATION_STANDARD;[_videoView setShortVideoStrategyModel:model];
36、点播终端极速高清
TUI 短视频支持开启终端高清,终端极速高清介绍可参见 终端极速高清。
根据文档中的步骤,将超分插件下载下来,集成到你的项目中。随后在设置点播策略的时候,开启超分策略。
TUIPlayerVodStrategyModel *model = [[TUIPlayerVodStrategyModel alloc] init];model.superResolutionType = TUI_SuperResolution_ASR;[_videoView setShortVideoStrategyModel:model];