短剧

短剧

ZJTubePage接入注意事项

  • 由于内容包没有放在 CocoaPods 的公共仓库,需要⾃⾏将 podspec ⽂件放⼊⼯程⾥,然后在 Podfile ⾥指定路径,参考如下:
 pod 'KSAdSDK', :path => '../ZJSDK/ZJSDKModuleKS/KS' 
  • 如不是通过pod导入,打包发布之前,需要去掉快手内容包的x86_64框架,具体的拆分合并命令参考以下
cd [KSAdSDK.framework所在的目录]
mkdir ./bak
cp -r KSAdSDK.framework ./bak
lipo KSAdSDK.framework/KSAdSDK -thin armv7 -output KSAdSDK_armv7
lipo KSAdSDK.framework/KSAdSDK -thin arm64 -output KSAdSDK_arm64
lipo -create KSAdSDK_armv7 KSAdSDK_arm64 -output KSAdSDK
mv KSAdSDK KSAdSDK.framework/

注意

目前sdk集成的KSAdSDK的版本,默认就是内容包,不再需要单独引入。如果导入的KSAdSDK不是内容包,SDK会提示文件找不到,请检查pod导入的依赖版本是否是最新版本

ZJTubePage说明

api说明

@interface ZJTubePage : ZJAd <ZJContentInfo>
@property (nonatomic, readonly) UIViewController *viewController;
///视频状态代理
@property (nonatomic, weak) id <ZJContentPageVideoStateDelegate> videoStateDelegate;
///页面状态代理
@property (nonatomic, weak) id <ZJContentPageStateDelegate> stateDelegate;
/// 短剧播放器回调
@property (nonatomic, weak) id <ZJShortPlayPlayerDelegate> playerCallbackDelegate;
/// 广告回调
@property (nonatomic, weak) id <ZJShortPlayAdDelegate> adCallbackDelegate;
/// 业务接口回调
@property (nonatomic, weak) id <ZJShortPlayInterfaceDelegate> interfaceCallbackDelegate;
/// 自定义详情页cell试图回调
@property (nonatomic, weak) id <ZJShortPlayCustomViewDelegate> customViewCallBackDelegate;
/// 自定义Draw流的subview回调
@property (nonatomic, weak) id <ZJShortPlayCustomDrawAdViewDelegate> customDrawAdViewCallBackDelegate;
/// 滑滑溜底部自定义Banner广告
@property (nonatomic, weak) id <ZJShortPlayDrawVideoViewControllerBannerDelegate> drawVideoViewBannerCallbackDelegate;
// 新增类方法,必须在调用初始化方法之前使用,此方法必须调用
+ (void)setConfig:(ZJTubePageConfig *)config;
@end

代理事件说明

  1. 视频状态代理 ZJContentPageVideoStateDelegate videoStateDelegate;
@optional
/**
 * 视频开始播放
 * @param videoContent 内容模型
 */
- (void)zj_videoDidStartPlay:(id<ZJContentInfo>)videoContent;
/**
* 视频暂停播放
* @param videoContent 内容模型
*/
- (void)zj_videoDidPause:(id<ZJContentInfo>)videoContent;
/**
* 视频恢复播放
* @param videoContent 内容模型
*/
- (void)zj_videoDidResume:(id<ZJContentInfo>)videoContent;
/**
* 视频停止播放
* @param videoContent 内容模型
* @param finished     是否播放完成
*/
- (void)zj_videoDidEndPlay:(id<ZJContentInfo>)videoContent isFinished:(BOOL)finished;
/**
* 视频播放失败
* @param videoContent 内容模型
* @param error        失败原因
*/
- (void)zj_videoDidFailedToPlay:(id<ZJContentInfo>)videoContent withError:(NSError *)error;

  1. 页面状态代理 ZJContentPageStateDelegate stateDelegate
/**
* 内容展示
* @param content 内容模型
*/
- (void)zj_contentDidFullDisplay:(id<ZJContentInfo>)content;
/**
* 内容隐藏
* @param content 内容模型
*/
- (void)zj_contentDidEndDisplay:(id<ZJContentInfo>)content;
/**
* 内容暂停显示,ViewController disappear或者Application resign active
* @param content 内容模型
*/
- (void)zj_contentDidPause:(id<ZJContentInfo>)content;
/**
* 内容恢复显示,ViewController appear或者Application become active
* @param content 内容模型
*/
- (void)zj_contentDidResume:(id<ZJContentInfo>)content;

/// 任务完成回调
- (void)zjAdapter_contentTaskComplete:(id<ZJContentInfo>)content;
  1. 短剧播放器回调 ZJShortPlayPlayerDelegate playerCallbackDelegate
