1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246 |
- using System;
- using UnityEngine;
- using UnityEngine.TestTools;
- using NUnit.Framework;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using Object = UnityEngine.Object;
- namespace Unity.WebRTC.RuntimeTest
- {
- class PeerConnectionTest
- {
- static RTCConfiguration GetDefaultConfiguration()
- {
- RTCConfiguration config = default;
- config.iceServers = new[]
- {
- new RTCIceServer
- {
- urls = new[] {"stun:stun.l.google.com:19302"},
- username = "",
- credential = "",
- credentialType = RTCIceCredentialType.Password
- }
- };
- config.iceTransportPolicy = RTCIceTransportPolicy.All;
- config.iceCandidatePoolSize = 0;
- config.bundlePolicy = RTCBundlePolicy.BundlePolicyBalanced;
- return config;
- }
- [SetUp]
- public void SetUp()
- {
- WebRTC.Initialize(true);
- }
- [TearDown]
- public void TearDown()
- {
- WebRTC.Dispose();
- }
- [Test]
- public void Construct()
- {
- var peer = new RTCPeerConnection();
- Assert.AreEqual(0, peer.GetReceivers().Count());
- Assert.AreEqual(0, peer.GetSenders().Count());
- Assert.AreEqual(0, peer.GetTransceivers().Count());
- Assert.AreEqual(RTCPeerConnectionState.New, peer.ConnectionState);
- Assert.That(() => peer.LocalDescription, Throws.InvalidOperationException);
- Assert.That(() => peer.RemoteDescription, Throws.InvalidOperationException);
- Assert.That(() => peer.PendingLocalDescription, Throws.InvalidOperationException);
- Assert.That(() => peer.PendingRemoteDescription, Throws.InvalidOperationException);
- Assert.That(() => peer.CurrentLocalDescription, Throws.InvalidOperationException);
- Assert.That(() => peer.CurrentRemoteDescription, Throws.InvalidOperationException);
- peer.Close();
- Assert.AreEqual(RTCPeerConnectionState.Closed, peer.ConnectionState);
- peer.Dispose();
- }
- [Test]
- public void AccessAfterDisposed()
- {
- var peer = new RTCPeerConnection();
- peer.Dispose();
- Assert.That(() => { var state = peer.ConnectionState; }, Throws.TypeOf<ObjectDisposedException>());
- }
- [Test]
- public void GetConfiguration()
- {
- var config = GetDefaultConfiguration();
- var peer = new RTCPeerConnection(ref config);
- var config2 = peer.GetConfiguration();
- Assert.That(config.iceServers, Is.Not.Null);
- Assert.That(config2.iceServers, Is.Not.Null);
- Assert.That(config.iceServers.Length, Is.EqualTo(config2.iceServers.Length));
- Assert.That(config.iceServers[0].username, Is.EqualTo(config2.iceServers[0].username));
- Assert.That(config.iceServers[0].credential, Is.EqualTo(config2.iceServers[0].credential));
- Assert.That(config.iceServers[0].urls, Is.EqualTo(config2.iceServers[0].urls));
- Assert.That(config.iceTransportPolicy, Is.EqualTo(RTCIceTransportPolicy.All));
- Assert.That(config.iceTransportPolicy, Is.EqualTo(config2.iceTransportPolicy));
- Assert.That(config.enableDtlsSrtp, Is.Null);
- Assert.That(config.enableDtlsSrtp, Is.EqualTo(config2.enableDtlsSrtp));
- Assert.That(config.iceCandidatePoolSize, Is.EqualTo(config2.iceCandidatePoolSize));
- Assert.That(config.bundlePolicy, Is.EqualTo(config2.bundlePolicy));
- peer.Close();
- peer.Dispose();
- }
- [Test]
- public void ConstructWithConfigThrowException()
- {
- RTCConfiguration config = default;
- // To specify TURN server, also needs `username` and `credential`.
- config.iceServers = new[]
- {
- new RTCIceServer { urls = new[] {"turn:127.0.0.1?transport=udp"} }
- };
- Assert.That(() => { new RTCPeerConnection(ref config); }, Throws.ArgumentException);
- }
- [Test]
- public void SetConfiguration()
- {
- var peer = new RTCPeerConnection();
- var config = GetDefaultConfiguration();
- var result = peer.SetConfiguration(ref config);
- Assert.AreEqual(RTCErrorType.None, result);
- peer.Close();
- peer.Dispose();
- }
- [Test]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public void AddTrack()
- {
- var peer = new RTCPeerConnection();
- var width = 256;
- var height = 256;
- var format = WebRTC.GetSupportedRenderTextureFormat(UnityEngine.SystemInfo.graphicsDeviceType);
- var rt = new UnityEngine.RenderTexture(width, height, 0, format);
- rt.Create();
- var track = new VideoStreamTrack(rt);
- var sender = peer.AddTrack(track);
- Assert.That(sender, Is.Not.Null);
- Assert.That(track, Is.EqualTo(sender.Track));
- RTCRtpSendParameters parameters = sender.GetParameters();
- Assert.That(parameters, Is.Not.Null);
- Assert.That(parameters.encodings, Is.Empty);
- track.Dispose();
- peer.Dispose();
- Object.DestroyImmediate(rt);
- }
- [Test]
- public void AddTrackThrowException()
- {
- var peer = new RTCPeerConnection();
- Assert.Throws<ArgumentNullException>(() => peer.AddTrack(null));
- }
- [Test]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public void AddTransceiver()
- {
- var peer = new RTCPeerConnection();
- var width = 256;
- var height = 256;
- var format = WebRTC.GetSupportedRenderTextureFormat(SystemInfo.graphicsDeviceType);
- var rt = new UnityEngine.RenderTexture(width, height, 0, format);
- rt.Create();
- var track = new VideoStreamTrack(rt);
- Assert.That(peer.GetTransceivers(), Is.Empty);
- var transceiver = peer.AddTransceiver(track);
- Assert.That(transceiver, Is.Not.Null);
- Assert.That(transceiver.Mid, Is.Null);
- Assert.That(transceiver.CurrentDirection, Is.Null);
- RTCRtpSender sender = transceiver.Sender;
- Assert.That(sender, Is.Not.Null);
- Assert.That(track, Is.EqualTo(sender.Track));
- RTCRtpSendParameters parameters = sender.GetParameters();
- Assert.That(parameters, Is.Not.Null);
- Assert.That(parameters.encodings, Is.Empty);
- Assert.That(parameters.transactionId, Is.Not.Empty);
- Assert.That(peer.GetTransceivers(), Has.Count.EqualTo(1));
- Assert.That(peer.GetTransceivers().First(), Is.Not.Null);
- Assert.That(parameters.codecs, Is.Empty);
- Assert.That(parameters.rtcp, Is.Not.Null);
- // Some platforms return an empty list
- Assert.That(parameters.headerExtensions, Is.Not.Null);
- foreach (var extension in parameters.headerExtensions)
- {
- Assert.That(extension, Is.Not.Null);
- Assert.That(extension.uri, Is.Not.Empty);
- }
- track.Dispose();
- peer.Dispose();
- Object.DestroyImmediate(rt);
- }
- [Test]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public void GetTransceiversReturnsNotEmptyAfterDisposingTransceiver()
- {
- // `RTCPeerConnection.AddTransceiver` method is not intuitive. Moreover, we don't have the API to remove
- // the transceiver from RTCPeerConnection directly.
- var peer = new RTCPeerConnection();
- var transceiver = peer.AddTransceiver(TrackKind.Video);
- Assert.That(peer.GetTransceivers(), Has.Count.EqualTo(1));
- transceiver.Dispose();
- Assert.That(peer.GetTransceivers(), Has.Count.EqualTo(1));
- peer.Dispose();
- }
- [Test]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public void GetTransceiversReturnsNotEmptyAfterCallingRemoveTrack()
- {
- // Also, `RTCPeerConnection.AddTrack` and `RTCPeerConnection.RemoveTrack` method is not intuitive.
- var peer = new RTCPeerConnection();
- var width = 256;
- var height = 256;
- var format = WebRTC.GetSupportedRenderTextureFormat(UnityEngine.SystemInfo.graphicsDeviceType);
- var rt = new UnityEngine.RenderTexture(width, height, 0, format);
- rt.Create();
- var track = new VideoStreamTrack(rt);
- var sender = peer.AddTrack(track);
- Assert.That(peer.GetTransceivers(), Has.Count.EqualTo(1));
- Assert.That(peer.RemoveTrack(sender), Is.EqualTo(RTCErrorType.None));
- Assert.That(peer.GetTransceivers(), Has.Count.EqualTo(1));
- peer.Dispose();
- }
- [Test]
- public void AddTransceiverThrowException()
- {
- var peer = new RTCPeerConnection();
- Assert.Throws<ArgumentNullException>(() => peer.AddTransceiver(null));
- }
- [Test]
- public void AddTransceiverTrackKindAudio()
- {
- var peer = new RTCPeerConnection();
- var transceiver = peer.AddTransceiver(TrackKind.Audio);
- Assert.That(transceiver, Is.Not.Null);
- Assert.That(transceiver.CurrentDirection, Is.Null);
- RTCRtpReceiver receiver = transceiver.Receiver;
- Assert.That(receiver, Is.Not.Null);
- MediaStreamTrack track = receiver.Track;
- Assert.That(track, Is.Not.Null);
- Assert.That(track.Kind, Is.EqualTo(TrackKind.Audio));
- Assert.That(track, Is.TypeOf<AudioStreamTrack>());
- Assert.That(receiver.Streams, Has.Count.EqualTo(0));
- Assert.That(peer.GetTransceivers(), Has.Count.EqualTo(1));
- Assert.That(peer.GetTransceivers(), Has.All.Not.Null);
- peer.Dispose();
- }
- [Test]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public void AddTransceiverTrackKindVideo()
- {
- var peer = new RTCPeerConnection();
- var transceiver = peer.AddTransceiver(TrackKind.Video);
- Assert.That(transceiver, Is.Not.Null);
- Assert.That(transceiver.CurrentDirection, Is.Null);
- RTCRtpReceiver receiver = transceiver.Receiver;
- Assert.That(receiver, Is.Not.Null);
- MediaStreamTrack track = receiver.Track;
- Assert.That(track, Is.Not.Null);
- Assert.That(track.Kind, Is.EqualTo(TrackKind.Video));
- Assert.That(track, Is.TypeOf<VideoStreamTrack>());
- Assert.That(receiver.Streams, Has.Count.EqualTo(0));
- Assert.That(peer.GetTransceivers(), Has.Count.EqualTo(1));
- Assert.That(peer.GetTransceivers(), Has.All.Not.Null);
- peer.Dispose();
- }
- [Test]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public void AddTransceiverWithInit()
- {
- var peer = new RTCPeerConnection();
- var stream = new MediaStream();
- var direction = RTCRtpTransceiverDirection.SendOnly;
- var width = 256;
- var height = 256;
- var format = WebRTC.GetSupportedRenderTextureFormat(UnityEngine.SystemInfo.graphicsDeviceType);
- var rt = new RenderTexture(width, height, 0, format);
- rt.Create();
- var track = new VideoStreamTrack(rt);
- var init = new RTCRtpTransceiverInit()
- {
- direction = direction,
- sendEncodings = new RTCRtpEncodingParameters[] {
- new RTCRtpEncodingParameters { maxFramerate = 30 }
- },
- streams = new MediaStream[] { stream }
- };
- var transceiver = peer.AddTransceiver(track, init);
- Assert.That(transceiver, Is.Not.Null);
- Assert.That(transceiver.CurrentDirection, Is.Null);
- Assert.That(transceiver.Direction, Is.EqualTo(RTCRtpTransceiverDirection.SendOnly));
- Assert.That(transceiver.Sender, Is.Not.Null);
- var parameters = transceiver.Sender.GetParameters();
- Assert.That(parameters, Is.Not.Null);
- Assert.That(parameters.codecs, Is.Not.Null.And.Empty);
- peer.Dispose();
- }
- [Test]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public void AddTransceiverWithKindAndInit()
- {
- var peer = new RTCPeerConnection();
- var stream = new MediaStream();
- var direction = RTCRtpTransceiverDirection.SendOnly;
- var init = new RTCRtpTransceiverInit()
- {
- direction = direction,
- sendEncodings = new RTCRtpEncodingParameters[] {
- new RTCRtpEncodingParameters { maxFramerate = 30 }
- },
- streams = new MediaStream[] { stream }
- };
- var transceiver = peer.AddTransceiver(TrackKind.Video, init);
- Assert.That(transceiver, Is.Not.Null);
- Assert.That(transceiver.CurrentDirection, Is.Null);
- Assert.That(transceiver.Direction, Is.EqualTo(RTCRtpTransceiverDirection.SendOnly));
- Assert.That(transceiver.Sender, Is.Not.Null);
- var parameters = transceiver.Sender.GetParameters();
- Assert.That(parameters, Is.Not.Null);
- Assert.That(parameters.codecs, Is.Not.Null.And.Empty);
- var init2 = new RTCRtpTransceiverInit()
- {
- direction = null,
- sendEncodings = null,
- streams = null
- };
- var transceiver2 = peer.AddTransceiver(TrackKind.Video, init2);
- Assert.That(transceiver2, Is.Not.Null);
- Assert.That(transceiver2.CurrentDirection, Is.Null);
- Assert.That(transceiver2.Direction, Is.EqualTo(RTCRtpTransceiverDirection.SendRecv));
- Assert.That(transceiver2.Sender, Is.Not.Null);
- peer.Dispose();
- }
- [Test]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public void GetAndSetDirectionTransceiver()
- {
- var peer = new RTCPeerConnection();
- var transceiver = peer.AddTransceiver(TrackKind.Video);
- Assert.NotNull(transceiver);
- transceiver.Direction = RTCRtpTransceiverDirection.SendOnly;
- Assert.AreEqual(RTCRtpTransceiverDirection.SendOnly, transceiver.Direction);
- transceiver.Direction = RTCRtpTransceiverDirection.RecvOnly;
- Assert.AreEqual(RTCRtpTransceiverDirection.RecvOnly, transceiver.Direction);
- peer.Close();
- peer.Dispose();
- }
- [Test]
- public void GetTransceivers()
- {
- var peer = new RTCPeerConnection();
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- var track = new AudioStreamTrack(source);
- var sender = peer.AddTrack(track);
- Assert.That(peer.GetTransceivers().ToList(), Has.Count.EqualTo(1));
- Assert.That(peer.GetTransceivers().Select(t => t.Sender).ToList(), Has.Member(sender));
- track.Dispose();
- peer.Dispose();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(1000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.OSXPlayer })]
- public IEnumerator CurrentDirection()
- {
- var config = GetDefaultConfiguration();
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- var audioTrack = new AudioStreamTrack(source);
- var transceiver1 = peer1.AddTransceiver(TrackKind.Audio);
- transceiver1.Direction = RTCRtpTransceiverDirection.RecvOnly;
- Assert.IsNull(transceiver1.CurrentDirection);
- var op1 = peer1.CreateOffer();
- yield return op1;
- var desc = op1.Desc;
- var op2 = peer1.SetLocalDescription(ref desc);
- yield return op2;
- var op3 = peer2.SetRemoteDescription(ref desc);
- yield return op3;
- var transceiver2 = peer2.GetTransceivers().First(x => x.Receiver.Track.Kind == TrackKind.Audio);
- Assert.True(transceiver2.Sender.ReplaceTrack(audioTrack));
- transceiver2.Direction = RTCRtpTransceiverDirection.SendOnly;
- var op4 = peer2.CreateAnswer();
- yield return op4;
- desc = op4.Desc;
- var op5 = peer2.SetLocalDescription(ref desc);
- yield return op5;
- var op6 = peer1.SetRemoteDescription(ref desc);
- yield return op6;
- Assert.AreEqual(transceiver1.CurrentDirection, RTCRtpTransceiverDirection.RecvOnly);
- Assert.AreEqual(transceiver2.CurrentDirection, RTCRtpTransceiverDirection.SendOnly);
- //Assert.That(transceiver2.Stop(), Is.EqualTo(RTCErrorType.None));
- //Assert.That(transceiver2.Direction, Is.EqualTo(RTCRtpTransceiverDirection.Stopped));
- // todo(kazuki):: Transceiver.CurrentDirection of Sender is not changed to "Stopped" even if waiting
- // yield return new WaitUntil(() => transceiver2.CurrentDirection == RTCRtpTransceiverDirection.Stopped);
- // Assert.That(transceiver2.CurrentDirection, Is.EqualTo(RTCRtpTransceiverDirection.Stopped));
- // todo(kazuki):: Transceiver.CurrentDirection of Receiver is not changed to "Stopped" even if waiting
- // yield return new WaitUntil(() => transceiver1.Direction == RTCRtpTransceiverDirection.Stopped);
- // Assert.That(transceiver1.Direction, Is.EqualTo(RTCRtpTransceiverDirection.Stopped));
- audioTrack.Dispose();
- peer1.Close();
- peer2.Close();
- peer1.Dispose();
- peer2.Dispose();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(5000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.IPhonePlayer })]
- public IEnumerator TransceiverReturnsSender()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
- peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
- var obj1 = new GameObject("audio1");
- var source1 = obj1.AddComponent<AudioSource>();
- source1.clip = AudioClip.Create("test1", 480, 2, 48000, false);
- AudioStreamTrack track1 = new AudioStreamTrack(source1);
- peer1.AddTrack(track1);
- yield return SignalingOffer(peer1, peer2);
- Assert.That(peer2.GetTransceivers().Count(), Is.EqualTo(1));
- RTCRtpSender sender1 = peer2.GetTransceivers().First().Sender;
- Assert.That(sender1, Is.Not.Null);
- var obj2 = new GameObject("audio2");
- var source2 = obj2.AddComponent<AudioSource>();
- source2.clip = AudioClip.Create("test2", 480, 2, 48000, false);
- AudioStreamTrack track2 = new AudioStreamTrack(source2);
- RTCRtpSender sender2 = peer2.AddTrack(track2);
- Assert.That(sender2, Is.Not.Null);
- Assert.That(sender1, Is.EqualTo(sender2));
- track1.Dispose();
- track2.Dispose();
- peer1.Dispose();
- peer2.Dispose();
- Object.DestroyImmediate(source1.clip);
- Object.DestroyImmediate(source2.clip);
- Object.DestroyImmediate(obj1);
- Object.DestroyImmediate(obj2);
- }
- [UnityTest]
- [Timeout(1000)]
- public IEnumerator CreateOffer()
- {
- var config = GetDefaultConfiguration();
- var peer = new RTCPeerConnection(ref config);
- var op = peer.CreateOffer();
- yield return op;
- Assert.True(op.IsDone);
- Assert.False(op.IsError);
- peer.Close();
- peer.Dispose();
- }
- [UnityTest]
- [Timeout(1000)]
- public IEnumerator CreateAnswerFailed()
- {
- var config = GetDefaultConfiguration();
- var peer = new RTCPeerConnection(ref config);
- var op = peer.CreateAnswer();
- yield return op;
- Assert.True(op.IsDone);
- // This is failed
- Assert.True(op.IsError);
- Assert.IsNotEmpty(op.Error.message);
- peer.Close();
- peer.Dispose();
- }
- [UnityTest]
- [Timeout(1000)]
- public IEnumerator CreateAnswer()
- {
- var config = GetDefaultConfiguration();
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- peer1.CreateDataChannel("data");
- var op1 = peer1.CreateOffer();
- yield return op1;
- var desc = op1.Desc;
- var op2 = peer1.SetLocalDescription(ref desc);
- yield return op2;
- var op3 = peer2.SetRemoteDescription(ref desc);
- yield return op3;
- var op4 = peer2.CreateAnswer();
- yield return op4;
- Assert.True(op4.IsDone);
- Assert.False(op4.IsError);
- peer1.Close();
- peer2.Close();
- peer1.Dispose();
- peer2.Dispose();
- }
- [UnityTest]
- [Timeout(1000)]
- public IEnumerator SetLocalDescription()
- {
- var peer = new RTCPeerConnection();
- var op = peer.CreateOffer();
- yield return op;
- Assert.True(op.IsDone);
- Assert.False(op.IsError);
- var desc = op.Desc;
- var op2 = peer.SetLocalDescription(ref desc);
- yield return op2;
- Assert.True(op2.IsDone);
- Assert.False(op2.IsError);
- var desc2 = peer.LocalDescription;
- Assert.AreEqual(desc.sdp, desc2.sdp);
- Assert.AreEqual(desc.type, desc2.type);
- peer.Close();
- peer.Dispose();
- }
- [Test]
- public void SetLocalDescriptionThrowException()
- {
- var peer = new RTCPeerConnection();
- RTCSessionDescription empty = new RTCSessionDescription();
- Assert.Throws<ArgumentException>(() => peer.SetLocalDescription(ref empty));
- RTCSessionDescription invalid = new RTCSessionDescription { sdp = "this is invalid parameter" };
- Assert.Throws<RTCErrorException>(() => peer.SetLocalDescription(ref invalid));
- peer.Dispose();
- }
- [UnityTest]
- [Timeout(1000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.OSXPlayer })]
- public IEnumerator SetRemoteDescription()
- {
- var config = GetDefaultConfiguration();
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- var channel1 = peer1.CreateDataChannel("data");
- var op1 = peer1.CreateOffer();
- yield return op1;
- var desc = op1.Desc;
- var op2 = peer1.SetLocalDescription(ref desc);
- yield return op2;
- var op3 = peer2.SetRemoteDescription(ref desc);
- yield return op3;
- var op4 = peer2.CreateAnswer();
- yield return op4;
- desc = op4.Desc;
- var op5 = peer2.SetLocalDescription(ref desc);
- yield return op5;
- var op6 = peer1.SetRemoteDescription(ref desc);
- yield return op6;
- var desc2 = peer1.RemoteDescription;
- Assert.AreEqual(desc.sdp, desc2.sdp);
- Assert.AreEqual(desc.type, desc2.type);
- channel1.Dispose();
- peer1.Close();
- peer2.Close();
- peer1.Dispose();
- peer2.Dispose();
- }
- [UnityTest]
- [Timeout(5000)]
- public IEnumerator SetDescriptionInParallel()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- var neededNegotiationPeer1 = false;
- var neededNegotiationPeer2 = false;
- peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
- peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
- peer1.OnNegotiationNeeded += () => neededNegotiationPeer1 = true;
- peer2.OnNegotiationNeeded += () => neededNegotiationPeer2 = true;
- peer1.AddTransceiver(TrackKind.Audio);
- yield return new WaitUntil(() => neededNegotiationPeer1);
- var op1 = peer1.SetLocalDescription();
- yield return op1;
- RTCSessionDescription desc = peer1.LocalDescription;
- Assert.That(desc.type, Is.EqualTo(RTCSdpType.Offer));
- Assert.That(peer1.SignalingState, Is.EqualTo(RTCSignalingState.HaveLocalOffer));
- peer2.AddTransceiver(TrackKind.Audio);
- yield return new WaitUntil(() => neededNegotiationPeer2);
- var op2 = peer2.SetLocalDescription();
- var op3 = peer2.SetRemoteDescription(ref desc);
- yield return op2;
- yield return op3;
- Assert.That(peer2.RemoteDescription.type, Is.EqualTo(RTCSdpType.Offer));
- Assert.That(peer2.SignalingState, Is.EqualTo(RTCSignalingState.HaveRemoteOffer));
- var op4 = peer2.SetLocalDescription();
- yield return op4;
- desc = peer2.LocalDescription;
- Assert.That(desc.type, Is.EqualTo(RTCSdpType.Answer));
- Assert.That(peer2.SignalingState, Is.EqualTo(RTCSignalingState.Stable));
- var op5 = peer1.SetRemoteDescription(ref desc);
- yield return op5;
- peer1.Close();
- peer2.Close();
- }
- [UnityTest]
- [Timeout(5000)]
- public IEnumerator CreateDescriptionInParallel()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- var neededNegotiationPeer1 = false;
- var neededNegotiationPeer2 = false;
- peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
- peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
- peer1.OnNegotiationNeeded += () => neededNegotiationPeer1 = true;
- peer2.OnNegotiationNeeded += () => neededNegotiationPeer2 = true;
- peer1.AddTransceiver(TrackKind.Audio);
- yield return new WaitUntil(() => neededNegotiationPeer1);
- var op1 = peer1.SetLocalDescription();
- yield return op1;
- RTCSessionDescription desc = peer1.LocalDescription;
- Assert.That(desc.type, Is.EqualTo(RTCSdpType.Offer));
- Assert.That(peer1.SignalingState, Is.EqualTo(RTCSignalingState.HaveLocalOffer));
- peer2.AddTransceiver(TrackKind.Audio);
- yield return new WaitUntil(() => neededNegotiationPeer2);
- var op2 = peer2.SetRemoteDescription(ref desc);
- yield return op2;
- Assert.That(peer2.RemoteDescription.type, Is.EqualTo(RTCSdpType.Offer));
- Assert.That(peer2.SignalingState, Is.EqualTo(RTCSignalingState.HaveRemoteOffer));
- var op3 = peer2.CreateOffer();
- var op4 = peer2.CreateAnswer();
- yield return op3;
- yield return op4;
- desc = op4.Desc;
- var op5 = peer2.SetLocalDescription(ref desc);
- yield return op5;
- Assert.That(desc.type, Is.EqualTo(RTCSdpType.Answer));
- Assert.That(peer2.SignalingState, Is.EqualTo(RTCSignalingState.Stable));
- var op6 = peer1.SetRemoteDescription(ref desc);
- yield return op6;
- peer1.Close();
- peer2.Close();
- }
- [Test]
- public void SetRemoteDescriptionThrowException()
- {
- var peer = new RTCPeerConnection();
- RTCSessionDescription empty = new RTCSessionDescription();
- Assert.Throws<ArgumentException>(() => peer.SetRemoteDescription(ref empty));
- RTCSessionDescription invalid = new RTCSessionDescription { sdp = "this is invalid parameter" };
- Assert.Throws<RTCErrorException>(() => peer.SetRemoteDescription(ref invalid));
- peer.Dispose();
- }
- [UnityTest]
- [Timeout(1000)]
- public IEnumerator SetLocalDescriptionFailed()
- {
- var peer = new RTCPeerConnection();
- var stream = new MediaStream();
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- var track = new AudioStreamTrack(source);
- var sender = peer.AddTrack(track, stream);
- var op = peer.CreateOffer();
- yield return op;
- Assert.True(op.IsDone);
- Assert.False(op.IsError);
- var desc = op.Desc;
- // change sdp to cannot parse
- desc.sdp = desc.sdp.Replace("a=mid:0", "a=mid:10");
- var op2 = peer.SetLocalDescription(ref desc);
- yield return op2;
- Assert.True(op2.IsDone);
- Assert.True(op2.IsError);
- Assert.IsNotEmpty(op2.Error.message);
- Assert.That(peer.RemoveTrack(sender), Is.EqualTo(RTCErrorType.None));
- track.Dispose();
- stream.Dispose();
- peer.Close();
- peer.Dispose();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(1000)]
- public IEnumerator SetRemoteDescriptionFailed()
- {
- var config = GetDefaultConfiguration();
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- var stream = new MediaStream();
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- var track = new AudioStreamTrack(source);
- var sender = peer1.AddTrack(track, stream);
- var op1 = peer1.CreateOffer();
- yield return op1;
- var desc = op1.Desc;
- var op2 = peer1.SetLocalDescription(ref desc);
- yield return op2;
- // change sdp to cannot parse
- desc.sdp = desc.sdp.Replace("a=mid:0", "a=mid:10");
- var op3 = peer2.SetRemoteDescription(ref desc);
- yield return op3;
- Assert.True(op3.IsDone);
- Assert.True(op3.IsError);
- Assert.IsNotEmpty(op3.Error.message);
- peer1.RemoveTrack(sender);
- track.Dispose();
- stream.Dispose();
- peer1.Close();
- peer2.Close();
- peer1.Dispose();
- peer2.Dispose();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(5000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.IPhonePlayer })]
- public IEnumerator IceConnectionStateChange()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
- peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- var track = new AudioStreamTrack(source);
- peer1.AddTrack(track);
- var op1 = peer1.CreateOffer();
- yield return op1;
- var desc = op1.Desc;
- var op2 = peer1.SetLocalDescription(ref desc);
- yield return op2;
- var op3 = peer2.SetRemoteDescription(ref desc);
- yield return op3;
- var op4 = peer2.CreateAnswer();
- yield return op4;
- desc = op4.Desc;
- var op5 = peer2.SetLocalDescription(ref desc);
- yield return op5;
- var op6 = peer1.SetRemoteDescription(ref desc);
- yield return op6;
- var op7 = new WaitUntilWithTimeout(
- () => peer1.IceConnectionState == RTCIceConnectionState.Connected ||
- peer1.IceConnectionState == RTCIceConnectionState.Completed, 5000);
- yield return op7;
- Assert.True(op7.IsCompleted);
- var op8 = new WaitUntilWithTimeout(
- () => peer2.IceConnectionState == RTCIceConnectionState.Connected ||
- peer2.IceConnectionState == RTCIceConnectionState.Completed, 5000);
- yield return op8;
- Assert.True(op8.IsCompleted);
- track.Dispose();
- peer1.Close();
- peer2.Close();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(5000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.IPhonePlayer })]
- public IEnumerator AddIceCandidate()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- var peer1ReceiveCandidateQueue = new Queue<RTCIceCandidate>();
- var peer2ReceiveCandidateQueue = new Queue<RTCIceCandidate>();
- peer1.OnIceCandidate = candidate => { peer2ReceiveCandidateQueue.Enqueue(candidate); };
- peer2.OnIceCandidate = candidate => { peer1ReceiveCandidateQueue.Enqueue(candidate); };
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- var track = new AudioStreamTrack(source);
- peer1.AddTrack(track);
- var op1 = peer1.CreateOffer();
- yield return op1;
- var desc = op1.Desc;
- var op2 = peer1.SetLocalDescription(ref desc);
- yield return op2;
- yield return new WaitUntil(() => peer2ReceiveCandidateQueue.Any());
- Assert.That(peer2.AddIceCandidate(peer2ReceiveCandidateQueue.Peek()), Is.False);
- var op3 = peer2.SetRemoteDescription(ref desc);
- yield return op3;
- Assert.That(peer2.AddIceCandidate(peer2ReceiveCandidateQueue.Dequeue()), Is.True);
- var op4 = peer2.CreateAnswer();
- yield return op4;
- desc = op4.Desc;
- var op5 = peer2.SetLocalDescription(ref desc);
- yield return op5;
- yield return new WaitUntil(() => peer1ReceiveCandidateQueue.Any());
- Assert.That(peer1.AddIceCandidate(peer1ReceiveCandidateQueue.Peek()), Is.False);
- var op6 = peer1.SetRemoteDescription(ref desc);
- yield return op6;
- Assert.That(peer1.AddIceCandidate(peer1ReceiveCandidateQueue.Dequeue()), Is.True);
- var op7 = new WaitUntilWithTimeout(
- () => peer1.IceConnectionState == RTCIceConnectionState.Connected ||
- peer1.IceConnectionState == RTCIceConnectionState.Completed, 5000);
- yield return op7;
- Assert.That(op7.IsCompleted, Is.True);
- var op8 = new WaitUntilWithTimeout(
- () => peer2.IceConnectionState == RTCIceConnectionState.Connected ||
- peer2.IceConnectionState == RTCIceConnectionState.Completed, 5000);
- yield return op8;
- Assert.That(op8.IsCompleted, Is.True);
- foreach (var candidate in peer1ReceiveCandidateQueue)
- {
- Assert.That(peer1.AddIceCandidate(candidate), Is.True);
- }
- peer1ReceiveCandidateQueue.Clear();
- foreach (var candidate in peer2ReceiveCandidateQueue)
- {
- Assert.That(peer2.AddIceCandidate(candidate), Is.True);
- }
- peer2ReceiveCandidateQueue.Clear();
- track.Dispose();
- peer1.Close();
- peer2.Close();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(5000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.IPhonePlayer })]
- public IEnumerator MediaStreamTrackThrowExceptionAfterPeerDisposed()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
- peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- AudioStreamTrack track = new AudioStreamTrack(source);
- peer1.AddTrack(track);
- MediaStreamTrack track1 = null;
- peer2.OnTrack = e => { track1 = e.Track; };
- yield return SignalingOffer(peer1, peer2);
- Assert.That(track1, Is.Not.Null);
- peer2.Dispose();
- Assert.That(() => track1.Id, Throws.TypeOf<ObjectDisposedException>());
- track.Dispose();
- track1.Dispose();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(5000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.IPhonePlayer })]
- public IEnumerator PeerConnectionStateChange()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- RTCPeerConnectionState state1 = default;
- RTCPeerConnectionState state2 = default;
- RTCIceConnectionState iceState1 = default;
- RTCIceConnectionState iceState2 = default;
- peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
- peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
- peer1.OnConnectionStateChange = state => { state1 = state; };
- peer2.OnConnectionStateChange = state => { state2 = state; };
- peer1.OnIceConnectionChange = state => { iceState1 = state; };
- peer2.OnIceConnectionChange = state => { iceState2 = state; };
- Assert.That(state1, Is.EqualTo(RTCPeerConnectionState.New));
- Assert.That(state2, Is.EqualTo(RTCPeerConnectionState.New));
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- AudioStreamTrack track1 = new AudioStreamTrack(source);
- peer1.AddTrack(track1);
- var op1 = peer1.CreateOffer();
- yield return op1;
- var desc = op1.Desc;
- var op2 = peer1.SetLocalDescription(ref desc);
- yield return op2;
- var op3 = peer2.SetRemoteDescription(ref desc);
- yield return op3;
- var op4 = peer2.CreateAnswer();
- yield return op4;
- desc = op4.Desc;
- var op5 = peer2.SetLocalDescription(ref desc);
- yield return op5;
- var op6 = peer1.SetRemoteDescription(ref desc);
- yield return op6;
- var op7 = new WaitUntilWithTimeout(() =>
- state1 == RTCPeerConnectionState.Connected &&
- state2 == RTCPeerConnectionState.Connected, 5000);
- yield return op7;
- Assert.That(op7.IsCompleted, Is.True);
- var op8 = new WaitUntilWithTimeout(() =>
- (iceState1 == RTCIceConnectionState.Connected || iceState1 == RTCIceConnectionState.Completed) &&
- (iceState2 == RTCIceConnectionState.Connected || iceState2 == RTCIceConnectionState.Completed)
- , 5000);
- yield return op8;
- Assert.That(op8.IsCompleted, Is.True);
- peer1.Close();
- var op9 = new WaitUntilWithTimeout(() =>
- state1 == RTCPeerConnectionState.Closed &&
- iceState2 == RTCIceConnectionState.Disconnected, 5000);
- yield return op9;
- Assert.That(op9.IsCompleted, Is.True);
- track1.Dispose();
- peer2.Close();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(5000)]
- [ConditionalIgnore(ConditionalIgnore.UnsupportedPlatformOpenGL, "Not support VideoStreamTrack for OpenGL")]
- public IEnumerator GetStatsReturnsReport()
- {
- if (SystemInfo.processorType == "Apple M1")
- Assert.Ignore("todo:: This test will hang up on Apple M1");
- var stream = new MediaStream();
- var go = new GameObject("Test");
- var cam = go.AddComponent<Camera>();
- stream.AddTrack(cam.CaptureStreamTrack(1280, 720));
- var source = go.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- stream.AddTrack(new AudioStreamTrack(source));
- var test = new MonoBehaviourTest<SignalingPeers>();
- test.component.AddStream(0, stream);
- yield return test;
- test.component.CoroutineUpdate();
- var op1 = test.component.GetSenderStats(0, 0);
- var op2 = test.component.GetReceiverStats(0, 0);
- var op3 = test.component.GetSenderStats(1, 0);
- var op4 = test.component.GetReceiverStats(1, 0);
- var ops = new[] { op1, op2, op3, op4 };
- foreach (var op in ops)
- {
- yield return op;
- Assert.That(op.IsDone, Is.True);
- Assert.That(op.Value, Is.Not.Null);
- Assert.That(op.Value.Stats, Is.Not.Null);
- }
- op1.Value.Dispose();
- op2.Value.Dispose();
- op3.Value.Dispose();
- op4.Value.Dispose();
- test.component.Dispose();
- foreach (var track in stream.GetTracks())
- {
- track.Dispose();
- }
- stream.Dispose();
- Object.DestroyImmediate(go);
- Object.DestroyImmediate(test.gameObject);
- }
- [UnityTest]
- [Timeout(5000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.IPhonePlayer })]
- public IEnumerator RestartIceInvokeOnNegotiationNeeded()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
- peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- AudioStreamTrack track = new AudioStreamTrack(source);
- peer1.AddTrack(track);
- yield return SignalingOffer(peer1, peer2);
- bool isInvokeOnNegotiationNeeded1 = false;
- bool isInvokeOnNegotiationNeeded2 = false;
- peer1.OnNegotiationNeeded = () => isInvokeOnNegotiationNeeded1 = true;
- peer2.OnNegotiationNeeded = () => isInvokeOnNegotiationNeeded2 = true;
- peer1.RestartIce();
- var op9 = new WaitUntilWithTimeout(() => isInvokeOnNegotiationNeeded1, 5000);
- yield return op9;
- Assert.That(op9.IsCompleted, Is.True);
- peer2.RestartIce();
- var op10 = new WaitUntilWithTimeout(() => isInvokeOnNegotiationNeeded2, 5000);
- yield return op10;
- Assert.That(op10.IsCompleted, Is.True);
- track.Dispose();
- peer1.Close();
- peer2.Close();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- [UnityTest]
- [Timeout(5000)]
- [UnityPlatform(exclude = new[] { RuntimePlatform.IPhonePlayer })]
- public IEnumerator RemoteOnRemoveTrack()
- {
- RTCConfiguration config = default;
- config.iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } };
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- peer1.OnIceCandidate = candidate => { peer2.AddIceCandidate(candidate); };
- peer2.OnIceCandidate = candidate => { peer1.AddIceCandidate(candidate); };
- var stream = new MediaStream();
- MediaStream receiveStream = null;
- var obj = new GameObject("audio");
- var source = obj.AddComponent<AudioSource>();
- source.clip = AudioClip.Create("test", 480, 2, 48000, false);
- var track = new AudioStreamTrack(source);
- stream.AddTrack(track);
- RTCRtpSender sender = peer1.AddTrack(track, stream);
- bool isInvokeNegotiationNeeded1 = false;
- peer1.OnNegotiationNeeded = () => isInvokeNegotiationNeeded1 = true;
- bool isInvokeOnRemoveTrack = false;
- peer2.OnTrack = e =>
- {
- Assert.That(e.Streams, Has.Count.EqualTo(1));
- receiveStream = e.Streams.First();
- receiveStream.OnRemoveTrack = ev => isInvokeOnRemoveTrack = true;
- };
- yield return SignalingOffer(peer1, peer2);
- peer1.RemoveTrack(sender);
- var op9 = new WaitUntilWithTimeout(() => isInvokeNegotiationNeeded1, 5000);
- yield return op9;
- Assert.That(op9.IsCompleted, Is.True);
- yield return SignalingOffer(peer1, peer2);
- var op10 = new WaitUntilWithTimeout(() => isInvokeOnRemoveTrack, 5000);
- yield return op10;
- Assert.That(op10.IsCompleted, Is.True);
- stream.Dispose();
- receiveStream.Dispose();
- track.Dispose();
- peer1.Dispose();
- peer2.Dispose();
- Object.DestroyImmediate(source.clip);
- Object.DestroyImmediate(obj);
- }
- private IEnumerator SignalingOffer(RTCPeerConnection @from, RTCPeerConnection to)
- {
- var op1 = @from.CreateOffer();
- yield return op1;
- var desc = op1.Desc;
- var op2 = @from.SetLocalDescription(ref desc);
- yield return op2;
- var op3 = to.SetRemoteDescription(ref desc);
- yield return op3;
- var op4 = to.CreateAnswer();
- yield return op4;
- desc = op4.Desc;
- var op5 = to.SetLocalDescription(ref desc);
- yield return op5;
- var op6 = @from.SetRemoteDescription(ref desc);
- yield return op6;
- var op7 = new WaitUntilWithTimeout(
- () => @from.IceConnectionState == RTCIceConnectionState.Connected ||
- @from.IceConnectionState == RTCIceConnectionState.Completed, 5000);
- yield return op7;
- Assert.That(op7.IsCompleted, Is.True);
- var op8 = new WaitUntilWithTimeout(
- () => to.IceConnectionState == RTCIceConnectionState.Connected ||
- to.IceConnectionState == RTCIceConnectionState.Completed, 5000);
- yield return op8;
- Assert.That(op8.IsCompleted, Is.True);
- }
- }
- }
|