音声・映像入力ソースと LocalStream の作成方法
Publish をするためには、音声・映像入力ソースまたはデータソースと紐付いた LocalStream が必要です。
ここでは、音声・映像入力ソースに対して LocalStream をどのように作るか説明します。
概要
LocalStream を作る操作は以下の流れで行います。
- ソースの作成
- (一部ソースのみ)ソースのキャプチャ処理開始
- ソースから LocalStream を作成
音声ソース
マイク入力ソース
現在、マイク入力ソースのみ対応しています。
マイクを利用する場合は info.plist
の Privacy - Microphone Usage Description
を追加して、value にはユーザーにマイク利用許可を確認するプロンプトのメッセージを登録してください。
マイク入力ソースは MicrophoneAudioSource.init()
で作成できます。
このソースから createStream()
で LocalStream を作成できます。
let audioSource: MicrophoneAudioSource = .init() let localSteam: LocalAudioStream = audioSource.createStream()
後述の映像ソースで必要なキャプチャの操作は不要です。
Subscribe され次第、マイクから音声がキャプチャされます。
映像ソース
カメラソース
本体のカメラ(前面・背面)入力から LocalStream を作成します。
カメラを利用する場合は info.plist
の Privacy - Camera Usage Description
を追加して、value にはユーザーにカメラ利用許可を確認するプロンプトのメッセージを登録してください。
カメラ入力ソースは、CameraVideoSource.shared()
で取得できます。
このソースはキャプチャが同時に1つしかできないため、シングルトンインスタンスで管理しています。
次に、カメラの設定を行います。
SkyWay SDK がサポートしているカメラの一覧から、キャプチャを行うカメラを設定できます。
supportedCameras()
から一覧取得できます。
例えば、前面カメラの場合は以下のようなコードで取得できます。
let frontCam: AVCaptureDevice? = CameraVideoSource.supportedCameras().first(where: { $0.position == .front })
※iPhone Simulatorでは利用できるカメラが存在しないことに注意してください。
startCapturing(with:options:completion:)
でキャプチャを開始する必要があります。
try? await CameraVideoSource.shared().startCapturing(with:frontCam, options:nil)
このソースから createStream()
で LocalStream を作成できます。
let stream = CameraVideoSource.shared().createStream()
※キャプチャ開始は、`createStream()`の後に任意のタイミングで開始させることもできますが、キャプチャを開始し忘れた場合、SubscriberがStreamを受け取っても映像が描画されませんので注意してください。
カメラデバイスの変更による映像切り替え
カメラデバイスの変更は Unpublish->新しいソースの LocalStream の作成->Subscribe といったことをさせず、ソースのみ切り替えることができます。
CameraVideoSource
の change(_:)
をコールすることで、映像描画中でもカメラデバイス変更できます。
カメラ映像のプレビュー
自分自身がカメラ映像を Publish する前にプレビューを確認したいユースケースの場合などの場合は、CameraVideoSource.shared().attach(_:)
で CameraPreviewView
に描画できます。
動画ファイルソース
アプリ内のアセットにある動画ファイルの映像から、LocalStream を作成します。
FileVideoSource.init(filename:)
から拡張子まで含めたファイル名でインスタンスを生成します。
let fileSource: FileVideoSource = .init(filename: "hoge.mp4")
startCapturing(onError:)
でキャプチャを開始する必要があります。
fileSource.startCapturing(onError: nil)
このソースから createStream()
で LocalStream を作成できます。
let stream = fileSource.createStream()
任意の画像フレームソース
CMSampleBuffer
型の画像データを連続的に更新し、その映像ソースから LocalStream を作成します。
CustomFrameVideoSource.init()
でインスタンスを作成します。
let frameSource: CustomFrameVideoSource = .init()
このソースから createStream()
で LocalStream を作成できます。
let stream = frameSource.createStream()
キャプチャループ内などで updateFrame(with:)
をコールして画像を更新します。
{ // フレーム更新ループ内などで frameSource.updateFrame(with:buffer) }
画面共有
ReplayKit と組み合わせることで、アプリ内の画面共有を行うことができます。
let source: CustomFrameVideoSource = .init() RPScreenRecorder.shared().startCapture { buffer, _, err in guard err == nil else { return } source.updateFrame(with: buffer) } completionHandler: { _ in } stream = source.createStream()