本文介绍了使用低代码集成(含UI)方式快速接入互动直播iOS端的方法。
前提条件
环境要求
设备类型:支持iPhone和iPad所有型号。
CPU架构:支持iOS真机armv7、arm64架构,不支持模拟器i386、X86_64架构。
系统版本:支持iOS 10.0及以上版本。
其他:不支持bitcode,不支持屏幕旋转。
集成步骤
第一步:添加SDK依赖
SDK依赖可基于CocoaPods添加或基于本地Framework依赖方式添加,推荐使用基于CocoaPods添加的方式。
方式1:基于CocoaPods添加SDK依赖(推荐)
在已有Xcode工程的Podfile文件中增加代码,需要添加的代码有:
#阿里云低代码音视频工厂总入口库 pod 'AliInteractiveRoomBundle', '1.6.0' #阿里云低代码音视频工厂依赖的三方库 pod 'Masonry' #阿里云低代码音视频工厂互动直播样板间库 pod 'AliStandardLiveRoomBundle', '1.6.0' #阿里云低代码音视频工厂主播推流端相关库 pod 'AliInteractiveLiveCore', '1.6.0' pod 'AlivcLivePusher', '4.2.1' pod 'Queen', '1.4.1-official-lite' #阿里云低代码音视频工厂观众拉流相关库 pod 'AliInteractiveVideoPlayerCore', '1.6.0' pod 'AliPlayerSDK_iOS', '5.4.4.0' pod 'AliPlayerSDK_iOS_ARTC', '5.4.4.0' #超低延迟拉流相关(可选,但需与RtsSDK同时选用) pod 'RtsSDK', '1.9.0' #超低延迟拉流相关(可选,但需与iOS_ARTC同时选用)
说明美颜库Queen的'1.4.1-official-lite'版本是免授权的基础版本,如果需要更高级的美颜功能,可以通过美颜特效SDK产品介绍进行了解和购买。
方式2:基于本地Framework添加SDK依赖
下载并解压SDK。
打开低代码音视频工厂控制台>应用管理 > 低代码集成,下载最新iOS端SDK。
解压之后,文件结构如下图所示:
在Xcode工程TARGETS的General页签下,在Frameworks, Libraries, and Embedded Content区域中添加以下framework,并修改对应的Embed属性。
把资源文件ASLRBLiveRoomAssets.xcassets、AliInteractiveLiveBeautyResource.bundle和queen-ios.Bundle添加到自己的工程目录下(与系统Assets.xcassets平级)。
增加pod依赖Masonry开源库。请在已有的Podfile中增加如下一行:
pod 'Masonry'
第二步:代码接入
此处以在ViewController中集成为例,实际请以自己业务为准。
#import "ViewController.h"
#import <objc/message.h>
#import <AliStandardLiveRoomBundle/AliStandardLiveRoomBundle.h>
#import "MyViewController.h"
#import <Masonry/Masonry.h>
@interface ViewController ()<ASLRBLiveRoomViewControllerDelegate,UITextFieldDelegate>
@property (nonatomic, weak) ASLRBLiveRoomViewController* liveRoomVC;
@property (nonatomic, strong) UITextField* textField;
@property (nonatomic, strong) ASLRBAppInitConfig* appConfig;
@property (nonatomic, assign) BOOL isCustomized;
@property (nonatomic, strong) UIView* goodsCardView;
@end
@implementation ViewController
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[super viewDidLoad];
__weak typeof(self) weakSelf = self;
//首先进行全局初始化,全局只需要执行一次
[[ASLRBLiveRoomManager sharedInstance] globalInitOnceWithConfig:({
ASLRBAppInitConfig *config = [[ASLRBAppInitConfig alloc]init];
config.appID = [NSString stringWithFormat:@"%@", @""];//在阿里云控制台开通互动直播后获取;
config.appKey = [NSString stringWithFormat:@"%@", @""];//在阿里云控制台开通互动直播后获取;
config.appServerUrl = [NSString stringWithFormat:@"%@", @"xxxx"];//参考接入文档的第一步,AppServer部署好之后会获得;
config.appServerSignSecret = [NSString stringWithFormat:@"%@", @"xxxx"];//在阿里云控制台开通互动直播后获取;
config.userID = @"xxx";//自定义用户id,必须是英文字母或者阿拉伯数字或者二者组合
config.userNick = @"xxx"; //必传,支持任意字符
config.userExtension = @{@"test" : @"test"}; //非必传
self.appConfig = config;
config;
}) onSuccess:^{
[[ASLRBLiveRoomManager sharedInstance] createLiveRoomVCWithConfig:({
ASLRBLiveInitConfig* config = [[ASLRBLiveInitConfig alloc] init];
config.liveID = @"xxx"; //主播侧非必传(为空是会创建新直播),观众或者回放模式下必传
config.role = ASLRBUserRoleAnchor; //观众或者主播
config.enableLivePlayback = YES; //开启回放模式,如果直播已结束将进入直播回放房间 (需要1.5.0及以上版本)
config;
})
onCompletion:^(ASLRBLiveRoomViewController * _Nonnull liveRoomVC) {
weakSelf.liveRoomVC = liveRoomVC;
// weakSelf.liveRoomVC.backgroundImage = [UIImage imageNamed:@"xxxxxx"];
//获取VC后,首先进行setup,成功后再present当前vc
[liveRoomVC setupOnSuccess:^(NSString * _Nonnull liveID) {
dispatch_async(dispatch_get_main_queue(), ^{
liveRoomVC.modalPresentationStyle = UIModalPresentationFullScreen;
liveRoomVC.delegate = weakSelf;
[weakSelf customizeVC:liveRoomVC];//自定义设置直播间:预览页、自定义区域、商品卡片(可以根据业务自行设计修改)
[weakSelf.navigationController pushViewController:liveRoomVC animated:YES];
});
} onFailure:^(NSString * _Nonnull errorMessage) {
}];
}];
} onFailure:^(NSString * _Nonnull errorMessage) {
}];
}
#pragma mark --自定义设置直播间:预览页、自定义区域、商品卡片(可以根据业务自行设计修改)
- (void)customizeVC:(ASLRBLiveRoomViewController*)vc{
void(^showCustomUI)(void) = ^(void){
//自定义预览页示例,增加了编辑直播标题、开播按钮、切换摄像头按钮
[vc.livePreviewCustomizedViewHolder addSubview:({
UITextField* textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 300, 200, 60)];
textField.placeholder = @"直播标题";
textField.backgroundColor = [UIColor colorWithWhite:1 alpha:0.7];
textField.layer.masksToBounds = YES;
textField.layer.cornerRadius = 4;
self.textField = textField;
textField;
})];
[vc.livePreviewCustomizedViewHolder addSubview:({
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(100, 400, 200, 60)];
button.backgroundColor = [UIColor redColor];
[button setTitle:@"开播" forState:UIControlStateNormal];
[button addTarget:self action:@selector(startLive) forControlEvents:UIControlEventTouchUpInside];
button;
})];
[vc.livePreviewCustomizedViewHolder addSubview:({
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(100, 520, 200, 60)];
button.backgroundColor = [UIColor greenColor];
[button setTitle:@"摄像头切换" forState:UIControlStateNormal];
[button addTarget:vc action:@selector(switchCamera) forControlEvents:UIControlEventTouchUpInside];
button;
})];
[vc.livePreviewCustomizedViewHolder addSubview:({
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(100, 640, 200, 60)];
button.backgroundColor = [UIColor greenColor];
[button setTitle:@"打开美颜面板" forState:UIControlStateNormal];
[button addTarget:vc action:@selector(showBeautyPanel) forControlEvents:UIControlEventTouchUpInside];
button;
})];
//自定义左上方区域示例
[vc.upperLeftCustomizedViewHolder addSubview:({
UILabel *label = [[UILabel alloc]initWithFrame:self.liveRoomVC.upperLeftCustomizedViewHolder.bounds];
label.layer.masksToBounds = YES;
label.layer.cornerRadius = 4;
label.backgroundColor = [[UIColor systemPinkColor] colorWithAlphaComponent:0.3];
label.adjustsFontSizeToFitWidth = YES;
label.text = @"这是左上自定义区域";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor blackColor];
label;
})];
//自定义右上方区域示例
[vc.upperRightCustomizedViewHolder addSubview:({
UILabel *label = [[UILabel alloc]initWithFrame:self.liveRoomVC.upperRightCustomizedViewHolder.bounds];
label.layer.masksToBounds = YES;
label.layer.cornerRadius = 4;
label.backgroundColor = [[UIColor yellowColor] colorWithAlphaComponent:0.3];
label.adjustsFontSizeToFitWidth = YES;
label.text = @"这是右上自定义区域";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor blackColor];
label;
})];
[vc.upperRightCustomizedViewHolder addSubview:({
UIButton *button = [[UIButton alloc]init];
button.backgroundColor = [UIColor whiteColor];
[button setTitle:@"➡️" forState:UIControlStateNormal];
button.frame = CGRectMake(110, 5, 30, 30);
[button addTarget:self action:@selector(nextScene) forControlEvents:UIControlEventTouchUpInside];
button;
})];
[vc.upperRightCustomizedViewHolder addSubview:({
UIButton *button = [[UIButton alloc]init];
button.backgroundColor = [UIColor whiteColor];
[button setTitle:@"❌" forState:UIControlStateNormal];
button.frame = CGRectMake(150, 5, 30, 30);
[button addTarget:self action:@selector(exitLiveRoom) forControlEvents:UIControlEventTouchUpInside];
button;
})];
//自定义中间区域示例
[vc.middleCustomizedViewHolder addSubview:({
UILabel *label = [[UILabel alloc]initWithFrame:self.liveRoomVC.middleCustomizedViewHolder.bounds];
label.layer.masksToBounds = YES;
label.layer.cornerRadius = 4;
label.backgroundColor = [[UIColor orangeColor] colorWithAlphaComponent:0.3];
label.adjustsFontSizeToFitWidth = YES;
label.text = @"这里是中心自定义区域";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor blackColor];
label;
})];
[vc.bottomCustomizedViewHolder addSubview:({
UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(5, 5, 180, 40)];
textField.layer.masksToBounds = YES;
textField.backgroundColor = [UIColor blackColor];
textField.layer.cornerRadius = 20;
textField.textColor = [UIColor blackColor];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"说点什么……"
attributes:@{
NSForegroundColorAttributeName:[UIColor colorWithWhite:1 alpha:0.8],
NSFontAttributeName:[UIFont systemFontOfSize:14]
}];
textField.attributedPlaceholder = attrString;
textField.textAlignment = NSTextAlignmentLeft;
textField.keyboardType = UIKeyboardTypeDefault;
textField.returnKeyType = UIReturnKeySend;
textField.keyboardAppearance = UIKeyboardAppearanceDefault;
textField.delegate = self;
textField.borderStyle = UITextBorderStyleRoundedRect;
[textField setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
textField;
})];
return;
};
// showCustomUI();//展示自定义UI,这个块调用被注释掉后会展示默认标准样板间实现
}
//自定义预览页中,使用到按钮的动作:开播
- (void)startLive{
ASLRBLiveInitConfig* config = [[ASLRBLiveInitConfig alloc] init];
config.liveCoverURL = @"xxxxxx";
config.liveCustomData = @"xxxxxxxxxxxx";
[self.liveRoomVC startLiveAndUpdateConfig:config];
}
- (void)nextScene{
[self.navigationController pushViewController:({
MyViewController* vc = [[MyViewController alloc]init];
vc;
}) animated:YES];
}
//自定义右上角区域中,使用到按钮的动作:离开直播间 +(主播端则还会停止直播)
- (void)exitLiveRoom{
[self.liveRoomVC exitLiveRoom];
[self dismissViewControllerAnimated:YES completion:nil];
}
//自定义中心区域中,使用到按钮的动作:展开/收起商品卡片(**观众端使用**)
- (void)showGoodsCardView{
[UIView animateWithDuration:0.2 animations:^{
if (!self.goodsCardView) {
self.goodsCardView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"直播-商品卡片"]];
[self.liveRoomVC.view addSubview:self.goodsCardView];
[self.goodsCardView mas_makeConstraints:^(MASConstraintMaker * _Nonnull make) {
make.bottom.equalTo(self.liveRoomVC.bottomCustomizedViewHolder.mas_top);
make.left.equalTo(self.liveRoomVC.view).with.offset(14);
make.height.mas_equalTo(80);
make.width.mas_equalTo(260);
}];
}
[(UITableView*)self.liveRoomVC.commentView mas_remakeConstraints:^(MASConstraintMaker * _Nonnull make) {
make.left.equalTo(self.liveRoomVC.view).with.offset(((UITableView*)(self.liveRoomVC.commentView)).frame.origin.x);
make.bottom.equalTo(self.goodsCardView.mas_top);
make.height.mas_equalTo(((UITableView*)(self.liveRoomVC.commentView)).bounds.size.height);
make.width.mas_equalTo(((UITableView*)(self.liveRoomVC.commentView)).bounds.size.width);
}];
}];
}
//自定义底部按钮的动作:展现一个VC
- (void) customizedButtonAction{
}
//VC的代理,通知分享按钮被点击、直播开始、退出按钮被点击的事件,以及错误消息等
#pragma mark - ASLRBLiveRoomViewControllerDelegate
- (void) onASLRBLiveRoomEventInViewController:(ASLRBLiveRoomViewController *)liveRoomVC liveRoomEvent:(ASLRBEvent)liveRoomEvent info:(nonnull NSDictionary *)info {
switch (liveRoomEvent) {
case ASLRBCommonEventShareButtonDidClicked :{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController* avc = [UIAlertController alertControllerWithTitle:@"分享界面" message:@"自定义你的分享界面。" preferredStyle:UIAlertControllerStyleAlert];
[avc addAction:({
UIAlertAction* action = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:nil];
action;
})];
[self.liveRoomVC presentViewController:avc animated:YES completion:nil];
});
}
break;
case ASLRBCommonEventExitButtonDidClicked:{
[self dismissViewControllerAnimated:YES completion:nil];
[self.liveRoomVC exitLiveRoom];
}
break;
case ASLRBAnchorEventLivePusherStarted:{
}
break;
case ASLRBCommonEventLiveDataUpdated:{
//直播间的数据更新会在这里处理,包括点赞数、实时在线人数、uv等
}
break;
default:
break;
}
}
- (void)onASLRBLiveRoomErrorInViewController:(nonnull ASLRBLiveRoomViewController *)liveRoomVC liveRoomError:(ASLRBLiveRoomError)liveRoomError withErrorMessage:(nonnull NSString *)errorMessage {
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[self.liveRoomVC sendComment:textField.text onSuccess:^{
} onFailure:^(ASLRBLiveRoomError code, NSString * _Nonnull errorMessage) {
}];
textField.text = nil;
return YES;
}
@end
后续步骤
如您需要进行扩展开发,请参见iOS端扩展开发。