Skip to content
ftao edited this page Jan 21, 2019 · 21 revisions

一 概述

​ Polyv iOS 直播观看 SDK 主要包含:播放器部分、接口部分和演示 demo 部分。

1.1 版本信息

livePlayerSDK ~ 2.5.2
PolyvIJKPlayer ~ 0.3.0
PolyvLiveAPI ~ 0.6.0
PolyvSocketAPI ~ 0.5.0
AgoraRtcEngine_iOS ~ 2.0.0

1.2 主要功能点

  • 直播播放
  • 暖场播放(视频/图片)
  • 竖屏小屏/横屏全屏
  • 多码率切换
  • 弹幕
  • 聊天室
  • 咨询提问
  • 在线列表
  • 音视频连麦

1.3 文件结构

├── Podfile (Podfile 文件,配置第三方依赖)
├── Podfile.lock
├── Pods (通过 pods 下载的第三方依赖库)
├── PolyvLiveSDKDemo
│   ├── AppDelegate.h
│   ├── AppDelegate.m 
│   ├── Library
│   ├── Modules
│   │   ├── Login 登录页
│   │   │   ├── LoginViewController.h
│   │   │   └── LoginViewController.m
│   │   ├── Player 播放器
│   │   │   ├── PLVLivePlayerController.h
│   │   │   ├── PLVLivePlayerController.m
│   │   │   ├── PLVLivePlayerControllerSkin.h
│   │   │   ├── PLVLivePlayerControllerSkin.m
│   │   │   └── PLVLivePlayerSkin.bundle 播放器资源
│   │   └── Watch 观看页
│   │       ├── Resources 观看页相关图片资源
│   │       ├── Chatroom 聊天室相关(互动聊天、咨询提问)
│   │       │   ├── PLVChatroomController.h
│   │       │   └── PLVChatroomController.m
│   │       ├── LivePlayerViewController.h  观看页主控制器
│   │       ├── LivePlayerViewController.m
│   │       ├── OnlineList 在线列表(在线列表、连麦)
│   │       │   ├── PLVOnlineListController.h
│   │       │   ├── PLVOnlineListController.m
│   │       │   └── Views
│   │       ├── PLVLiveManager 业务逻辑处理
│   ├── Supporting\ Files
│   │   ├── Assets.xcassets (demo资源文件)
│   │   ├── Info.plist
│   └── Utils (工具类)
│       ├── FTPageController
│       ├── PLVUtils.h
│       └── PLVUtils.m

1.4 系统要求

  • 支持最低系统版本:iOS 9.0

