ReplayKit+Agoraで画面共有がしたい
Agora導入手順
まずはAgoraのアカウント等作成しておく
コンソールを開いてProject > More
こちらの鍵マークからTokenを生成する
Tokenは24時間限定の一時的なもの
ChannelNameを設定して生成
今回はScreenShare
とする
こちらのiOSのAPIExampleをビルドしていく
初めに設定しておくのは以下の箇所
- KeyCenter.swiftの
AppId
とToken
を書き換える
struct KeyCenter {
static let AppId: String = "YourAppID"
// assign token to nil if you have not enabled app certificate
static var Token: String? = "TempToken"
}
- Agora-ScreenShare-Extension > AgoraUoloader.swiftの
byToken: nil
を書き換える
static func startBroadcast(to channel: String) {
sharedAgoraEngine.joinChannel(byToken: KeyCenter.Token, channelId: channel, info: nil, uid: 0, joinSuccess: nil)
}
ScreenShareを選択しチャンネル名を指定してjoin
ビデオ通話、画面共有が確認できる
WebSDKとの相互運用
デモページから確認できる
ビデオ通話について
- クイックスタート
https://docs.agora.io/en/Video/start_call_ios - API Reference
https://docs.agora.io/en/api-reference?platform=ios
ReplayKit
アプリ内で画面録画、音声録音、ライブストリーミングなどを可能にするフレームワーク。
ReplayKitを使用することで、簡単に画面の録画やライブストリーミングを行うことができます。
BroadcastUploadExtension
ReplayKitを使用してiOSアプリで画面共有機能を実装するための拡張機能。
BroadcastExtensionを追加することで、アプリ内で録画した画面を外部のアプリやWebページなどに配信することができます。
画面共有に関してはもう一人ユーザーがjoinするイメージ。
Extensionの追加
Fileメニューから New > Target > Broadcastと入力
画面共有用のボタン
赤枠のボタンを追加していく
let frame = CGRect(x: 0, y:0, width: 60, height: 60)
let systemBroadcastPicker = RPSystemBroadcastPickerView(frame: frame)
systemBroadcastPicker.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin]
if let url = Bundle.main.url(forResource: "Agora-ScreenShare-Extension", withExtension: "appex", subdirectory: "PlugIns") {
if let bundle = Bundle(url: url) {
systemBroadcastPicker.preferredExtension = bundle.bundleIdentifier
}
}
broadcasterPickerContainer.addSubview(systemBroadcastPicker)
タップするとBroadcastPickerViewが表示される
SampleHandlerに処理を書いていく
import ReplayKit
class SampleHandler: RPBroadcastSampleHandler {
// 配信開始時に呼ばれる
override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
if let setupInfo = setupInfo, let channel = setupInfo["channelName"] as? String {
//In-App Screen Capture
AgoraUploader.startBroadcast(to: channel)
} else {
//iOS Screen Record and Broadcast
AgoraUploader.startBroadcast(to: "channel")
}
}
// 配信が一時停止したときに呼ばれる
override func broadcastPaused() {
// User has requested to pause the broadcast. Samples will stop being delivered.
}
// 配信が一時停止された後、再開されたときに呼ばれる
override func broadcastResumed() {
// User has requested to resume the broadcast. Samples delivery will resume.
}
// 配信終了時に呼ばれる
override func broadcastFinished() {
AgoraUploader.stopBroadcast()
}
// エラーが発生して終了するときに呼ばれる
override func finishBroadcastWithError(_ error: Error) {
print("finishBroadcastWithError: \(error)")
}
// SampleBufferを生成するたびに呼ばれる(受け取ったSampleBufferの処理など)
override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
DispatchQueue.main.async {
switch sampleBufferType {
case .video:
// ここでsampleBufferを送っている
AgoraUploader.sendVideoBuffer(sampleBuffer)
case .audioApp:
AgoraUploader.sendAudioAppBuffer(sampleBuffer)
case .audioMic:
AgoraUploader.sendAudioMicBuffer(sampleBuffer)
@unknown default:
break
}
}
}
}
アプリから終了するには?
アプリ側から終了させるにはエラー終了させる必要があります。
override func finishBroadcastWithError(_ error: Error) {
print("finishBroadcastWithError: \(error)")
}
ユーザーがチャンネルを離れたタイミングでエラー終了させる。
let message = "画面共有を停止しました"
let userInfo = [NSLocalizedFailureReasonErrorKey: message]
let error = NSError(domain: "BroadcastExtension", code: 1, userInfo: userInfo)
super.finishBroadcastWithError(error)
Extensionのデバッグ方法
BroadcastUploadExtensionを指定して、アプリを選択してビルドする
データの共有方法
AppGroupsを追加してUserDefaultsで共有する
// 保存
UserDefaults(suiteName: "group.jp.hoge")?.setValue("abcdefg", forKey: "key")
// 取得
UserDefaults(suiteName: "group.jp.hoge")?.string(forKey: "key")
ファイルの共有方法
Extensionに共有したいファイルを選択→InspectorのTargetMemberShipでExtensionを選択する
まとめ
基本的にドキュメントが豊富で、サンプルを動かしてみることで実装方法は概ね理解できました。
Web側との確認用も準備されているのでやりとりもしやすかったです。
とてもとても参考にさせていただきました
https://speakerdeck.com/fromatom/iosdc2019
https://speakerdeck.com/matsuokah/live-streaming-with-screen-recording
Discussion