ブログ
これまでに経験してきたプロジェクトで気になる技術の情報を紹介していきます。
SIPフォンを作る【第三回】
SIPフォンの作成第三回
登録、受信、発信ができるようになったので、とっても大事なRTP通信での通話部分を説明していきます。
通話ができなければ電話ではないですから。
第二回で後述すると書いたGenerate_SDP();とPrepare_RTP(SDP);について書きます あとはこれができれば電話のていは成すので自由に拡張するだけになりますからね。
public SessionDescription Generate_SDP()
{
SessionDescription session = new SessionDescription();
session.Version = 0;
Owner owner = new Owner();
owner.Username = username.text
owner.SessionID = 16264;
owner.Version = 18299;
owner.Address = NatIP;
session.Owner = owner;
session.Name = "SIP Call";
Connection connection = new Connection();
connection.Address = NatIP;
session.Connection = connection;
var time = new Independentsoft.Sip.Sdp.Time(0, 0);
session.Time.Add(time);
Media media1 = new Media();
media1.Type = "audio";
media1.Port = NatPort;
media1.TransportProtocol = "RTP/AVP";
media1.MediaFormats.Add("0");
media1.MediaFormats.Add("101");
media1.Attributes.Add("rtpmap", "0 PCMU/8000");
media1.Attributes.Add("rtpmap", "101 telephone-event/8000");
media1.Attributes.Add("fmtp", "101 0-11");
session.Media.Add(media1);
return session;
}
元々SIP.Netのサイトにあったサンプルを持ってきただけでOwner型の辺りが何の値を受け取っているのかよくわからないのでその辺はそのまま使います、IPはNAPT変換された物、SIPサーバーから見たときのものを入れます。 Media型で定義されているところは重要なので、解説していきます。 これはRTPのペイロードに載せるデータのエンコード形式を書きます、SIPサーバーや相手の端末でデコードするのに必要になる情報ですね。 今回使うのはPCMU(u-Law)でエンコードされたサンプリング周波数8000Hzのデータなので記述はこうなっています、RTPのヘッダーにペイロードタイプ0を書き込むとこのデータはPCMUの8000Hzという形で認識されるわけですね。
これで生成されたデータはSIPでInviteやそれに対するOKに載ってSIPサーバーに届き通信を確立させます。 音声をRTPで送受信するそれぞれのオブジェクトに共通のsocketを渡してSDPから得た相手の受信ポートに音声を投げます。 SIPサーバーがAsteriskの場合、送信に使用したポートに対して音声を送ってくるので、同じsocketを指定するだけでよい。
[SerializeField] Send_Voice Send_RTP;
[SerializeField] Resive_Voice Resive_RTP;
Prepare_RTP(SDP)
{
var RemoteEndPoint = new IPEndPoint(IPAddress.Parse(SDP.Connection.Address),SDP.Media[0].Port) as EndPoint;
var LocalEndPoint = new IPEndPoint(IPAddress.Any, SDP.Media[0].Port);
client.UdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
client.Bind(LocalEndPoint);
Send_RTP.RemoteEndPoint = RemoteEndPoint as IPEndPoint;
Send_RTP.soc = client.UdpSocket;
Resive_RTP.soc = client.UdpSocket;
Audio_Objects_Enable();
}
Send_Voiceはオブジェクトがactiveになった時から指定したsocketで指定したRemoteEndPointにUnityのマイクからの入力をuLaw変換してUDPで送信し続けるというScriptを用意した、audiosauceが付いたオブジェクトにくっつけてそれを指定する。 Resive_Voiceはオブジェクトがactiveになった時から指定したsocketの値をUDPで受け取り続けてuLawからPCM(非圧縮音源)にして出力し続けるというScriptを用意した、audiosauceがついたオブジェクトにくっつけてそれを指定する。 Audio_Objects_Enable()は↑2つのオブジェクトをactiveにするメソッド、内容は二つをアクティブにできれば何でもよい。
Send_VoiceとResive_Voiceに関しては調べて出てきたやり方を切り貼りしすぎて要所要所の解説ができるほどに理解が深まっていないので、今解説できるのはここまでです。
コメントはありません。