1.5 环境配置

  • 建议 Xcode 9.0 及以上
  • CocoaPods(未安装可参考官方说明:CocoaPods guides

1.6 快速开始

  • 首页下载 Clone or download -> Download ZIP (或版本处下载:Release

  • 进入 PolyvLiveSDKDemo 目录下,cd $PolyvLiveSDKDemo文件路径

  • 执行 pod install

  • 运行 PolyvLiveSDKDemo.xcworkspace

  • 配置 appId、appSecrect 参数,可登录保利威后台获取:云直播 -> 开发设置 -> 身份认证

    AppDelegate.m [PLVLiveConfig liveConfigWithAppId:appId appSecret:appSecret];

1.7 常见问题

​ 执行 pod install 失败,或在集成至项目期间的问题可以查看 常见问题

二 配置与集成

2.1 配置

2.1.1 info.plist 配置

  • 音视频连麦会使用设备的音频和摄像头权限,需要添加麦克风和摄像头权限声明
  • 关闭ATS ,SDK中部分地址不支持 HTTPS
<key>NSCameraUsageDescription</key>
<string>应用需要访问您的摄像头权限</string>
<key>NSMicrophoneUsageDescription</key>
<string>应用需要访问您的麦克风权限</string>
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

2.2 集成

播放器和接口部分为封装好的 Framework,可以通过 CocoaPods 方式集成(建议方式),也可以直接添加至项目中集成。

2.2.2 通过 CocoaPods 集成 Framework

podfile 文件配置信息

platform :ios, '9.0'

target 'PolyvLiveSDKDemo' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  use_frameworks!

  # Pods for PolyvLiveSDKDemo
  pod 'Masonry', '~> 1.1'
  pod 'MBProgressHUD', '~> 1.1.0'
  pod 'SDWebImage', '~> 4.4.0'

  pod 'PolyvLiveAPI', '~> 0.6.0'      # Polyv live api
  pod 'PolyvSocketAPI', '~> 0.5.0'    # Polyv socket.io api
  pod 'PolyvIJKPlayer', '~> 0.3.0'    # Polyv ijkPlayer
  pod 'AgoraRtcEngine_iOS', '~>2.0.0' # Agora rtc engine
end

需要使用 use_frameworks! ,因为 PolyvSocketAPI 依赖了 Swift 库

如果 PolyvSocketAPI 是 0.4.0 版本之下,还需要添加以下内容:

# 以下设置 Pods 子 Target 的 Swift 版本为 4.0(PolyvSocketAPI 0.4.0版本下)
post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |configuration|
            configuration.build_settings['SWIFT_VERSION'] = "4.0"
        end
    end
end
# 或不添加以上内容,执行完 pod install/update 后手动设置 Starscream 库的 swift 版本为 4.0,操作如下:
# 进入Project(Pods)->Target(Starscream)->Build settings->Swift Language Version,设置为 "Swift 4.0"

2.2.3 直接/手动集成Framework

​ 手动集成 Framework 需要参考版本信息下载相关库,然后手动添加至工程项目中,相关下载可参考 2.3 依赖库信息。

  • PolyvLiveAPI

  • PLVSocketAPI

    有两个 Swift 依赖库:SocketIO.framework、Starscream.framework,该依赖库可以直接使用 pods 添加: pod 'Socket.IO-Client-Swift',手动添加需要以下配置:

    • 将 SocketIO.framework 、Starscream.framework 库添加至项目的 Embeded Binaries
    • 设置 Build Settings -> Always Embed Swift Standard LibrariesYES
  • IJKMediaFramework.framework

    需要导入以下依赖库

 #     Select your Application's target.
 #     Build Phases -> Link Binary with Libraries -> Add:
 #         AudioToolbox.framework
 #         AVFoundation.framework
 #         CoreGraphics.framework
 #         CoreMedia.framework
 #         CoreVideo.framework
 #         libbz2.tbd
 #         libz.tbd
 #         MediaPlayer.framework
 #         MobileCoreServices.framework
 #         OpenGLES.framework
 #         QuartzCore.framework
 #         UIKit.framework
 #         VideoToolbox.framework
 #         libstdc++.tbd (iOS 12 不再支持此库,替换为 libc++ )

完成以上操作后可以真机和虚拟机下分别编译检查是否通过

2.3 依赖库信息

Framework IJKMediaFramework PLVLiveAPI PLVSocketAPI
功能 直播/点播播放器 直播相关接口 Socket.IO 相关接口
CocoaPods pod 'PolyvIJKPlayer' pod 'PolyvLiveAPI pod 'PolyvSocketAPI'
文档 Readme Readme Readme
发布版本 Release Release Release
第三方依赖库 SocketIO.framework、Starscream.framework
备注 Podfile 配置中需要添加 use_frameworks!
  • IJKMediaFramework.framework

    保利威 iOS点播、直播播放器,基于ijkplayer ,编译过程参考 ijkplayer Readme.md 中 Build iOS。

    • 支持 HTTPS
    • 支持 HLS AES-126 加密视频
    • 修复了原项目中部分已知问题
    • 支持 i386、x86_64、armv7、arm64 架构 CUP
  • PLVLiveAPI.framework

    保利威 iOS 直播观看、推流、聊天室相关接口

  • PLVSocketAPI.framework

    保利威 SocketIO 封装对象接口,用于聊天室、连麦、云课堂、互动课堂消息接收、发送等

三 代码示例

3.1 初始化播放器

​ 参看 LivePlayerViewController

- (void)loadPlayer {
    self.livePlayer = [self initializeLivePlayer];
    
    __weak typeof(self)weakSelf = self;
    [PLVLiveAPI getStreamStatusWithChannelId:self.channelId stream:self.stream completion:^(PLVLiveStreamState streamState, NSString *mode) {
        if (streamState == PLVLiveStreamStateNoStream) {
            [weakSelf.livePlayer playWithCover];
        }else {
            [weakSelf.livePlayer play];
        }
    } failure:^(PLVLiveErrorCode errorCode, NSString *description) {
        [weakSelf.livePlayer play];
    }];
    
    // 注册播放器通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerReconnectNotification:) name:PLVLivePlayerReconnectNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerWillChangeToFullScreenNotification) name:PLVLivePlayerWillChangeToFullScreenNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(livePlayerWillExitFullScreenNotification) name:PLVLivePlayerWillExitFullScreenNotification object:nil];
}

- (PLVLivePlayerController *)initializeLivePlayer {
    if (_livePlayer) {
        [_livePlayer clearPlayer];
        _livePlayer = nil ;
    }
    _livePlayer = [[PLVLivePlayerController alloc] initWithChannel:self.channel displayView:self.displayView];
    //[IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_INFO];    // 日志等级
    [self configCallBackBlock];
    
    [_livePlayer insertDanmuView:self.danmuLayer]; // 添加弹幕层
    
    return _livePlayer;
}

3.2 配置后台统计参数

​ 参看,AppDelegate,初始化播放器前配置即可

// 配置统计后台参数:用户Id、用户昵称、自定义参数4、自定义参数5
[PLVLiveConfig setViewLogParam:@"test id" param2:@"test nick" param4:nil param5:nil];

3.3 聊天室

3.3.1 初始化 socket

  • 请求连麦授权接口
  • 初始化 socket 及 连接 -connect
@property (nonatomic, strong) PLVSocketIO *socketIO;

- (void)initSocketIO {
    __weak typeof(self)weakSelf = self;
    // 获取连接授权 token
    [PLVLiveAPI requestAuthorizationForLinkingSocketWithChannelId:self.channelId Appld:[PLVLiveConfig sharedInstance].appId appSecret:[PLVLiveConfig sharedInstance].appSecret success:^(NSDictionary *responseDict) {
        // 1.初始化 socketIO 连接对象
        weakSelf.socketIO = [[PLVSocketIO alloc] initSocketIOWithConnectToken:responseDict[@"chat_token"] enableLog:NO];
        weakSelf.socketIO.delegate = weakSelf;
        [weakSelf.socketIO connect];
        
        // 2.初始化一个socket登录对象,或在 socketIO:didConnectWithInfo: 回调中配置
        
        // 3.数据存储
        PLVLiveManager *manager = [PLVLiveManager sharedLiveManager];
        manager.linkMicParams = responseDict;
    } failure:^(PLVLiveErrorCode errorCode, NSString *description) {
        [PLVUtils showHUDWithTitle:@"聊天室连接失败!" detail:[NSString stringWithFormat:@"错误码:%ld, 信息:%@",errorCode,description] view:self.view];
    }];
}

3.3.2 登录/配置昵称和头像

在连接成功的回调方法中进行登录操作

#pragma mark - <PLVSocketIODelegate>
/// 连接成功
- (void)socketIO:(PLVSocketIO *)socketIO didConnectWithInfo:(NSString *)info {
    NSLog(@"%@--%@",NSStringFromSelector(_cmd),info);
    // 初始化一个 socket 登录对象,配置昵称和头像
    PLVSocketObject *login = [PLVSocketObject socketObjectForLoginEventWithRoomId:self.channelId nickName:self.nickName avatar:self.avatar userType:PLVSocketObjectUserTypeStudent];
	// 登录聊天室
	[socketIO emitMessageWithSocketObject:login];
	// 存储,login 可作为发送其他消息的一个初始化参数
	[PLVLiveManager sharedLiveManager].login = login;
}

3.3.3 回调事件

其他回调事件参看 PLVSocketIODelegate

@required
/** SocketIO 连接服务器成功*/
- (void)socketIO:(PLVSocketIO *)socketIO didConnectWithInfo:(NSString *)info;

@optional
/** SocketIO 用户状态改变*/
- (void)socketIO:(PLVSocketIO *)socketIO didUserStateChange:(PLVSocketUserState)userState;

/** SocketIO 收到聊天室(公聊)消息*/
- (void)socketIO:(PLVSocketIO *)socketIO didReceivePublicChatMessage:(PLVSocketChatRoomObject *)chatObject;
/** SocketIO 收到聊天室(私聊)消息*/
- (void)socketIO:(PLVSocketIO *)socketIO didReceivePrivateChatMessage:(PLVSocketChatRoomObject *)chatObject;
/** SocketIO 收到连麦消息*/
- (void)socketIO:(PLVSocketIO *)socketIO didReceiveLinkMicMessage:(PLVSocketLinkMicObject *)linkMicObject;
/** SocketIO 收到云课堂消息*/
- (void)socketIO:(PLVSocketIO *)socketIO didReceivePPTMessage:(PLVSocketPPTObject *)pptObject;
/** SocketIO 收到互动课堂消息*/
- (void)socketIO:(PLVSocketIO *)socketIO didReceiveClassMessage:(PLVSocketClassObject *)classObject;

/** SocketIO 收到答题卡问题信息*/
- (void)socketIO:(PLVSocketIO *)socketIO didReceiveQuestionContent:(NSString *)json;
/** SocketIO 收到答题卡答案信息*/
- (void)socketIO:(PLVSocketIO *)socketIO didReceiveQuestionResult:(NSString *)json;

/** SocketIO 和服务器失去连接*/
- (void)socketIO:(PLVSocketIO *)socketIO didDisconnectWithInfo:(NSString *)info;
/** SocketIO 连接服务器出错*/
- (void)socketIO:(PLVSocketIO *)socketIO connectOnErrorWithInfo:(NSString *)info;
/** SocketIO 重新连接服务器*/
- (void)socketIO:(PLVSocketIO *)socketIO reconnectWithInfo:(NSString *)info;

/** 本地出错信息回调*/
- (void)socketIO:(PLVSocketIO *)socketIO localError:(NSString *)description;

#pragma mark Deprecated
/** SocketIO 收到聊天室消息*/
- (void)socketIO:(PLVSocketIO *)socketIO didReceiveChatMessage:(PLVSocketChatRoomObject *)chatObject;

3.3.4 获取聊天室在线人数

  1. 通过 PLVLiveManager 单例的 onlineCount 属性获取(需要已连接聊天室,实时)

    /// 聊天室在线人数(实时)
    @property (nonatomic, readonly) NSUInteger onlineCount;
    
  2. 通过在线列表 PLVOnlineListController 实例对象的 onlineCount属性获取(不需要连接聊天室,更新频率较慢)

    /// 聊天室在线人数(定时刷新,15s)
    @property (nonatomic, readonly) NSUInteger onlineCount;
    

其他示例代码待补充,可参考 demo中 LivePlayerViewController 实现文件。

四 其他

4.1 关闭控制台系统日志

​ 部分系统下控制台信息会输出较多系统日志,可通过以下方式关闭:

​ 选择工程 Target -> Edit Scheme -> Run -> Arguments 的Environment Variables,添加 name OS_ACTIVITY_MODE value disable

4.2 控制台日志的版本信息

ijkplayer,或在控制台过滤关键字:version

 ff3.2--ijk0.7.2-20161107--001
 ===== custom modules begin =====
 register demuxer : ijklivehook
 ===== custom modules end =====
 2016-12-08 14:04:28.549 PolyvIJKLivePlayer[3004:121765] 
 !!!!!!!!!!
 actual: ff3.2--ijk0.7.2-20161107--001
  expect: ff3.2--ijk0.7.4--20161116--001

 !!!!!!!!!!
 av_version_info: ff3.2--ijk0.7.2-20161107--001
 ijk_version_info: k0.7.5

4.3 开启/关闭视频硬解码

​ 硬解码需要最低 iOS8.0 系统支持,默认在 PLVLivePlayerController.m 中初始化开启设备的硬解码,如不使用可以关闭(不建议,占用较多的cpu资源)