private void OnDestroy() { peer?.Dispose(); peer = null; WebRTC.Dispose(); }
public void Clear() { SendVideoTrack?.Dispose(); SendVideoTrack = null; offerPc?.Close(); offerPc?.Dispose(); offerPc = null; answerPc?.Close(); answerPc?.Dispose(); answerPc = null; SendTexture = null; RecvTexture = null; }
private void HangUp() { RemoveTracks(); _pc1.Close(); _pc2.Close(); _pc1.Dispose(); _pc2.Dispose(); _pc1 = null; _pc2 = null; callButton.interactable = true; restartButton.interactable = false; hangUpButton.interactable = false; receiveImage.color = Color.black; }
public IEnumerator CreateAnswerFailed() { var config = GetConfiguration(); var peer = new RTCPeerConnection(ref config); RTCAnswerOptions options = default; var op = peer.CreateAnswer(ref options); yield return(op); Assert.True(op.IsDone); // This is failed Assert.True(op.IsError); peer.Close(); peer.Dispose(); }
public IEnumerator SetRemoteDescription() { var config = GetDefaultConfiguration(); var peer1 = new RTCPeerConnection(ref config); var peer2 = new RTCPeerConnection(ref config); var channel1 = peer1.CreateDataChannel("data"); RTCOfferOptions options1 = default; RTCAnswerOptions options2 = default; var op1 = peer1.CreateOffer(ref options1); 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(ref options2); 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(); }
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(); }
public void AddTransceiver() { 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); 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); }
public void Close() { try { signaling?.Close(); signaling = null; } catch (Exception ex) { OnErrorEvent.Invoke("signaling.close", ex.Message); } try { if (dataChannel != null) { dataChannel.OnOpen = null; dataChannel.OnMessage = null; dataChannel.OnClose = null; dataChannel.Close(); dataChannel = null; } } catch (Exception ex) { OnErrorEvent.Invoke("dataChannel dispose", ex.Message); } try { peer.OnConnectionStateChange = null; peer.OnDataChannel = null; peer.OnIceCandidate = null; peer.OnIceGatheringStateChange = null; peer.OnNegotiationNeeded = null; peer.OnTrack = null; peer.Close(); peer.Dispose(); peer = null; } catch (Exception ex) { OnErrorEvent.Invoke("peer dispose", ex.Message); } }
public IEnumerator PeerConnection_SetRemoteDescription() { 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); RTCDataChannel channel1 = null; var conf = new RTCDataChannelInit(true); channel1 = peer1.CreateDataChannel("data", ref conf); RTCOfferOptions options1 = default; RTCAnswerOptions options2 = default; var op1 = peer1.CreateOffer(ref options1); yield return(op1); var op2 = peer1.SetLocalDescription(ref op1.desc); yield return(op2); var op3 = peer2.SetRemoteDescription(ref op1.desc); yield return(op3); var op4 = peer2.CreateAnswer(ref options2); yield return(op4); var op5 = peer2.SetLocalDescription(ref op4.desc); yield return(op5); var op6 = peer1.SetRemoteDescription(ref op4.desc); yield return(op6); channel1.Dispose(); peer1.Dispose(); peer2.Dispose(); }
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(); }
private void HangUp() { RemoveTracks(); _pc1.Close(); _pc2.Close(); _pc1.Dispose(); _pc2.Dispose(); _pc1 = null; _pc2 = null; callButton.interactable = true; hangUpButton.interactable = false; codecSelector.interactable = true; codecSelector.value = 0; actualCodecText.text = string.Empty; sourceImage.color = Color.black; receiveImage.color = Color.black; }
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); }
private void HangUp() { RemoveTracks(); _pc1.Close(); _pc2.Close(); Debug.Log("Close local/remote peer connection"); _pc1.Dispose(); _pc2.Dispose(); _pc1 = null; _pc2 = null; callButton.interactable = true; hangUpButton.interactable = false; bandwidthSelector.interactable = false; bandwidthSelector.value = 0; sourceImage.color = Color.black; receiveImage.color = Color.black; }
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); }
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(); }
private void HangUp() { foreach (var image in receiveImages.Concat(sourceImages)) { image.texture = null; DestroyImmediate(image.gameObject); } receiveImages.Clear(); sourceImages.Clear(); foreach (var cam in cameras) { DestroyImmediate(cam.gameObject); } cameras.Clear(); foreach (var track in videoStreamTrackList) { track.Dispose(); } videoStreamTrackList.Clear(); sendingSenderList.Clear(); _pc1.Close(); _pc2.Close(); Debug.Log("Close local/remote peer connection"); _pc1.Dispose(); _pc2.Dispose(); _pc1 = null; _pc2 = null; videoIndex = 0; objectIndex = 0; widthInput.interactable = true; heightInput.interactable = true; callButton.interactable = true; hangUpButton.interactable = false; addVideoObjectButton.interactable = false; addTracksButton.interactable = false; }
public void GetConfiguration() { var config = GetDefaultConfiguration(); var peer = new RTCPeerConnection(ref config); var config2 = peer.GetConfiguration(); Assert.NotNull(config.iceServers); Assert.NotNull(config2.iceServers); Assert.AreEqual(config.iceServers.Length, config2.iceServers.Length); Assert.AreEqual(config.iceServers[0].username, config2.iceServers[0].username); Assert.AreEqual(config.iceServers[0].credential, config2.iceServers[0].credential); Assert.AreEqual(config.iceServers[0].urls, config2.iceServers[0].urls); Assert.AreEqual(config.iceTransportPolicy, config2.iceTransportPolicy); Assert.AreEqual(config.iceCandidatePoolSize, config2.iceCandidatePoolSize); Assert.AreEqual(config.bundlePolicy, config2.bundlePolicy); peer.Close(); peer.Dispose(); }
private void HangUp() { videoStream.Dispose(); receiveStream.Dispose(); videoStream = null; receiveStream = null; _pc1.Close(); _pc2.Close(); Debug.Log("Close local/remote peer connection"); _pc1.Dispose(); _pc2.Dispose(); _pc1 = null; _pc2 = null; receiveImage.texture = null; callButton.interactable = true; hangUpButton.interactable = false; addTracksButton.interactable = false; removeTracksButton.interactable = false; }
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(); }
public IEnumerator InitializeReceiver() { var peer = new RTCPeerConnection(); var transceiver = peer.AddTransceiver(TrackKind.Video); Assert.NotNull(transceiver); RTCRtpReceiver receiver = transceiver.Receiver; Assert.NotNull(receiver); MediaStreamTrack track = receiver.Track; Assert.NotNull(track); Assert.AreEqual(TrackKind.Video, track.Kind); var videoTrack = track as VideoStreamTrack; Assert.NotNull(videoTrack); var rt = videoTrack.InitializeReceiver(640, 320); Assert.True(videoTrack.IsDecoderInitialized); videoTrack.Dispose(); // wait for disposing video track. yield return 0; peer.Dispose(); Object.DestroyImmediate(rt); }
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(); }
private void HangUp() { if (webCamTexture != null) { webCamTexture.Stop(); webCamTexture = null; } receiveAudioStream?.Dispose(); receiveAudioStream = null; receiveVideoStream?.Dispose(); receiveVideoStream = null; videoStreamTrack?.Dispose(); videoStreamTrack = null; audioStreamTrack?.Dispose(); audioStreamTrack = null; Debug.Log("Close local/remote peer connection"); _pc1?.Dispose(); _pc2?.Dispose(); _pc1 = null; _pc2 = null; sourceImage.texture = null; sourceAudio.Stop(); sourceAudio.clip = null; receiveImage.texture = null; receiveAudio.Stop(); receiveAudio.clip = null; useWebCamToggle.interactable = true; webCamListDropdown.interactable = useWebCamToggle.isOn; useMicToggle.interactable = true; micListDropdown.interactable = useMicToggle.isOn; callButton.interactable = true; hangUpButton.interactable = false; addTracksButton.interactable = false; removeTracksButton.interactable = false; }
public IEnumerator SetRemoteDescriptionFailed() { var config = GetConfiguration(); var peer1 = new RTCPeerConnection(ref config); var peer2 = new RTCPeerConnection(ref config); var stream = new MediaStream(); var track = new AudioStreamTrack("audio"); var sender = peer1.AddTrack(track, stream); RTCOfferOptions options1 = default; var op1 = peer1.CreateOffer(ref options1); 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("m=audio", "m=audiable"); 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(); }
public void ReceiverGetTrackReturnsAudioTrack() { var peer = new RTCPeerConnection(); var transceiver = peer.AddTransceiver(TrackKind.Audio); Assert.That(transceiver, Is.Not.Null); Assert.That(transceiver.CurrentDirection, Is.Null); // The receiver has a audio track RTCRtpReceiver receiver = transceiver.Receiver; Assert.That(receiver, Is.Not.Null); Assert.That(receiver.Track, Is.Not.Null); Assert.That(receiver.Track, Is.TypeOf <AudioStreamTrack>()); // The receiver has no track RTCRtpSender sender = transceiver.Sender; Assert.That(sender, Is.Not.Null); Assert.That(sender.Track, Is.Null); peer.Dispose(); }
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(); }
public IEnumerator CreateAnswer() { var config = GetConfiguration(); var peer1 = new RTCPeerConnection(ref config); var peer2 = new RTCPeerConnection(ref config); var conf = new RTCDataChannelInit(true); peer1.CreateDataChannel("data", ref conf); RTCOfferOptions options1 = default; RTCAnswerOptions options2 = default; var op1 = peer1.CreateOffer(ref options1); 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(ref options2); yield return(op4); Assert.True(op4.IsDone); Assert.False(op4.IsError); peer1.Close(); peer2.Close(); peer1.Dispose(); peer2.Dispose(); }
public void AddTransceiver() { var peer = new RTCPeerConnection(); var stream = Audio.CaptureStream(); var track = stream.GetAudioTracks().First(); Assert.AreEqual(0, peer.GetTransceivers().Count()); var transceiver = peer.AddTransceiver(track); Assert.NotNull(transceiver); Assert.IsNull(transceiver.CurrentDirection); RTCRtpSender sender = transceiver.Sender; Assert.NotNull(sender); Assert.AreEqual(track, sender.Track); RTCRtpSendParameters parameters = sender.GetParameters(); Assert.NotNull(parameters); Assert.NotNull(parameters.Encodings); foreach (var encoding in parameters.Encodings) { Assert.True(encoding.active); Assert.Null(encoding.maxBitrate); Assert.Null(encoding.minBitrate); Assert.Null(encoding.maxFramerate); Assert.Null(encoding.scaleResolutionDownBy); Assert.IsNotEmpty(encoding.rid); } Assert.IsNotEmpty(parameters.TransactionId); Assert.AreEqual(1, peer.GetTransceivers().Count()); Assert.NotNull(peer.GetTransceivers().First()); track.Dispose(); stream.Dispose(); peer.Dispose(); }
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); }
void Dispose() { dataChannel.Dispose(); pc1.Dispose(); pc2.Dispose(); }
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); }