123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- using System;
- using System.Linq;
- using System.Collections;
- using System.Collections.Generic;
- using NUnit.Framework;
- using Unity.Collections;
- using UnityEngine;
- using Unity.WebRTC;
- using UnityEngine.TestTools;
- using UnityEngine.InputSystem;
- using UnityEngine.InputSystem.Users;
- namespace Unity.RenderStreaming.RuntimeTest
- {
- class VideoStreamSenderTest
- {
- [Test]
- public void GetAvailableCodec()
- {
- IEnumerable<VideoCodecInfo> codecs = VideoStreamSender.GetAvailableCodecs();
- Assert.That(codecs, Is.Not.Empty);
- Assert.That(codecs.Any(codec => codec.name == "VP8"));
- Assert.That(codecs.Any(codec => codec.name == "VP9"));
- Assert.That(codecs.Any(codec => codec.name == "AV1"));
- foreach(var codec in codecs)
- {
- Assert.That(codec.name, Is.Not.Empty);
- Assert.That(codec.mimeType, Is.Not.Empty);
- Assert.That(codec.codecImplementation, Is.Not.Empty);
- switch (codec)
- {
- case VP9CodecInfo vp9codec:
- Assert.That(vp9codec.name, Is.EqualTo("VP9"));
- Assert.That(vp9codec.profile, Is.Not.Zero);
- break;
- case H264CodecInfo h264codec:
- Assert.That(h264codec.name, Is.EqualTo("H264"));
- Assert.That(h264codec.level, Is.GreaterThan(0));
- Assert.That(h264codec.profile, Is.Not.Zero);
- break;
- default:
- break;
- }
- }
- }
- [Test]
- public void SelectCodecCapabilities()
- {
- var codecs = VideoStreamSender.GetAvailableCodecs();
- var caps = RTCRtpSender.GetCapabilities(TrackKind.Video).SelectCodecCapabilities(codecs);
- Assert.That(codecs.Count(), Is.EqualTo(caps.Count()));
- }
- [Test]
- public void SetEnabled()
- {
- var go = new GameObject();
- var sender = go.AddComponent<VideoStreamSender>();
- sender.enabled = false;
- sender.enabled = true;
- UnityEngine.Object.DestroyImmediate(go);
- }
- [UnityTest]
- public IEnumerator CreateTrack()
- {
- var go = new GameObject();
- var sender = go.AddComponent<VideoStreamSender>();
- MediaStreamTrack track = null;
- // With camera
- sender.source = VideoStreamSource.Camera;
- Assert.That(() => sender.CreateTrack(), Throws.Exception.TypeOf<ArgumentNullException>());
- var camera = go.AddComponent<Camera>();
- sender.sourceCamera = camera;
- sender.width = 640;
- sender.height = 480;
- var op = sender.CreateTrack();
- yield return op;
- track = op.Track;
- Assert.That(track, Is.Not.Null);
- var videoTrack = track as VideoStreamTrack;
- Assert.That(videoTrack.Texture.width, Is.EqualTo(sender.width));
- Assert.That(videoTrack.Texture.height, Is.EqualTo(sender.height));
- track.Dispose();
- track = null;
- // With screen
- sender.source = VideoStreamSource.Screen;
- op = sender.CreateTrack();
- yield return op;
- track = op.Track;
- Assert.That(track, Is.Not.Null);
- track.Dispose();
- track = null;
- // With Texture
- sender.source = VideoStreamSource.Texture;
- Assert.That(sender.sourceTexture, Is.Null);
- Assert.That(() => sender.CreateTrack(), Throws.Exception.TypeOf<ArgumentNullException>());
- var width = 640;
- var height = 480;
- var format = WebRTC.WebRTC.GetSupportedRenderTextureFormat(SystemInfo.graphicsDeviceType);
- var texture = new RenderTexture(width, height, 0, format);
- sender.sourceTexture = texture;
- Assert.That(sender.sourceTexture, Is.Not.Null);
- Assert.That(sender.width, Is.EqualTo(width));
- Assert.That(sender.height, Is.EqualTo(height));
- Assert.That(() => sender.width = 1280, Throws.Nothing);
- Assert.That(() => sender.height = 720, Throws.Nothing);
- op = sender.CreateTrack();
- yield return op;
- track = op.Track;
- Assert.That(track, Is.Not.Null);
- track.Dispose();
- // With WebCam
- /// todo:: standalone build is failed by IL2CPP error in Unity 2021.3.
- #if !(UNITY_IPHONE || UNITY_ANDROID || (UNITY_2021_3 && ENABLE_IL2CPP))
- if (WebCamTexture.devices.Length > 0 && Application.HasUserAuthorization(UserAuthorization.WebCam))
- {
- sender.source = VideoStreamSource.WebCamera;
- Assert.That(sender.sourceDeviceIndex, Is.EqualTo(0));
- sender.sourceDeviceIndex = -1;
- Assert.That(() => sender.CreateTrack(), Throws.Exception.TypeOf<ArgumentOutOfRangeException>());
- sender.sourceDeviceIndex = 0;
- op = sender.CreateTrack();
- yield return op;
- track = op.Track;
- Assert.That(track, Is.Not.Null);
- Assert.That(sender.sourceWebCamTexture, Is.Not.Null);
- track.Dispose();
- }
- #endif
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void IsPlaying()
- {
- var go = new GameObject();
- var sender = go.AddComponent<VideoStreamSender>();
- Assert.That(sender.isPlaying, Is.False);
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void SetBitrate()
- {
- var go = new GameObject();
- var sender = go.AddComponent<VideoStreamSender>();
- uint minBitrate = 1000;
- uint maxBitrate = 2000;
- sender.SetBitrate(minBitrate, maxBitrate);
- Assert.That(sender.minBitrate, Is.EqualTo(minBitrate));
- Assert.That(sender.maxBitrate, Is.EqualTo(maxBitrate));
- minBitrate = 3000;
- Assert.That(() => sender.SetBitrate(minBitrate, maxBitrate), Throws.Exception.TypeOf<ArgumentException>());
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void SetFrameRate()
- {
- var go = new GameObject();
- var sender = go.AddComponent<VideoStreamSender>();
- float framerate = 24;
- sender.SetFrameRate(framerate);
- Assert.That(sender.frameRate, Is.EqualTo(framerate));
- framerate = 0;
- sender.SetFrameRate(framerate);
- Assert.That(sender.frameRate, Is.EqualTo(framerate));
- framerate = -1;
- Assert.That(() => sender.SetFrameRate(framerate), Throws.Exception.TypeOf<ArgumentOutOfRangeException>());
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void SetScaleResolutionDown()
- {
- var go = new GameObject();
- var sender = go.AddComponent<VideoStreamSender>();
- float scaleFactor = 2;
- sender.SetScaleResolutionDown(scaleFactor);
- Assert.That(sender.scaleResolutionDown, Is.EqualTo(scaleFactor));
- scaleFactor = 1;
- sender.SetScaleResolutionDown(scaleFactor);
- Assert.That(sender.scaleResolutionDown, Is.EqualTo(scaleFactor));
- scaleFactor = -1;
- Assert.That(() => sender.SetScaleResolutionDown(scaleFactor), Throws.Exception.TypeOf<ArgumentOutOfRangeException>());
- scaleFactor = 0.5f;
- Assert.That(() => sender.SetScaleResolutionDown(scaleFactor), Throws.Exception.TypeOf<ArgumentOutOfRangeException>());
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void SetCodec()
- {
- var go = new GameObject();
- var sender = go.AddComponent<VideoStreamSender>();
- Assert.That(sender.codec, Is.Null);
- var codecs = VideoStreamSender.GetAvailableCodecs();
- Assert.That(codecs, Is.Not.Empty);
- var codec = codecs.First();
- sender.SetCodec(codec);
- Assert.That(sender.codec, Is.EqualTo(codec));
- sender.SetCodec(null);
- Assert.That(sender.codec, Is.Null);
- }
- }
- class VideoStreamReceiverTest
- {
- [Test]
- public void GetAvailableCodec()
- {
- IEnumerable<VideoCodecInfo> codecs = VideoStreamReceiver.GetAvailableCodecs();
- Assert.That(codecs, Is.Not.Empty);
- Assert.That(codecs.Any(codec => codec.name == "VP8"));
- Assert.That(codecs.Any(codec => codec.name == "VP9"));
- Assert.That(codecs.Any(codec => codec.name == "AV1"));
- foreach (var codec in codecs)
- {
- Assert.That(codec.name, Is.Not.Empty);
- Assert.That(codec.mimeType, Is.Not.Empty);
- Assert.That(codec.codecImplementation, Is.Not.Empty);
- switch (codec)
- {
- case VP9CodecInfo vp9codec:
- Assert.That(vp9codec.name, Is.EqualTo("VP9"));
- Assert.That(vp9codec.profile, Is.Not.Zero);
- break;
- case H264CodecInfo h264codec:
- Assert.That(h264codec.name, Is.EqualTo("H264"));
- Assert.That(h264codec.level, Is.GreaterThan(0));
- Assert.That(h264codec.profile, Is.Not.Zero);
- break;
- }
- }
- }
- [Test]
- public void SelectCodecCapabilities()
- {
- var codecs = VideoStreamReceiver.GetAvailableCodecs();
- var caps = RTCRtpReceiver.GetCapabilities(TrackKind.Video).SelectCodecCapabilities(codecs);
- Assert.That(codecs.Count(), Is.EqualTo(caps.Count()));
- }
- [Test]
- public void SetCodec()
- {
- var go = new GameObject();
- var receiver = go.AddComponent<VideoStreamReceiver>();
- Assert.That(receiver.codec, Is.Null);
- var codecs = VideoStreamReceiver.GetAvailableCodecs();
- Assert.That(codecs, Is.Not.Empty);
- var codec = codecs.First();
- receiver.SetCodec(codec);
- Assert.That(receiver.codec, Is.EqualTo(codec));
- receiver.SetCodec(null);
- Assert.That(receiver.codec, Is.Null);
- }
- }
- class AudioStreamSenderTest
- {
- [Test]
- public void GetAvailableCodec()
- {
- IEnumerable<AudioCodecInfo> codecs = AudioStreamSender.GetAvailableCodecs();
- Assert.That(codecs, Is.Not.Empty);
- foreach(var codec in codecs)
- {
- Assert.That(codec.name, Is.Not.Empty);
- Assert.That(codec.mimeType, Is.Not.Empty);
- Assert.That(codec.channelCount, Is.GreaterThan(0));
- Assert.That(codec.sampleRate, Is.GreaterThan(0));
- }
- }
- [UnityTest]
- public IEnumerator CreateTrack()
- {
- var go = new GameObject();
- var sender = go.AddComponent<AudioStreamSender>();
- MediaStreamTrack track;
- // With AudioSource
- var go2 = new GameObject();
- sender = go2.AddComponent<AudioStreamSender>();
- sender.source = AudioStreamSource.AudioSource;
- Assert.That(() => sender.CreateTrack(), Throws.Exception.TypeOf<InvalidOperationException>());
- sender.audioSource = go2.AddComponent<AudioSource>();
- var op = sender.CreateTrack();
- yield return op;
- track = op.Track;
- Assert.That(track, Is.Not.Null);
- track.Dispose();
- // APIOnly
- var go3 = new GameObject();
- sender = go3.AddComponent<AudioStreamSender>();
- sender.source = AudioStreamSource.APIOnly;
- op = sender.CreateTrack();
- yield return op;
- track = op.Track;
- Assert.That(track, Is.Not.Null);
- track.Dispose();
- // With AudioListener
- // workaround(kazuki): Fix NullReferenceException in AudioStreamTrack.ProcessAudio.
- //sender.source = AudioStreamSource.AudioListener;
- //Assert.That(() => sender.CreateTrack(), Throws.Exception.TypeOf<InvalidOperationException>());
- //sender.audioListener = go.AddComponent<AudioListener>();
- //op = sender.CreateTrack();
- //yield return op;
- //track = op.Track;
- //Assert.That(track, Is.Not.Null);
- //track.Dispose();
- // With Microphone
- #if !(UNITY_IPHONE || UNITY_ANDROID)
- if (Microphone.devices.Length > 0 && Application.HasUserAuthorization(UserAuthorization.Microphone))
- {
- sender.source = AudioStreamSource.Microphone;
- op = sender.CreateTrack();
- yield return op;
- track = op.Track;
- Assert.That(track, Is.Not.Null);
- track.Dispose();
- track = null;
- }
- #endif
- UnityEngine.Object.DestroyImmediate(go);
- UnityEngine.Object.DestroyImmediate(go2);
- UnityEngine.Object.DestroyImmediate(go3);
- }
- // workaround(kazuki): Fix NullReferenceException in AudioStreamTrack.ProcessAudio. (WRS-231)
- [UnityTest]
- [UnityPlatform(exclude = new[] { RuntimePlatform.OSXEditor, RuntimePlatform.OSXPlayer, RuntimePlatform.LinuxEditor, RuntimePlatform.LinuxPlayer })]
- public IEnumerator ReplaceTrack()
- {
- var go = new GameObject();
- var sender = go.AddComponent<AudioStreamSender>();
- Assert.That(() => sender.ReplaceTrack(null), Throws.Exception.TypeOf<ArgumentNullException>());
- // With AudioListener
- sender.source = AudioStreamSource.AudioListener;
- var audioListener = go.AddComponent<AudioListener>();
- sender.audioListener = audioListener;
- var op = sender.CreateTrack();
- yield return op;
- var track = op.Track;
- Assert.That(track, Is.Not.Null);
- sender.ReplaceTrack(track);
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void SelectCodecCapabilities()
- {
- var codecs = AudioStreamSender.GetAvailableCodecs();
- var caps = RTCRtpSender.GetCapabilities(TrackKind.Audio).SelectCodecCapabilities(codecs);
- Assert.That(codecs.Count(), Is.EqualTo(caps.Count()));
- }
- [Test]
- public void SetEnabled()
- {
- var go = new GameObject();
- var sender = go.AddComponent<AudioStreamSender>();
- sender.enabled = false;
- sender.enabled = true;
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void IsPlaying()
- {
- var go = new GameObject();
- var sender = go.AddComponent<VideoStreamSender>();
- Assert.That(sender.isPlaying, Is.False);
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void SetBitrate()
- {
- var go = new GameObject();
- var sender = go.AddComponent<AudioStreamSender>();
- uint minBitrate = 1000;
- uint maxBitrate = 2000;
- sender.SetBitrate(minBitrate, maxBitrate);
- Assert.That(sender.minBitrate, Is.EqualTo(minBitrate));
- Assert.That(sender.maxBitrate, Is.EqualTo(maxBitrate));
- minBitrate = 3000;
- Assert.That(() => sender.SetBitrate(minBitrate, maxBitrate), Throws.Exception.TypeOf<ArgumentException>());
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void SetCodec()
- {
- var go = new GameObject();
- var sender = go.AddComponent<AudioStreamSender>();
- Assert.That(sender.codec, Is.Null);
- var codecs = AudioStreamSender.GetAvailableCodecs();
- Assert.That(codecs, Is.Not.Empty);
- var codec = codecs.First();
- sender.SetCodec(codec);
- Assert.That(sender.codec, Is.EqualTo(codec));
- sender.SetCodec(null);
- Assert.That(sender.codec, Is.Null);
- }
- [Test]
- public void SetData()
- {
- var go = new GameObject();
- var sender = go.AddComponent<AudioStreamSender>();
- NativeArray<float> nativeArray = new NativeArray<float>(256, Allocator.Temp);
- Assert.That(() => sender.SetData(ref nativeArray, 2), Throws.Exception.TypeOf<InvalidOperationException>());
- sender.source = AudioStreamSource.APIOnly;
- Assert.That(() => sender.SetData(ref nativeArray, 2), Throws.Nothing);
- nativeArray.Dispose();
- }
- }
- class AudioStreamReceiverTest
- {
- [Test]
- public void GetAvailableCodec()
- {
- IEnumerable<AudioCodecInfo> codecs = AudioStreamReceiver.GetAvailableCodecs();
- Assert.That(codecs, Is.Not.Empty);
- foreach (var codec in codecs)
- {
- Assert.That(codec.name, Is.Not.Empty);
- Assert.That(codec.mimeType, Is.Not.Empty);
- Assert.That(codec.channelCount, Is.GreaterThan(0));
- Assert.That(codec.sampleRate, Is.GreaterThan(0));
- }
- }
- [Test]
- public void SelectCodecCapabilities()
- {
- var codecs = AudioStreamReceiver.GetAvailableCodecs();
- var caps = RTCRtpReceiver.GetCapabilities(TrackKind.Audio).SelectCodecCapabilities(codecs);
- Assert.That(codecs.Count(), Is.EqualTo(caps.Count()));
- }
- [Test]
- public void SetCodec()
- {
- var go = new GameObject();
- var receiver = go.AddComponent<AudioStreamReceiver>();
- Assert.That(receiver.codec, Is.Null);
- var codecs = AudioStreamReceiver.GetAvailableCodecs();
- Assert.That(codecs, Is.Not.Empty);
- var codec = codecs.First();
- receiver.SetCodec(codec);
- Assert.That(receiver.codec, Is.EqualTo(codec));
- receiver.SetCodec(null);
- Assert.That(receiver.codec, Is.Null);
- }
- }
- class InputSenderTest
- {
- [Test]
- public void SetChannel()
- {
- var go = new GameObject();
- var sender = go.AddComponent<InputSender>();
- Assert.That(sender.Channel, Is.Null);
- Assert.That(() => sender.SetChannel(null), Throws.Exception.TypeOf<NullReferenceException>());
- sender.enabled = false;
- sender.enabled = true;
- sender.SetChannel(null, null);
- var connection = new RTCPeerConnection();
- var channel = connection.CreateDataChannel("test");
- sender.SetChannel(null, channel);
- UnityEngine.Object.DestroyImmediate(go);
- channel.Dispose();
- connection.Dispose();
- }
- }
- class InputReceiverTest
- {
- [Test]
- public void SetChannel()
- {
- var go = new GameObject();
- go.SetActive(false);
- var receiver = go.AddComponent<InputReceiver>();
- var asset = ScriptableObject.CreateInstance<InputActionAsset>();
- var mapName = "test";
- asset.AddActionMap(mapName);
- receiver.actions = asset;
- go.SetActive(true);
- Assert.That(receiver.Channel, Is.Null);
- Assert.That(() => receiver.SetChannel(null), Throws.Exception.TypeOf<NullReferenceException>());
- receiver.enabled = false;
- receiver.enabled = true;
- Assert.That(receiver.inputIsActive, Is.True);
- Assert.That(receiver.user.id, Is.Not.EqualTo(InputUser.InvalidId));
- Assert.That(receiver.devices, Is.Empty);
- Assert.That(receiver.defaultActionMap, Is.Null);
- Assert.That(receiver.currentActionMap, Is.Null);
- receiver.currentActionMap = new InputActionMap();
- Assert.That(receiver.actionEvents, Is.Not.Null);
- receiver.actionEvents = new PlayerInput.ActionEvent[]{};
- receiver.SwitchCurrentActionMap(mapName);
- var device = UnityEngine.InputSystem.InputSystem.devices.First();
- receiver.PerformPairingWithDevice(device);
- receiver.PerformPairingWithAllLocalDevices();
- receiver.UnpairDevices(device);
- receiver.SetChannel(null, null);
- UnityEngine.Object.DestroyImmediate(asset);
- UnityEngine.Object.DestroyImmediate(go);
- }
- [Test]
- public void InputUserId()
- {
- var go = new GameObject();
- go.SetActive(false);
- var receiver = go.AddComponent<InputReceiver>();
- // user.id is InputUser.InvalidId in default.
- Assert.That(receiver.actions, Is.Null);
- Assert.That(receiver.user.id, Is.EqualTo(InputUser.InvalidId));
- var asset = ScriptableObject.CreateInstance<InputActionAsset>();
- var mapName = "test";
- asset.AddActionMap(mapName);
- receiver.actions = asset;
- // user.id is not InputUser.InvalidId after set actions parameter.
- Assert.That(receiver.actions, Is.Not.Null);
- Assert.That(receiver.user.id, Is.EqualTo(InputUser.InvalidId));
- UnityEngine.Object.DestroyImmediate(go);
- }
- }
- }
|