/*! @abstract 视频切换时的回调 */
- (void)zj_shortplayDrawVideoCurrentVideoChanged:(NSInteger)index adapter:(id<ZJContentInfo>)content;

/*! @abstract 加载失败按钮点击重试回调 */
- (void)zj_shortplayDrawVideoDidClickedErrorButtonRetry:(id<ZJContentInfo>)content;

/*! @abstract 默认关闭按钮被点击的回调 */
- (void)zj_shortplayDrawVideoCloseButtonClicked:(id<ZJContentInfo>)content;

/*! @abstract 数据刷新完成回调 */
- (void)zj_shortplayDrawVideoDataRefreshCompletion:(NSError *)error content:(id<ZJContentInfo>)content;

/*! @abstract tab栏切换控制器的回调*/
- (void)zj_shortplayPageViewControllerSwitchToIndex:(NSInteger)index content:(id<ZJContentInfo>)content;

/**! @abstract 推荐页面底部banner视图**/
- (UIView *)zj_shortplayDrawVideoVCBottomBannerView:(UIViewController *)vc content:(id<ZJContentInfo>)content;
  1. 广告回调 ZJShortPlayAdDelegate adCallbackDelegate
/*! @abstract 发起广告请求 */
- (void)zj_shortplaySendAdRequest:(id<ZJContentInfo>)content;

/*! @abstract 广告加载成功 */
- (void)zj_shortplayAdLoadSuccess:(id<ZJContentInfo>)content;

/*! @abstract 广告加载失败 */
- (void)zj_shortplayAdLoadFail:(id<ZJContentInfo>)content error:(NSError *)error;

/*! @abstract 广告填充失败 */
- (void)zj_shortplayAdFillFail:(id<ZJContentInfo>)content;

/*! @abstract 广告曝光 */
- (void)zj_shortplayAdWillShow:(id<ZJContentInfo>)content;

/*! @abstract 视频广告开始播放 */
- (void)zj_shortplayVideoAdStartPlay:(id<ZJContentInfo>)content;

/*! @abstract 视频广告暂停播放 */
- (void)zj_shortplayVideoAdPause:(id<ZJContentInfo>)content;

/*! @abstract 视频广告继续播放 */
- (void)zj_shortplayVideoAdContinue:(id<ZJContentInfo>)content;

/*! @abstract 视频广告停止播放 */
- (void)zj_shortplayVideoAdOverPlay:(id<ZJContentInfo>)content;

/*! @abstract 点击广告 */
- (void)zj_shortplayClickAdViewEvent:(id<ZJContentInfo>)content;
/*! @abstract 广告缓冲 */
- (void)zj_shortplayVideoBufferEvent:(id<ZJContentInfo>)content;

/*! @abstract 激励视频广告结束 */
- (void)zj_shortplayVideoRewardFinishEvent:(id<ZJContentInfo>)content;

/*! @abstract 激励视频广告跳过 */
- (void)zj_shortplayVideoRewardSkipEvent:(id<ZJContentInfo>)content;
  1. 业务接口回调 ZJShortPlayInterfaceDelegate interfaceCallbackDelegate
/*! @abstract 解锁流程开始 */
- (void)zj_shortplayPlayletDetailUnlockFlowStart:(id<ZJContentInfo>)content;

/*! @abstract 解锁流程取消 */
- (void)zj_shortplayPlayletDetailUnlockFlowCancel:(id<ZJContentInfo>)content;


/*! @abstract 解锁流程结束,回调解锁结果
 *  - success: 是否解锁成功
 *   - error: 解锁失败错误信息
 */
- (void)zj_shortplayPlayletDetailUnlockFlowEnd:(id<ZJContentInfo>)content
                           success:(BOOL)success
                             error:(NSError * _Nullable)error;

/*! @abstract 点击混排中进入跳转播放页的按钮 */
- (void)zj_shortplayClickEnterView:(id<ZJContentInfo>)content;

/*! @abstract 本剧集观看完毕,切到下一部短剧回调 */
- (void)zj_shortplayNextPlayletWillPlay:(id<ZJContentInfo>)content;

- (UIView *)zj_shortplayPlayletDetailBottomBanner:(id<ZJContentInfo>)content;
  1. 自定义详情页cell试图回调 ZJShortPlayCustomViewDelegate customViewCallBackDelegate
/// 创建自定义View直接返回,外部不要持有,cell自己持有复用
/// @param cell 短剧的cell
- (UIView *)zj_shortplayPlayletDetailCellCustomView:(UITableViewCell *)cell;

