声网为 CDN 直播推流场景研发 Streaming Kit(推流组件),支持将单个主播音视频流推送到 CDN。如果你同时集成 Streaming Kit 和声网 RTC SDK,你还可以在观众无感知的情况下实现单主播和多主播画面的动态切换。
声网在 GitHub 上提供开源的 RtmpStreaming 示例项目供你参考。
参考以下步骤创建一个 iOS 项目。
打开 Xcode 并点击 Create a new Xcode project。
选择项目类型为 Single View App,并点击 Next。
输入项目信息,如项目名称、开发团队信息、组织名称和语言,并点击 Next。
Note:如果你没有添加过开发团队信息,会看到 Add account… 按钮。点击该按钮并按照屏幕提示登入 Apple ID,完成后即可选择你的账户作为开发团队。
选择项目存储路径,并点击 Create。
将你的 iOS 设备连接至电脑。
进入 TARGETS > Project Name > Signing & Capabilities 菜单,选择 Automatically manage signing,并在弹出菜单中点击 Enable Automatic。
方法一:使用 CocoaPods 自动集成
开始前请确保你已安装 Cocoapods。参考 Getting Started with CocoaPods 安装说明。
在 Terminal 里进入项目根目录,并运行 pod init
命令。项目文件夹下会生成一个 Podfile 文本文件。
打开 Podfile 文件,修改文件为如下内容。注意将 Your App
替换为你的 Target 名称。
target 'Your App' do
pod 'AgoraStreamingKit_iOS'
end
在 Terminal 内运行 pod update
命令更新本地库版本。
运行 pod install
命令安装 Streaming Kit。成功安装后,Terminal 中会显示 Pod installation complete!
,此时项目文件夹下会生成一个 xcworkspace
文件。
打开新生成的 xcworkspace
文件。
方法二:手动复制 Streaming Kit 文件
前往下载页面,下载最新版 Streaming Kit,然后解压。
将 libs
文件夹内的 AgoraStreamingKit.framework
文件复制到项目文件夹下。
在 TARGETS > Project Name > General > Frameworks, Libraries, and Embedded Content 菜单中,将 AgoraStreamingKit.framework
的状态修改为 Embed & Sign。
打开 Xcode,进入 TARGETS > Project Name > Build Phases > Link Binary with Libraries 菜单,点击 + 添加如下库。在添加 AgoraStreamingKit.framework
文件时,还需在点击 + 后点击 Add Other…,找到本地文件并打开。
AgoraStreamingKit.framework
Accelerate.framework
AudioToolbox.framework
AVFoundation.framework
CoreMedia.framework
CoreML.framework
CoreTelephony.framework
libc++.tbd
libresolv.tbd
SystemConfiguration.framework
VideoToolbox.framework
添加后:
如需支持 iOS 11 或更低版本的设备,请在 Xcode 中将对 CoreML.framework 的依赖设为 Optional。
根据场景需要,在 info.plist 文件中,点击 + 图标开始添加如下内容,获取相应的设备权限:
Key | Type | Value |
---|---|---|
Privacy - Microphone Usage Description | String | 使用麦克风的目的,例如:for live streaming |
Privacy - Camera Usage Description | String | 使用摄像头的目的,例如:for live streaming |
你可以参考本节依次实现如下功能:
创建一个 AgoraStreamingKit
实例,并设置 AgoraStreamingContext
的如下参数:
appId
: 你的 App ID。delegate
: 详见 AgoraStreamingDelegate
。audioStreamConfiguration
: 音频编码属性。推荐使用默认的音频编码属性:采样率 44.1 kHz,码率 48 Kbps,16 bits,单声道,LC-AAC。videoStreamConfiguration
: 视频编码属性,推荐使用默认的视频编码属性:分辨率 640 * 360,帧率 15 fps,码率 800 Kbps,方向模式为 OrientationModeFixedPortrait (2)
。- (void)createStreamingKit {
AgoraStreamingContext *context = [[AgoraStreamingContext alloc] init];
// 设置音频配置信息
context.audioStreamConfiguration = [AgoraAudioStreamConfiguration defaultConfiguration];
// 设置视频配置信息
context.videoStreamConfiguration = [AgoraVideoStreamConfiguration defaultConfiguration];
context.appId = @"AppId";
// 设置代理回调
context.delegate = self;
// 初始化 AgoraStreamingKit 单实例
self.streamingKit = [AgoraStreamingKit sharedStreamingKitWithContext:context];
}
你可以使用默认的日志设置。如果你需要管理日志,请在创建 Streaming Kit 后立即调用如下方法。
- (void)setupLog:(NSString *)filePath {
// 设置日志文件路径,默认为 App Sandbox/Library/Caches/streaming-kit.log
[self.streamingKit setLogFile:filePath];
// 设置日志文件大小,默认为 512 KB
[self.streamingKit setLogFileSize:512];
// 设置日志过滤级别,默认为 INFO
[self.streamingKit setLogFilter:LogFilterInfo];
}
如果你想让主播在直播推流开始前进行本地预览,请在创建 Streaming Kit 后调用如下方法:
- (void)setupPreview:(UIView *)view {
//(必须)获取 preview renderer 对象,以管理所有与渲染相关的操作
AgoraVideoPreviewRenderer *previewRenderer = [self.streamingKit getVideoPreviewRenderer];
// 设置本地预览视图
[previewRenderer setView:view];
// 设置本地预览视图的镜像模式,默认情况下,使用前置摄像头开启镜像,使用后置摄像头不开启镜像
[previewRenderer setMirrorMode:MirrorModeAuto];
// 设置本地预览渲染模式,默认为 FIT 模式
[previewRenderer setRenderMode:RenderModeFit];
}
开始直播推流前,你需要让 Streaming Kit 对主播进行录音和视频采集。该步骤和步骤 3 无严格先后顺序。
// 开启录音,不支持推流过程中调用
[self.streamingKit enableAudioRecording:YES];
// 开启视频采集,不支持推流过程中调用
[self.streamingKit enableVideoCapturing:YES];
如果你使用 1.1.0 版及之后的 Streaming Kit,你可以在摄像头开启后管理摄像头,实现手动对焦、人脸自动对焦、变焦、切换分辨率等功能。
// 设置摄像头手动对焦
if ([self.cameraCapturer isCameraFocusPositionInPreviewSupported]) {
CGPoint position = CGPointMake(0.5, 0.5);
[self.cameraCapturer setCameraFocusPositionInPreview:position];
}
// 设置摄像头人脸自动对焦
if ([self.cameraCapturer isCameraAutoFocusFaceModeSupported]) {
[self.cameraCapturer setCameraAutoFocusFaceModeEnabled:YES];
}
// 设置摄像头变焦倍数,放大摄像头采集的视频图像
if ([self.cameraCapturer isCameraZoomSupported]) {
CGFloat maxZoom = [self.cameraCapturer getMaxZoom];
CGFloat zoom = 1.0;
[self.cameraCapturer setCameraZoomFactor:zoom];
}
// 切换分辨率
[self.streamingKit switchResolution:CGSizeMake(720, 1280)];
如果你想给主播美颜,请调用 addVideoFilter
向 video track 添加一个 video filter。然后自行实现 VideoFilter 类,使用该类的 process
方法。
Streaming Kit 通过 process
方法的 inputPixelBuffer
参数向你输出采集到的视频帧。拿到视频帧后,你可以通过第三方 SDK 对视频帧进行美颜等前处理。最后,将处理后的视频帧通过 process
方法的返回值传回 Steaming Kit。
如果你想抛弃视频帧,将返回值传空。
// 添加自定义美颜
[self.streamingKit addVideoFilter:videoFilter];
// 删除自定义美颜
[self.streamingKit removeVideoFilter:videoFilter];
调用如下方法开始推流:
// 开始单主播直推 CDN
[self.streamingKit startStreaming:publishUrl];
// 停止单主播直推 CDN
[self.streamingKit stopStreaming];
startStreaming
成功和失败会分别触发 onStartStreamingSuccess
和 onStartStreamingFailure
回调。失败时,请通过 AgoraStartStreamingError
排查问题。startStreaming
成功后,如果推送的媒体流出错,kit 会触发 onMediaStreamingFailure
回调。你可以通过 AgoraMediaStreamingError
和 msg
信息排查媒体流的问题。推流过程中,你可以通过 onStreamingConnectionStateChanged
回调监听当前推流状态,详见 AgoraStreamingConnectionState
。
如果你想只推视频流或只推音视流,你可以在 startStreaming
后调用 muteAudioStream
或 muteVideoStream
。如果你想切换摄像头,可以在 startStreaming
前和后调用 switchCamera
。
- Streaming Kit 在 iOS 设备上默认使用前置摄像头。
- Streaming Kit 不支持在
startStreaming
后调用enableAudioRecording
、enableVideoCapturing
、switchResolution
。
销毁 Streaming Kit 后,请确保不再使用 Streaming Kit 提供的 API。
// 销毁 StreamingKit ,同时需要将实例置为 nil
[self.streamingKit releaseStreamingKit];
self.streamingKit = nil;
当其他主播加入单主播的直播推流时,你需要先结束单主播的 CDN 直播推流,然后注册音视频观测器接收音频帧,并将音视频帧作为 RTC SDK 的自定义音频源和自定义视频源。最后使用 RTC SDK 提供的旁路推流 API 完成多主播的直播推流。
- (void)switchToAgoraChannel {
// 结束单主播 CDN 直播推流
[self.streamingKit stopStreaming];
// 设置 RTC SDK 自定义音频源
[self.agoraKit enableExternalAudioSourceWithSampleRate:audioSampleRate channelsPerFrame:audioChannels];
// 设置 RTC SDK 自定义视频源
[self.agoraKit setExternalVideoSource:YES useTexture:YES pushMode:YES];
// 加入声网频道
[self.agoraKit joinChannelByToken:[KeyCenter Token] channelId:self.roomName info:nil uid:0 joinSuccess:nil];
// 在 onJoinChannelSuccess 和 didJoinedOfUid 回调之后,依次调用 setLiveTranscoding 和 addPublishStreamUrl 开始旁路推流
......
}
详情请参考如下文档:
当其他主播离开单主播的直播推流时,你需要使用 RTC SDK 的推流 API 结束多主播的直播推流,然后离开 RTC 频道,并取消注册音视频观测器。最后开始单主播的直播推流。
- (void)switchToRtmpStreaming {
// 结束 RTC SDK 提供的旁路推流
[self.agoraKit removePublishStreamUrl:self.publishUrl];
// 退出声网 RTC 频道
[self.agoraKit leaveChannel:nil];
// 关闭 RTC SDK 自定义音频源
[self.agoraKit disableExternalAudioSource];
// 关闭 RTC SDK 自定义视频源
[self.agoraKit setExternalVideoSource:NO useTexture:NO pushMode:NO];
// 开始单主播 CDN 直播推流
[self.streamingKit startStreaming:self.publishUrl];
}