オーディオストリーミング
このパッケージではオーディオストリーミングを実装するクラスとして AudioStreamTrack を提供しています。このクラスを利用して AudioSource をピア間で送受信できます。 また SetData メソッドを利用することで AudioSource 以外の音源で生成された生データを渡すことも可能です。
Note
サンプル にはオーディオに関する機能を紹介する Audio シーンが含まれています。
オーディオの送信
音源となる AudioSource をコンストラクタの引数に渡して AudioStreamTrack インスタンスを作成します。
// `AudioSource` をコンストラクタに渡して `AudioStreamTrack` インスタンスを作成。
var inputAudioSource = GetComponent<AudioSource>();
var track = new AudioStreamTrack(inputAudioSource);
// `RTCPeerConnection` インスタンスにトラックを追加。
var sendStream = new MediaStream();
var sender = peerConnection.AddTrack(track, sendStream);
RTCRtpSender インスタンスは RemoveTrack メソッドでトラックを削除するときに使います。
// `RTCPeerConnection` インスタンスからトラックを削除。
peerConnection.RemoveTrack(sender);
AudioStreamTrack のコンストラクタには2種類あります。1つは AudioSource を引数に持つもの、もう1つは引数を持たないものです。もし AudioListener を音源として利用したい場合は、引数なしのものを利用します。
SetData メソッドはオーディオデータを送信するために使用します。AudioSource をコンストラクタに渡した場合は SetData は AudioStreamTrack の内部で自動的に呼ばれます。引数なしのコンストラクタで作成した場合は、SetData は自身で呼び出す必要があります。なお、SetData メソッドはメインスレッドではなく、オーディオスレッドから呼ばれることを想定しています。詳細は OnAudioFilterRead を確認してください。
[RequireComponent(typeof(AudioListener))]
class AudioSender : MonoBehaviour
{
AudioStreamTrack track;
const int sampleRate = 48000;
// 初期化処理は省略しています。
// このメソッドはオーディオスレッドで実行されます。
private void OnAudioFilterRead(float[] data, int channels)
{
track.SetData(data, channels, sampleRate);
}
}
Note
AudioListener コンポーネントで OnAudioFilterRead メソッドを利用する際には、コンポーネントを GameObject にアサインしアクティブな状態にする必要があります。
オーディオの受信
オーディオストリーミングの受信に AudioStreamTrack を利用します。
RTCPeerConnection インスタンスの OnTrack イベントを処理して受信用のトラックを取得します。
イベントから受け取った MediaStreamTrack を TrackKind.Audio と比較して、 Track の値が AudioStreamTrack クラスとして利用できるか判定します。
var receivedAudioSource = GetComponent<AudioSource>();
var receiveStream = new MediaStream();
receiveStream.OnAddTrack = e => {
if(e.Track is AudioStreamTrack track)
{
// `AudioSource.SetTrack` は `Unity.WebRTC` 名前空間に拡張メソッドとして
// 定義されています。
receivedAudioSource.SetTrack(track);
// `loop` フラグを有効にしてください。
receivedAudioSource.loop = true;
receivedAudioSource.Play();
}
else if (e.Track is VideoStreamTrack track)
{
// この Track は映像用です。
}
}
var peerConnection = new RTCPeerConnection();
peerConnection.OnTrack = (RTCTrackEvent e) => {
if (e.Track.Kind == TrackKind.Audio)
{
// 受信用の `MediaStream` に Track を追加します。
// この処理は `MediaStream` の `OnAddTrack` イベントを発火します。
receiveStream.AddTrack(e.Track);
}
};