/// 根据数据更新UI
/// @param cell 短剧的cell
/// @param customView `djx_playletDetailCellCustomView:`返回的自定义View,短剧的cell内部会持有
/// @param playletInfo 短剧的数据
- (void)zj_shortplayPlayletDetailCell:(UITableViewCell *)cell updateCustomView:(UIView *)customView withPlayletData:(id)playletInfo;

/// 当cell执行到layoutSubviews时会回调此协议方法
/// @param cell 短剧的cell
/// @param customView `djx_playletDetailCellCustomView:`返回的自定义View
- (void)zj_shortplayPlayletDetailCell:(UITableViewCell *)cell layoutSubviews:(UIView *)customView;

/// 当cell执行到layoutSubviews后会回调此协议方法
/// @param cell 短剧的cell
/// @param customView `djx_playletDetailCellCustomView:`返回的自定义View
- (void)zj_shortplayPlayletDetailCell:(UITableViewCell *)cell afterLayoutSubviews:(UIView *)customView;
  1. 自定义Draw流的subview回调 ZJShortPlayCustomDrawAdViewDelegate customDrawAdViewCallBackDelegate
- (UIView *)zj_shortplayDetailCellCreateAdView:(UITableViewCell *)cell adInputIndex:(NSUInteger)adIndex;

- (void)zj_shortplayDetailCell:(UITableViewCell *)cell bindDataToDrawAdView:(UIView *)drawAdView adInputIndex:(NSUInteger)adIndex;

- (void)zj_shortplayDetailCell:(UITableViewCell *)cell layoutSubview:(UIView *)drawAdView adInputIndex:(NSUInteger)adIndex;

- (void)zj_shortplayDetailCell:(UITableViewCell *)cell willDisplayDrawAdView:(UIView *)drawAdView adInputIndex:(NSUInteger)adIndex;

- (void)zj_shortplayDetailCell:(UITableViewCell *)cell didEndDisplayDrawAdView:(UIView *)drawAdView adInputIndex:(NSUInteger)adIndex;
  1. 滑滑溜底部自定义Banner广告 ZJShortPlayDrawVideoViewControllerBannerDelegate drawVideoViewBannerCallbackDelegate
- (UIView *)zj_shortplayDrawVideoVCBottomBannerView:(UIViewController *)vc;
  1. 短剧内容加载结果代理 ZJContentPageLoadCallBackDelegate loadCallBackDelegate
// 内容加载成功
- (void)zj_contentPageLoadSuccess;

// 内容加载失败
- (void)zj_contentPageLoadFailure:(NSError *)error;

加载短剧内容

  • 此种对接方式将要废弃,请使用ZJTubePageAd这种方式对接
ZJTubePageConfig *config = [[ZJTubePageConfig alloc] init];
// SDK_Setting_5434885.json是用户在穿山甲平台申请的SDK参数配置文件
config.JSONConfigPath = [[NSBundle mainBundle] pathForResource:@"SDK_Setting_5434885" ofType:@"json"];
config.freeEpisodesCount = 2;
config.unlockEpisodesCountUsingAD = 1;
config.hideLikeIcon = YES;
config.hideCollectIcon = YES;
config.showCloseButton = YES;
// 是否开启自定义详情页cell视图的代理
config.configOrNotCustomViewDelegate = YES; 
// 是否开启自定义详情页Draw广告的代理
config.configOrNotCustomDrawAdViewDelegate = YES;
// 是否开启滑滑溜底部自定义Banner广告
config.configOrNotCustomBannerDelegate = YES;
[ZJTubePage setConfig:config];
self.tubePage = [[ZJTubePage alloc]initWithPlacementId:self.contentId];
//视频状态代理
self.tubePage.videoStateDelegate = self;
//页面状态代理
self.tubePage.stateDelegate = self;
//短剧播放器回调
self.tubePage.playerCallbackDelegate = self;
//广告回调
self.tubePage.adCallbackDelegate = self;
//业务接口回调
self.tubePage.interfaceCallbackDelegate = self;
//自定义详情页cell视图回调,需要设置是否开启的属性
self.tubePage.customViewCallBackDelegate = self;
//自定义Draw流的subview回调,需要设置是否开启的属性
self.tubePage.customDrawAdViewCallBackDelegate = self;
//滑滑溜底部自定义Banner广告,需要设置是否开启的属性
self.tubePage.drawVideoViewBannerCallbackDelegate = self;

// 获取到短剧VC页面,需要添加到页面上
self.weakTubeVC = self.tubePage.viewController;

