shiguredo / sora-ios-sdk

WebRTC SFU Sora iOS SDK
https://sora-ios-sdk.shiguredo.jp/
Apache License 2.0
42 stars 8 forks source link

画面キャプチャ時の音声データの送信方法について #29

Open FromAtom opened 5 years ago

FromAtom commented 5 years ago

JSのSDKでは stream.addTrack(); と処理を行い、音声データを送信することができますが、それと同等の機能はiOS SDKではどのように実現すれば良いでしょう。

困っている点としては、 RPBroadcastSampleHandler を継承したClassで得られた CMSampleBuffermainStream.send(videoFrame: frame) で送りたいのですが、 .audioApp.audioMic: タイプの CMSampleBufferVideoFrame(from: CMSampleBuffer) でインスタンスが生成できない点です。

voluntas commented 5 years ago

@FromAtom 結論から先に言いますと、 Sora iOS SDK ではマイク以外の任意の音声データを送信することができません。これは libwebrtc (iOS) の音声に関する実装がデバイスのマイクと密接に結びついており、任意の音声データを送信する仕組みが用意されていないからです。 libwebrtc (iOS) の実装の問題であり、残念ながら Sora iOS SDK ではどうにもできず、有力な回避策もないのが現状です。ご期待に沿えず申し訳ありません。

なお、他社のサービスによっては iOS で任意の音声データを送信できる場合がありますが、そのようなサービスでは libwebrtc の実装にかなり手を加えている可能性があります。現在の弊社のリソースで libwebrtc の実装にカスタマイズを行い、メンテナンスを行うのは難しいので、その対応が現実的ではありません。

困っている点としては、 RPBroadcastSampleHandler を継承したClassで得られた CMSampleBuffermainStream.send(videoFrame: frame) で送りたいのですが、 .audioApp.audioMic: タイプの CMSampleBufferVideoFrame(from: CMSampleBuffer) でインスタンスが生成できない点です。

VideoFrame は上記の理由で音声データに対応していません。また、 VideoFrame は libwebrtc の RTCVideoFrame のラッパーとして実装されていますが、 RTCVideoFrame の現在の仕様では音声データを持てません。こちらも libwebrtc (iOS) 実装に依存しているためです。

申し訳ないです .. 。

voluntas commented 5 years ago

こちらの issues は問題が解決されるまで Open にしておきます。

FromAtom commented 5 years ago

@voluntas 詳細な説明ありがとうございます。libwebrtcの制約について理解しました。

問題を解決するために追加で質問なのですが、 https://github.com/shiguredo/sora-ios-sdk-samples/tree/develop/ScreenCastSample/ScreenCastSample を参考にReplayKitを利用したScreenCastを実装した場合は、問題なくマイク音声を取得して送信することができました。しかし、ReplayKitのBroadcast Upload Extensionを利用して画面収録を行った際には、マイク音声を送信することができませんでした。

ReplayKitのマイクが利用されないように、

Sora.shared.configureAudioSession {
    RPScreenRecorder.shared().isCameraEnabled = false
    RPScreenRecorder.shared().isMicrophoneEnabled = false

    do {
        try AVAudioSession.sharedInstance().setActive(true, options: [])
    } catch(let error) {
        print(error)
    }
}

といったコードを記載し、InfoPlistにもマイクを利用するための設定を記載してあります。そのうえで、 func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {} 内で .audioMic タイプのCMSampleBufferが取得されていることは確認できているのですが、実際に配信している動画ではマイク音声を送ることができません。

こちらはlibwebrtcの制約で、Broadcast Upload Extensionではマイク音声が送れないことになっているのでしょうか?それとも、なにかこちらで指定すべきパラメータなどが抜け漏れているのでしょうか?

voluntas commented 5 years ago

@FromAtom おまたせして申し訳ないです。今の所の結論としては libwebrtc 側の制約でマイク音声が流れないという認識でいます。

このマイク以外からの音声データが入力できない問題は弊社としても課題と考えておりまして、なんとか実現できないかと思い、以前1度調査をしたのですが、かなり難しい事がわかっています。

以前の調査資料の一部内容を省いたものです。

iOS SDK: 外部audioをWebRTC経由で流す方法の調査

なんとか実現をしたいと考えておりますので、もう一度、調査と検討してみます。おまたせして申し訳ありません。

FromAtom commented 5 years ago

@voluntas なるほど。やはり libwebrtc の制約の可能性が高いのですね。わかりました。

調査・検討していただけるとのことで、ありがとうございます。こちらでも調査を続けつつ、お待ちしております。