if(self.weakTubeVC){
    if (self.tubePageAd.currentAdapter.config.platformType == ZJAdPlatform_KS) {
        [self addChildViewController:self.weakTubeVC];
        [self.view addSubview:self.weakTubeVC.view];
    } else {
        // 穿山甲目前用presentViewController的方式
        [self presentViewController:self.weakTubeVC animated:YES completion:^{
            
        }];
    }
}else{
    NSLog(@"未能创建对应广告位VC,建议从以下原因排查:\n 1,内容包需要手动导入快手模块(pod公共仓库中的SDK不支持内容包)\n 
    2,确保sdk已注册成功 \n 3,确保广告位正确可用");
}

TIP

加载广告具体示例详见Demo中的 : ZJTubePageStyle1VC

推荐使用以下方式接入短剧类型

TIP

新对接方式支持ZJSDK '2.5.9.8'及其以上版本,之前的版本请使用上面的对接方式对接, 新版本不再需要自己去导入快手内容版sdk,默认集成的sdk已经包含内容版

ZJTubePageAd说明

@interface ZJTubePageAd : ZJAd

@property (nonatomic, strong,nullable) ZJTubePageAdapter *currentAdapter;
///视频状态代理
@property (nonatomic, weak) id <ZJContentPageVideoStateDelegate> videoStateDelegate;
///页面状态代理
@property (nonatomic, weak) id <ZJContentPageStateDelegate> stateDelegate;
/// 短剧内容加载结果代理
@property (nonatomic, weak) id <ZJContentPageLoadCallBackDelegate> loadCallBackDelegate;
/// 短剧播放器回调
@property (nonatomic, weak) id <ZJShortPlayPlayerDelegate> playerCallbackDelegate;
/// 广告回调
@property (nonatomic, weak) id <ZJShortPlayAdDelegate> adCallbackDelegate;
/// 业务接口回调
@property (nonatomic, weak) id <ZJShortPlayInterfaceDelegate> interfaceCallbackDelegate;
/// 自定义详情页cell试图回调
@property (nonatomic, weak) id <ZJShortPlayCustomViewDelegate> customViewCallBackDelegate;
/// 自定义Draw流的subview回调
@property (nonatomic, weak) id <ZJShortPlayCustomDrawAdViewDelegate> customDrawAdViewCallBackDelegate;
/// 滑滑溜底部自定义Banner广告
@property (nonatomic, weak) id <ZJShortPlayDrawVideoViewControllerBannerDelegate> drawVideoViewBannerCallbackDelegate;
/// 短剧相关配置
@property (nonatomic, strong) ZJTubePageConfig *tubePageConfig;

/// 短剧内容的控制器,媒体可以在广告加载成功之后,直接获取并展示
- (UIViewController *)tubePageViewController;

@end

加载短剧内容

// 加载广告
ZJTubePageConfig *config = [[ZJTubePageConfig alloc] init];
config.JSONConfigPath = [[NSBundle mainBundle] pathForResource:@"SDK_Setting_5434885" ofType:@"json"];
config.freeEpisodesCount = 5;
config.unlockEpisodesCountUsingAD = 5;
//    config.hideLikeIcon = YES;
//    config.hideCollectIcon = YES;
config.showCloseButton = YES;
//    CGFloat contentY = [UIApplication sharedApplication].statusBarFrame.size.height+self.navigationController.navigationBar.frame.size.height;
//    config.viewSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height - contentY);
config.configOrNotCustomViewDelegate = YES;
config.configOrNotCustomDrawAdViewDelegate = YES;
config.configOrNotCustomBannerDelegate = YES;
config.customAdIndex = @[@0, @1];
self.tubePageAd = [[ZJTubePageAd alloc]initWithPlacementId:adId];
self.tubePageAd.tubePageConfig = config;
self.tubePageAd.videoStateDelegate = self;
self.tubePageAd.stateDelegate = self;
self.tubePageAd.loadCallBackDelegate = self;
/// 短剧播放器回调
self.tubePageAd.playerCallbackDelegate = self;
/// 广告回调
self.tubePageAd.adCallbackDelegate = self;
/// 业务接口回调
//    self.tubePageAd.interfaceCallbackDelegate = self;
/// 自定义详情页cell试图回调
self.tubePageAd.customViewCallBackDelegate = self;
/// 自定义Draw流的subview回调
self.tubePageAd.customDrawAdViewCallBackDelegate = self;
/// 滑滑溜底部自定义Banner广告
self.tubePageAd.drawVideoViewBannerCallbackDelegate = self;
[self.tubePageAd loadAd];

// 展示广告
self.weakTubeVC = self.tubePageAd.tubePageViewController;
// 快手只能push
if (self.tubePageAd.currentAdapter.config.platformType == ZJAdPlatform_KS) {
    [self addChildViewController:self.weakTubeVC];
    [self.view addSubview:self.weakTubeVC.view];
} else {
    // 穿山甲目前用presentViewController的方式
    [self presentViewController:self.weakTubeVC animated:YES completion:^{
        
    }];
}