From 645ee8fc594d2c084ea41dbbbbf31d22523e45a5 Mon Sep 17 00:00:00 2001 From: Unity Technologies <@unity> Date: Fri, 13 Dec 2024 00:00:00 +0000 Subject: [PATCH] com.unity.renderstreaming@3.1.0-exp.9 ## [3.1.0-exp.9] - 2024-12-13 ### Changed - deps: use com.unity.webrtc@3.0.0-pre.8 - doc: improve the API documentation of VideoCodecInfo - doc: improve the API documentation of AudioCodecInfo - doc: improve the API documentation of VideoStreamSender - doc: improve the API documentation of VideoStreamReceiver - doc: improve the API documentation of InputSender - doc: improve the API documentation of InputReceiver - doc: improve the API documentation of AudioStreamSender - doc: improve the API documentation of AudioStreamReceiver - doc: improve the API documentation of SignalingManager ## [3.1.0-exp.8] - 2023-11-30 ### Changed - Upgrade the version of WebRTC package `3.0.0-pre.7`. --- CHANGELOG.md | 20 +++ Editor/WebAppDownloader.cs | 2 +- Runtime/Scripts/AudioCodecInfo.cs | 51 ++++--- Runtime/Scripts/AudioStreamReceiver.cs | 36 +++-- Runtime/Scripts/AudioStreamSender.cs | 88 +++++++++--- Runtime/Scripts/CommandLineParser.cs | 10 +- Runtime/Scripts/InputReceiver.cs | 133 +++++++++++++----- Runtime/Scripts/InputSender.cs | 46 ++++-- .../InputSystem/EmulateInputFieldEvent.cs | 6 + Runtime/Scripts/PeerConnection.cs | 2 +- Runtime/Scripts/RenderStreaming.cs | 9 +- Runtime/Scripts/SignalingManager.cs | 104 ++++++++++---- Runtime/Scripts/SignalingManagerInternal.cs | 6 +- Runtime/Scripts/VideoCodecInfo.cs | 84 ++++++----- Runtime/Scripts/VideoStreamReceiver.cs | 47 ++++--- Runtime/Scripts/VideoStreamSender.cs | 111 +++++++++++---- Samples~/Example/Editor/PostProcess.cs | 40 ++++++ Samples~/Example/Editor/PostProcess.cs.meta | 11 ++ Tests/Runtime/CommandLineParserTest.cs | 1 + package.json | 10 +- 20 files changed, 593 insertions(+), 224 deletions(-) create mode 100644 Samples~/Example/Editor/PostProcess.cs create mode 100644 Samples~/Example/Editor/PostProcess.cs.meta diff --git a/CHANGELOG.md b/CHANGELOG.md index e1c939b..67678c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,26 @@ All notable changes to com.unity.renderstreaming package will be documented in t The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [3.1.0-exp.9] - 2024-12-13 + +### Changed +- deps: use com.unity.webrtc@3.0.0-pre.8 +- doc: improve the API documentation of VideoCodecInfo +- doc: improve the API documentation of AudioCodecInfo +- doc: improve the API documentation of VideoStreamSender +- doc: improve the API documentation of VideoStreamReceiver +- doc: improve the API documentation of InputSender +- doc: improve the API documentation of InputReceiver +- doc: improve the API documentation of AudioStreamSender +- doc: improve the API documentation of AudioStreamReceiver +- doc: improve the API documentation of SignalingManager + +## [3.1.0-exp.8] - 2023-11-30 + +### Changed + +- Upgrade the version of WebRTC package `3.0.0-pre.7`. + ## [3.1.0-exp.7] - 2023-08-09 ### Added diff --git a/Editor/WebAppDownloader.cs b/Editor/WebAppDownloader.cs index 71bc0cb..db4fcf1 100644 --- a/Editor/WebAppDownloader.cs +++ b/Editor/WebAppDownloader.cs @@ -7,7 +7,7 @@ namespace Unity.RenderStreaming.Editor internal static class WebAppDownloader { const string URLRoot = "https://github.com/Unity-Technologies/UnityRenderStreaming"; - const string LatestKnownVersion = "3.1.0-exp.7"; + const string LatestKnownVersion = "3.1.0-exp.8"; // TODO::fix release process of webserver runtime. const string FileNameWebAppForMac = "webserver_mac"; diff --git a/Runtime/Scripts/AudioCodecInfo.cs b/Runtime/Scripts/AudioCodecInfo.cs index 680b249..662d3b8 100644 --- a/Runtime/Scripts/AudioCodecInfo.cs +++ b/Runtime/Scripts/AudioCodecInfo.cs @@ -5,7 +5,7 @@ namespace Unity.RenderStreaming { /// - /// + /// Represents information about an audio codec, including its MIME type, SDP format parameters, channel count, and sample rate. /// [Serializable] public class AudioCodecInfo : IEquatable @@ -20,27 +20,27 @@ public class AudioCodecInfo : IEquatable private int m_SampleRate; /// - /// + /// Gets the name of the audio codec. /// public string name { get { return m_MimeType.GetCodecName(); } } /// - /// + /// Gets the MIME type of the audio codec. /// public string mimeType { get { return m_MimeType; } } /// - /// + /// Gets the number of audio channels. /// public int channelCount { get { return m_ChannelCount; } } /// - /// + /// Gets the sample rate of the audio. /// public int sampleRate { get { return m_SampleRate; } } /// - /// + /// Gets the SDP format parameters line. /// public string sdpFmtpLine { get { return m_SdpFmtpLine; } } @@ -50,10 +50,17 @@ static internal AudioCodecInfo Create(RTCRtpCodecCapability caps) } /// - /// + /// Determines whether the specified is equal to the current . /// - /// - /// + /// + /// + /// + /// + /// + /// The to compare with the current . + /// true if the specified is equal to the current ; otherwise, false. public bool Equals(AudioCodecInfo other) { if (other == null) @@ -65,30 +72,30 @@ public bool Equals(AudioCodecInfo other) } /// - /// + /// Determines whether the specified object is equal to the current . /// - /// - /// + /// The object to compare with the current . + /// true if the specified object is equal to the current ; otherwise, false. public override bool Equals(object obj) { return obj is AudioCodecInfo ? Equals((AudioCodecInfo)obj) : base.Equals(obj); } /// - /// + /// Returns a hash code for the . /// - /// + /// A hash code for the current . public override int GetHashCode() { return new { mimeType, sdpFmtpLine, channelCount, sampleRate }.GetHashCode(); } /// - /// + /// Determines whether two specified instances of are equal. /// - /// - /// - /// + /// The first to compare. + /// The second to compare. + /// true if the two instances are equal; otherwise, false. public static bool operator ==(AudioCodecInfo left, AudioCodecInfo right) { if (ReferenceEquals(left, null)) @@ -102,11 +109,11 @@ public override int GetHashCode() } /// - /// + /// Determines whether two specified instances of are not equal. /// - /// - /// - /// + /// The first to compare. + /// The second to compare. + /// true if the two instances are not equal; otherwise, false. public static bool operator !=(AudioCodecInfo left, AudioCodecInfo right) { return !(left == right); diff --git a/Runtime/Scripts/AudioStreamReceiver.cs b/Runtime/Scripts/AudioStreamReceiver.cs index be0f45c..2e80fd4 100644 --- a/Runtime/Scripts/AudioStreamReceiver.cs +++ b/Runtime/Scripts/AudioStreamReceiver.cs @@ -7,8 +7,9 @@ namespace Unity.RenderStreaming { /// - /// + /// AudioStreamReceiver is a component that receives audio streams and plays them through a specified AudioSource. /// + /// [AddComponentMenu("Render Streaming/Audio Stream Receiver")] public class AudioStreamReceiver : StreamReceiverBase { @@ -16,13 +17,13 @@ public class AudioStreamReceiver : StreamReceiverBase internal const string TargetAudioSourcePropertyName = nameof(m_TargetAudioSource); /// - /// + /// Delegate for handling updates to the received audio source. /// - /// + /// The updated AudioSource. public delegate void OnUpdateReceiveAudioSourceHandler(AudioSource source); /// - /// + /// Event triggered when the received audio source is updated. /// public OnUpdateReceiveAudioSourceHandler OnUpdateReceiveAudioSource; @@ -33,7 +34,7 @@ public class AudioStreamReceiver : StreamReceiverBase private AudioCodecInfo m_Codec; /// - /// + /// Gets the codec information for the audio stream. /// public AudioCodecInfo codec { @@ -41,7 +42,7 @@ public AudioCodecInfo codec } /// - /// + /// Gets or sets the target AudioSource where the received audio will be played. /// public AudioSource targetAudioSource { @@ -50,9 +51,15 @@ public AudioSource targetAudioSource } /// - /// + /// Gets the available audio codecs. /// - /// + /// + /// var codecs = AudioStreamReceiver.GetAvailableCodecs(); + /// foreach (var codec in codecs) + /// Debug.Log(codec.name); + /// + /// + /// A list of available codecs. static public IEnumerable GetAvailableCodecs() { var excludeCodecMimeType = new[] { "audio/CN", "audio/telephone-event" }; @@ -61,9 +68,18 @@ static public IEnumerable GetAvailableCodecs() } /// - /// + /// Sets the codec for the audio stream. /// - /// + /// + /// + /// x.mimeType.Contains("opus")); + /// audioStreamReceiver.SetCodec(codec); + /// ]]> + /// + /// + /// The codec information to set. + /// Thrown if the transceiver is streaming or the track has ended. public void SetCodec(AudioCodecInfo codec) { m_Codec = codec; diff --git a/Runtime/Scripts/AudioStreamSender.cs b/Runtime/Scripts/AudioStreamSender.cs index 918fef4..59882ab 100644 --- a/Runtime/Scripts/AudioStreamSender.cs +++ b/Runtime/Scripts/AudioStreamSender.cs @@ -9,31 +9,33 @@ namespace Unity.RenderStreaming { /// - /// + /// Specifies the source of the audio stream. /// public enum AudioStreamSource { /// - /// + /// Use the AudioListener component as the audio source. /// AudioListener = 0, /// - /// + /// Use the AudioSource component as the audio source. /// AudioSource = 1, /// - /// + /// Use the microphone as the audio source. /// Microphone = 2, /// - /// + /// Use only the API to provide audio data. /// APIOnly = 3 } /// - /// Attach AudioListerner or AudioSource + /// Component for sending audio streams. /// + /// + /// [AddComponentMenu("Render Streaming/Audio Stream Sender")] public class AudioStreamSender : StreamSenderBase { @@ -80,7 +82,7 @@ public class AudioStreamSender : StreamSenderBase private int m_frequency = 48000; /// - /// + /// Gets or sets the source of the audio stream. /// public AudioStreamSource source { @@ -100,7 +102,7 @@ public AudioStreamSource source } /// - /// + /// Gets the codec used for the audio stream. /// public AudioCodecInfo codec { @@ -108,7 +110,7 @@ public AudioCodecInfo codec } /// - /// + /// Gets the minimum bitrate for the audio stream. /// public uint minBitrate { @@ -116,7 +118,7 @@ public uint minBitrate } /// - /// + /// Gets the maximum bitrate for the audio stream. /// public uint maxBitrate { @@ -124,7 +126,7 @@ public uint maxBitrate } /// - /// Play or not sending to remote audio in local. + /// Gets or sets whether to play the audio locally while sending it to the remote peer. /// public bool loopback { @@ -149,7 +151,7 @@ public bool loopback } /// - /// The index of Microphone.devices. + /// Gets or sets the index of the microphone device used as the audio source. /// public int sourceDeviceIndex { @@ -169,7 +171,7 @@ public int sourceDeviceIndex } /// - /// + /// Gets or sets the AudioSource component used as the audio source. /// public AudioSource audioSource { @@ -189,7 +191,7 @@ public AudioSource audioSource } /// - /// + /// Gets or sets the AudioListener component used as the audio source. /// public AudioListener audioListener { @@ -209,9 +211,15 @@ public AudioListener audioListener } /// - /// + /// Gets the available video codecs. /// - /// + /// + /// var codecs = VideoStreamSender.GetAvailableCodecs(); + /// foreach (var codec in codecs) + /// Debug.Log(codec.name); + /// + /// + /// A list of available codecs. static public IEnumerable GetAvailableCodecs() { var excludeCodecMimeType = new[] { "audio/CN", "audio/telephone-event" }; @@ -220,10 +228,16 @@ static public IEnumerable GetAvailableCodecs() } /// - /// + /// Sets the bitrate range for the audio stream. /// - /// - /// + /// + /// + /// audioStreamSender.SetBitrate(128, 256); + /// + /// + /// The minimum bitrate in kbps. Must be greater than zero. + /// The maximum bitrate in kbps. Must be greater than or equal to the minimum bitrate. + /// Thrown when the maximum bitrate is less than the minimum bitrate. public void SetBitrate(uint minBitrate, uint maxBitrate) { if (minBitrate > maxBitrate) @@ -239,9 +253,17 @@ public void SetBitrate(uint minBitrate, uint maxBitrate) } /// - /// + /// Sets the codec for the audio stream. /// - /// + /// + /// + /// x.mimeType.Contains("opus")); + /// audioStreamSender.SetCodec(codec); + /// ]]> + /// + /// + /// The codec information to set. public void SetCodec(AudioCodecInfo codec) { m_Codec = codec; @@ -300,7 +322,6 @@ internal override WaitForCreateTrack CreateTrack() return m_sourceImpl.CreateTrack(); } - AudioStreamSourceImpl CreateAudioStreamSource() { switch (m_Source) @@ -317,7 +338,6 @@ AudioStreamSourceImpl CreateAudioStreamSource() throw new InvalidOperationException(""); } - private protected override void OnEnable() { OnAudioConfigurationChanged(false); @@ -331,6 +351,28 @@ private protected override void OnDisable() base.OnDisable(); } + /// + /// Sets the audio data for the stream. + /// + /// + /// + /// (bufferSize, Allocator.Temp); + /// for (int i = 0; i < bufferSize; i++) + /// { + /// audioData[i] = Mathf.Sin(2 * Mathf.PI * frequency * i / sampleRate); + /// } + /// audioStreamSender.SetData(audioData.AsReadOnly(), 1); + /// audioData.Dispose(); + /// ]]> + /// + /// + /// The native array containing the audio data. + /// The number of audio channels. + /// Thrown when the source property is not set to AudioStreamSource.APIOnly. public void SetData(NativeArray.ReadOnly nativeArray, int channels) { if (m_Source != AudioStreamSource.APIOnly) diff --git a/Runtime/Scripts/CommandLineParser.cs b/Runtime/Scripts/CommandLineParser.cs index 0d51ad9..a58788f 100644 --- a/Runtime/Scripts/CommandLineParser.cs +++ b/Runtime/Scripts/CommandLineParser.cs @@ -46,18 +46,18 @@ internal abstract class BaseArgument : IArgument public string ArgumentName { get; } /// - /// + /// /// public bool Defined => m_defined; /// - /// + /// /// public readonly bool Required; /// - /// + /// /// public T Value => m_value; @@ -212,10 +212,10 @@ static bool TryParseStringArrayArgument(string[] arguments, string argumentName, list.Add(arguments[startIndex + 1]); i = startIndex + 2; } - if (list.Count == 0 && required) + if (list.Count == 0) { argumentValue = null; - return false; + return !required; } argumentValue = list.ToArray(); return true; diff --git a/Runtime/Scripts/InputReceiver.cs b/Runtime/Scripts/InputReceiver.cs index ea48ee5..a95d359 100644 --- a/Runtime/Scripts/InputReceiver.cs +++ b/Runtime/Scripts/InputReceiver.cs @@ -24,12 +24,12 @@ public class InputReceiver : InputChannelReceiverBase internal const string DefaultActionMapPropertyName = nameof(m_DefaultActionMap); /// - /// + /// Event triggered when a device changes. /// public override event Action onDeviceChange; /// - /// + /// Gets or sets the input action asset associated with the player. /// public InputActionAsset actions { @@ -66,22 +66,22 @@ public InputActionAsset actions } /// - /// + /// Indicates whether the input is currently active. /// public bool inputIsActive => m_InputActive; /// - /// + /// Gets or sets the default action map. /// public InputUser user => m_InputUser; /// - /// + /// Gets or sets the action events associated with the player. /// public ReadOnlyArray devices => m_InputUser.pairedDevices; /// - /// + /// Gets or sets the current action map. /// public InputActionMap currentActionMap { @@ -95,7 +95,7 @@ public InputActionMap currentActionMap } /// - /// + /// Gets or sets the default action map. /// public string defaultActionMap { @@ -104,7 +104,7 @@ public string defaultActionMap } /// - /// + /// Gets or sets the action events associated with the player. /// public ReadOnlyArray actionEvents { @@ -121,9 +121,6 @@ public ReadOnlyArray actionEvents } } - /// - /// - /// protected virtual void OnEnable() { m_Enabled = true; @@ -135,9 +132,6 @@ protected virtual void OnEnable() ActivateInput(); } - /// - /// - /// protected virtual void OnDisable() { m_Enabled = false; @@ -149,8 +143,15 @@ protected virtual void OnDisable() } /// - /// + /// Activates input for the player. /// + /// + /// + /// + /// + /// public void ActivateInput() { m_InputActive = true; @@ -164,8 +165,15 @@ public void ActivateInput() } /// - /// + /// Deactivates input for the player. /// + /// + /// + /// + /// + /// public void DeactivateInput() { m_CurrentActionMap?.Disable(); @@ -174,9 +182,17 @@ public void DeactivateInput() } /// - /// + /// Switches the current action map to the one with the given name or ID. /// - /// + /// The name or ID of the action map to switch to. + /// + /// + /// + /// + /// + public void SwitchCurrentActionMap(string mapNameOrId) { // Must be enabled. @@ -205,17 +221,33 @@ public void SwitchCurrentActionMap(string mapNameOrId) } /// - /// + /// Performs pairing with the specified input device. /// - /// + /// + /// + /// (); + /// playerInput.PerformPairingWithDevice(device); + /// ]]> + /// + /// + /// The input device to pair with. public void PerformPairingWithDevice(InputDevice device) { m_InputUser = InputUser.PerformPairingWithDevice(device, m_InputUser); } /// - /// + /// Performs pairing with all local devices. /// + /// + /// + /// (); + /// playerInput.PerformPairingWithAllLocalDevices(); + /// ]]> + /// + /// public void PerformPairingWithAllLocalDevices() { foreach (var device in Inputs.devices.Where(_ => !_.remote)) @@ -225,9 +257,17 @@ public void PerformPairingWithAllLocalDevices() } /// - /// + /// Unpairs the input user with the given device. /// - /// + /// + /// + /// (); + /// playerInput.UnpairDevices(device); + /// ]]> + /// + /// + /// The device to unpair. public void UnpairDevices(InputDevice device) { if (!m_InputUser.valid) @@ -236,9 +276,23 @@ public void UnpairDevices(InputDevice device) } /// - /// + /// Sets the RTCDataChannel for the sender. /// - /// + /// + /// + /// (); + /// var channel = channels.FirstOrDefault(_ => !_.IsLocal && !_.IsConnected); + /// channel?.SetChannel(data); + /// } + /// ]]> + /// + /// + /// The connection ID. + /// The RTCDataChannel to set. public override void SetChannel(string connectionId, RTCDataChannel channel) { if (channel == null) @@ -257,28 +311,39 @@ public override void SetChannel(string connectionId, RTCDataChannel channel) } /// - /// + /// Calculates the input region based on the given texture size and region in world coordinates. /// - /// Texture Size. - /// Region of the texture in world coordinate system. + /// + /// + /// + /// + /// + /// The region of the texture in world coordinate system. + /// The size of the texture. public void CalculateInputRegion(Vector2Int size, Rect region) { receiver.CalculateInputRegion(new Rect(Vector2.zero, size), region); } /// - /// + /// Enables or disables input position correction. /// - /// + /// + /// + /// + /// + /// + /// True to enable input position correction, false to disable. public void SetEnableInputPositionCorrection(bool enabled) { receiver.EnableInputPositionCorrection = enabled; } - - /// - /// - /// protected virtual void OnDestroy() { Dispose(); diff --git a/Runtime/Scripts/InputSender.cs b/Runtime/Scripts/InputSender.cs index c2cdf6e..5d1a49f 100644 --- a/Runtime/Scripts/InputSender.cs +++ b/Runtime/Scripts/InputSender.cs @@ -6,8 +6,9 @@ namespace Unity.RenderStreaming { /// - /// + /// The InputSender component is responsible for sending input data over a data channel in a Unity Render Streaming context. /// + /// [AddComponentMenu("Render Streaming/Input Sender")] public class InputSender : DataChannelBase { @@ -16,9 +17,23 @@ public class InputSender : DataChannelBase private IDisposable suscriberDisposer; /// - /// + /// Sets the RTCDataChannel for the sender. /// - /// + /// + /// + /// (); + /// var channel = channels.FirstOrDefault(_ => !_.IsLocal && !_.IsConnected); + /// channel?.SetChannel(data); + /// } + /// ]]> + /// + /// + /// The connection ID. + /// The RTCDataChannel to set. public override void SetChannel(string connectionId, RTCDataChannel channel) { if (channel == null) @@ -37,19 +52,34 @@ public override void SetChannel(string connectionId, RTCDataChannel channel) } /// - /// + /// Calculates the input region based on the given texture size and region in world coordinates. /// - /// Texture Size. - /// Region of the texture in world coordinate system. + /// + /// + /// + /// + /// + /// The region of the texture in world coordinate system. + /// The size of the texture. public void CalculateInputResion(Rect region, Vector2Int size) { sender.CalculateInputRegion(region, new Rect(Vector2.zero, size)); } /// - /// + /// Enables or disables input position correction. /// - /// + /// + /// + /// + /// + /// + /// True to enable input position correction, false to disable. public void EnableInputPositionCorrection(bool enabled) { sender.EnableInputPositionCorrection = enabled; diff --git a/Runtime/Scripts/InputSystem/EmulateInputFieldEvent.cs b/Runtime/Scripts/InputSystem/EmulateInputFieldEvent.cs index c4c6b42..303dcde 100644 --- a/Runtime/Scripts/InputSystem/EmulateInputFieldEvent.cs +++ b/Runtime/Scripts/InputSystem/EmulateInputFieldEvent.cs @@ -213,6 +213,12 @@ unsafe Event CreateEvent(InputEventPtr ptr) // todo: not supported multibyte character. return null; } + if (utf32Char < 0x100) + { + // ignore control + if (char.IsControl((char)utf32Char)) + return null; + } return new Event { diff --git a/Runtime/Scripts/PeerConnection.cs b/Runtime/Scripts/PeerConnection.cs index a5291ca..4713912 100644 --- a/Runtime/Scripts/PeerConnection.cs +++ b/Runtime/Scripts/PeerConnection.cs @@ -86,7 +86,7 @@ public PeerConnection(bool polite, RTCConfiguration config, float resendInterval case RTCPeerConnectionState.Connected: OnConnectHandler?.Invoke(); break; - case RTCPeerConnectionState.Disconnected: + case RTCPeerConnectionState.Failed: OnDisconnectHandler?.Invoke(); break; } diff --git a/Runtime/Scripts/RenderStreaming.cs b/Runtime/Scripts/RenderStreaming.cs index b6c2bd7..1fb5f44 100644 --- a/Runtime/Scripts/RenderStreaming.cs +++ b/Runtime/Scripts/RenderStreaming.cs @@ -123,9 +123,14 @@ private static void InitializeInEditor() EditorApplication.projectChanged += () => { - if (!EditorBuildSettings.TryGetConfigObject(EditorBuildSettingsConfigKey, out RenderStreamingSettings _)) + if (EditorBuildSettings.TryGetConfigObject(EditorBuildSettingsConfigKey, out RenderStreamingSettings _)) { - Settings = AssetDatabase.LoadAssetAtPath(DefaultRenderStreamingSettingsPath); + return; + } + var value = AssetDatabase.LoadAssetAtPath(DefaultRenderStreamingSettingsPath); + if (value != null) + { + Settings = value; } }; } diff --git a/Runtime/Scripts/SignalingManager.cs b/Runtime/Scripts/SignalingManager.cs index b9f8a22..fec7a5a 100644 --- a/Runtime/Scripts/SignalingManager.cs +++ b/Runtime/Scripts/SignalingManager.cs @@ -13,6 +13,12 @@ namespace Unity.RenderStreaming { + /// + /// Manages the signaling process for Unity RenderStreaming. + /// + /// + /// + /// [AddComponentMenu("Render Streaming/Signaling Manager")] public sealed class SignalingManager : MonoBehaviour { @@ -37,13 +43,13 @@ public sealed class SignalingManager : MonoBehaviour private List handlers = new List(); /// - /// + /// Indicates whether the signaling process should automatically start when the Awake method is called. /// [SerializeField, Tooltip("Automatically started when called Awake method.")] public bool runOnAwake = true; /// - /// + /// Indicates whether to evaluate command line arguments if launching runtime on the command line. /// [SerializeField, Tooltip("Evaluate commandline arguments if launching runtime on the command line.")] public bool evaluateCommandlineArguments = true; @@ -55,7 +61,7 @@ public sealed class SignalingManager : MonoBehaviour private bool m_running; /// - /// + /// Gets a value indicating whether the signaling process is running. /// public bool Running => m_running; @@ -79,10 +85,20 @@ public bool useDefaultSettings } /// - /// + /// Sets the signaling settings. /// - /// - /// + /// + /// + /// var settings = new WebSocketSignalingSettings("ws://example.com", new[] + /// { + /// new IceServer (urls: new[] {"stun:stun.l.google.com:19302"}) + /// }); + /// signalingManager.SetSignalingSettings(settings); + /// + /// + /// The signaling settings. + /// Thrown when the signaling process has already started. + /// Thrown when the settings are null. public void SetSignalingSettings(SignalingSettings settings) { if (m_running) @@ -95,18 +111,33 @@ public void SetSignalingSettings(SignalingSettings settings) } /// - /// + /// Gets the signaling settings. /// - /// + /// + /// + /// var settings = signalingManager.GetSignalingSettings(); + /// if (settings is WebSocketSignalingSettings webSocketSettings) + /// { + /// Debug.Log($"WebSocket URL: {webSocketSettings.url}"); + /// } + /// + /// + /// The signaling settings. public SignalingSettings GetSignalingSettings() { return signalingSettings; } /// - /// + /// Adds a signaling handler. /// - /// + /// + /// + /// var handler = instance.GetComponent(); + /// signalingManager.AddSignalingHandler(handler); + /// + /// + /// The signaling handler to add. public void AddSignalingHandler(SignalingHandlerBase handlerBase) { if (handlers.Contains(handlerBase)) @@ -124,9 +155,15 @@ public void AddSignalingHandler(SignalingHandlerBase handlerBase) } /// - /// + /// Removes a signaling handler. /// - /// + /// + /// + /// var handler = instance.GetComponent(); + /// signalingManager.RemoveSignalingHandler(handler); + /// + /// + /// The signaling handler to remove. public void RemoveSignalingHandler(SignalingHandlerBase handlerBase) { handlers.Remove(handlerBase); @@ -140,10 +177,15 @@ public void RemoveSignalingHandler(SignalingHandlerBase handlerBase) } /// - /// + /// Runs the signaling process. /// - /// - /// + /// The signaling instance to use. If null, a new instance will be created. + /// The signaling handlers to use. If null, the existing handlers will be used. + /// + /// + /// signalingManager.Run(); + /// + /// public void Run( ISignaling signaling = null, SignalingHandlerBase[] handlers = null) @@ -152,12 +194,21 @@ public void Run( } /// - /// + /// Runs the signaling process with the specified RTC configuration. /// - /// - /// - /// - /// To use this method, Need to depend WebRTC package + /// + /// + /// var rtcConfig = new RTCConfiguration + /// { + /// iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } } + /// }; + /// signalingManager.Run(rtcConfig); + /// + /// + /// The RTC configuration. + /// The signaling instance to use. If null, a new instance will be created. + /// The signaling handlers to use. If null, the existing handlers will be used. + /// To use this method, the WebRTC package is required. public void Run( RTCConfiguration conf, ISignaling signaling = null, @@ -178,12 +229,6 @@ bool IsValidSignalingSettingsObject(SignalingSettingsObject asset) } #endif - /// - /// - /// - /// - /// - /// private void _Run( RTCConfiguration? conf = null, ISignaling signaling = null, @@ -266,8 +311,13 @@ internal static bool EvaluateCommandlineArguments(ref SignalingSettings settings } /// - /// + /// Stops the signaling process. /// + /// + /// + /// signalingManager.Stop(); + /// + /// public void Stop() { m_instance?.Dispose(); diff --git a/Runtime/Scripts/SignalingManagerInternal.cs b/Runtime/Scripts/SignalingManagerInternal.cs index 2901c97..db0fae9 100644 --- a/Runtime/Scripts/SignalingManagerInternal.cs +++ b/Runtime/Scripts/SignalingManagerInternal.cs @@ -365,7 +365,11 @@ PeerConnection CreatePeerConnection(string connectionId, bool polite) _mapConnectionIdAndPeer[connectionId] = peer; peer.OnConnectHandler += () => onConnect?.Invoke(connectionId); - peer.OnDisconnectHandler += () => onDisconnect?.Invoke(connectionId); + peer.OnDisconnectHandler += () => + { + _signaling?.CloseConnection(connectionId); + onDisconnect?.Invoke(connectionId); + }; peer.OnDataChannelHandler += channel => onAddChannel?.Invoke(connectionId, channel); ; peer.OnTrackEventHandler += e => onAddTransceiver?.Invoke(connectionId, e.Transceiver); peer.SendOfferHandler += desc => _signaling?.SendOffer(connectionId, desc); diff --git a/Runtime/Scripts/VideoCodecInfo.cs b/Runtime/Scripts/VideoCodecInfo.cs index ef07054..5f1d7cf 100644 --- a/Runtime/Scripts/VideoCodecInfo.cs +++ b/Runtime/Scripts/VideoCodecInfo.cs @@ -6,7 +6,7 @@ namespace Unity.RenderStreaming { /// - /// + /// Represents information about a video codec, including its MIME type, SDP format parameters. /// [Serializable] public class VideoCodecInfo : IEquatable @@ -21,30 +21,37 @@ public class VideoCodecInfo : IEquatable readonly Dictionary m_parameters = new Dictionary(); /// - /// + /// Gets the name of the video codec. /// public string name { get { return m_MimeType.GetCodecName(); } } /// - /// + /// Gets the MIME type of the video codec. /// public string mimeType { get { return m_MimeType; } } /// - /// + /// Gets the codec implementation name. /// public string codecImplementation { get { return parameters[KeyCodecImplementation]; } } /// - /// + /// Gets the SDP format parameters line. /// public string sdpFmtpLine { get { return m_SdpFmtpLine; } } /// - /// + /// Determines whether the specified is equal to the current . /// - /// - /// + /// + /// + /// + /// + /// + /// The to compare with the current . + /// True if the specified is equal to the current ; otherwise, false. public bool Equals(VideoCodecInfo other) { if (other == null) @@ -54,30 +61,31 @@ public bool Equals(VideoCodecInfo other) } /// - /// + /// Determines whether the specified object is equal to the current . /// - /// - /// + /// The object to compare with the current . + /// True if the specified object is equal to the current ; otherwise, false. public override bool Equals(object obj) { return obj is VideoCodecInfo ? Equals((VideoCodecInfo)obj) : base.Equals(obj); } /// - /// + /// Returns a hash code for the . + /// The hash code is based on the MIME type and SDP format parameters line properties. /// - /// + /// A hash code for the current . public override int GetHashCode() { return new { mimeType, sdpFmtpLine }.GetHashCode(); } /// - /// + /// Determines whether two specified instances of are equal. /// - /// - /// - /// + /// The first to compare. + /// The second to compare. + /// True if the two instances are equal; otherwise, false. public static bool operator ==(VideoCodecInfo left, VideoCodecInfo right) { if (ReferenceEquals(left, null)) @@ -91,11 +99,11 @@ public override int GetHashCode() } /// - /// + /// Determines whether two specified instances of are not equal. /// - /// - /// - /// + /// The first to compare. + /// The second to compare. + /// True if the two instances are not equal; otherwise, false. public static bool operator !=(VideoCodecInfo left, VideoCodecInfo right) { return !(left == right); @@ -158,37 +166,37 @@ internal VideoCodecInfo(RTCRtpCodecCapability caps) } /// - /// + /// Represents the profiles for the VP9 video codec. /// public enum VP9Profile { /// - /// + /// Profile 0. /// Profile0 = 0, /// - /// + /// Profile 1. /// Profile1 = 1, /// - /// + /// Profile 2. /// Profile2 = 2, /// - /// + /// Profile 3. /// Profile3 = 3, } /// - /// + /// Represents information about the VP9 video codec. /// public class VP9CodecInfo : VideoCodecInfo { const string KeyProfileId = "profile-id"; /// - /// + /// Gets the profile of the VP9 video codec. /// public VP9Profile? profile { @@ -208,7 +216,7 @@ internal VP9CodecInfo(RTCRtpCodecCapability caps) : base(caps) } /// - /// + /// Represents the profiles for the H264 video codec. /// public enum H264Profile { @@ -235,14 +243,14 @@ public enum H264Profile } /// - /// + /// Represents information about the H264 video codec. /// public class H264CodecInfo : VideoCodecInfo { const string KeyProfileLevelId = "profile-level-id"; /// - /// + /// Gets the profile of the H264 video codec. /// public H264Profile profile { @@ -250,7 +258,7 @@ public H264Profile profile } /// - /// + /// Gets the level of the H264 video codec. /// public int level { get { return Convert.ToInt32(parameters[KeyProfileLevelId], 16) & 0xFF; } } @@ -260,33 +268,33 @@ internal H264CodecInfo(RTCRtpCodecCapability caps) : base(caps) } /// - /// + /// Represents the profiles for the AV1 video codec. /// public enum AV1Profile { /// - /// + /// Profile 0. /// Profile0 = 0, /// - /// + /// Profile 1. /// Profile1 = 1, /// - /// + /// Profile 2. /// Profile2 = 2, } /// - /// + /// Represents information about the AV1 video codec. /// public class AV1CodecInfo : VideoCodecInfo { const string KeyProfile = "profile"; /// - /// + /// Gets the profile of the AV1 video codec. /// public AV1Profile profile { diff --git a/Runtime/Scripts/VideoStreamReceiver.cs b/Runtime/Scripts/VideoStreamReceiver.cs index 033756c..bb49efa 100644 --- a/Runtime/Scripts/VideoStreamReceiver.cs +++ b/Runtime/Scripts/VideoStreamReceiver.cs @@ -8,22 +8,22 @@ namespace Unity.RenderStreaming { /// - /// + /// Enum representing the video render mode. /// public enum VideoRenderMode { /// - /// + /// Render to a RenderTexture. /// RenderTexture, /// - /// + /// API only, no rendering. /// APIOnly, } /// - /// + /// Component for receiving video streams. /// [AddComponentMenu("Render Streaming/Video Stream Receiver")] public class VideoStreamReceiver : StreamReceiverBase @@ -33,13 +33,13 @@ public class VideoStreamReceiver : StreamReceiverBase internal const string TargetTexturePropertyName = nameof(m_TargetTexture); /// - /// + /// Delegate for updating the received texture. /// - /// + /// The received texture. public delegate void OnUpdateReceiveTextureHandler(Texture receiveTexture); /// - /// + /// Event triggered when the received texture is updated. /// public OnUpdateReceiveTextureHandler OnUpdateReceiveTexture; @@ -53,7 +53,7 @@ public class VideoStreamReceiver : StreamReceiverBase private RenderTexture m_TargetTexture; /// - /// + /// Gets the codec information for the video stream. /// public VideoCodecInfo codec { @@ -61,22 +61,22 @@ public VideoCodecInfo codec } /// - /// + /// The width of the received video stream. /// public int width => m_texture.width; /// - /// + /// The height of the received video stream. /// public int height => m_texture.height; /// - /// + /// The texture of the received video stream. /// public Texture texture => m_texture; /// - /// + /// The target RenderTexture. /// public RenderTexture targetTexture { @@ -90,9 +90,15 @@ public RenderTexture targetTexture /// - /// + /// Gets the available video codecs. /// - /// + /// + /// var codecs = VideoStreamSender.GetAvailableCodecs(); + /// foreach (var codec in codecs) + /// Debug.Log(codec.name); + /// + /// + /// A list of available codecs. public static IEnumerable GetAvailableCodecs() { string[] excludeCodecMimeType = { "video/red", "video/ulpfec", "video/rtx", "video/flexfec-03" }; @@ -101,9 +107,18 @@ public static IEnumerable GetAvailableCodecs() } /// - /// + /// Sets the codec for the video stream. /// - /// + /// + /// + /// x.mimeType.Contains("VP9")); + /// videoStreamReceiver.SetCodec(codec); + /// ]]> + /// + /// + /// The codec information to set. + /// Thrown if the transceiver is streaming or the track has ended. public void SetCodec(VideoCodecInfo codec) { m_Codec = codec; diff --git a/Runtime/Scripts/VideoStreamSender.cs b/Runtime/Scripts/VideoStreamSender.cs index b63117e..9237cdd 100644 --- a/Runtime/Scripts/VideoStreamSender.cs +++ b/Runtime/Scripts/VideoStreamSender.cs @@ -86,29 +86,29 @@ public static RTCError SetBitrate(this RTCRtpSender sender, uint? minBitrate, ui } /// - /// + /// Specifies the source of the video stream. /// public enum VideoStreamSource { /// - /// + /// Use the camera as the video stream source. /// Camera = 0, /// - /// + /// Use the screen as the video stream source. /// Screen = 1, /// - /// + /// Use the web camera as the video stream source. /// WebCamera = 2, /// - /// + /// Use a texture as the video stream source. /// Texture = 3 } /// - /// + /// Component for sending video streams. /// [AddComponentMenu("Render Streaming/Video Stream Sender")] public class VideoStreamSender : StreamSenderBase @@ -171,7 +171,7 @@ public class VideoStreamSender : StreamSenderBase private VideoStreamSourceImpl m_sourceImpl = null; /// - /// + /// Gets or sets the source of the video stream. /// public VideoStreamSource source { @@ -191,7 +191,7 @@ public VideoStreamSource source } /// - /// + /// Gets or sets the camera used as the video stream source. /// public Camera sourceCamera { @@ -211,7 +211,7 @@ public Camera sourceCamera } /// - /// + /// Gets or sets the texture used as the video stream source. /// public Texture sourceTexture { @@ -251,7 +251,7 @@ public int sourceDeviceIndex } /// - /// + /// Gets the WebCamTexture used as the video stream source. /// public WebCamTexture sourceWebCamTexture { @@ -267,7 +267,7 @@ public WebCamTexture sourceWebCamTexture /// - /// + /// Gets the frame rate of the video stream. /// public float frameRate { @@ -275,7 +275,7 @@ public float frameRate } /// - /// + /// Gets the minimum bitrate of the video stream. /// public uint minBitrate { @@ -283,7 +283,7 @@ public uint minBitrate } /// - /// + /// Gets the maximum bitrate of the video stream. /// public uint maxBitrate { @@ -291,7 +291,7 @@ public uint maxBitrate } /// - /// + /// The scale factor by which to reduce the video resolution to conserve bandwidth. /// public float scaleResolutionDown { @@ -299,7 +299,7 @@ public float scaleResolutionDown } /// - /// + /// Gets or sets the width of the frame buffer used for streaming. /// public uint width { @@ -311,7 +311,7 @@ public uint width } /// - /// + /// Gets or sets the height of the frame buffer used for streaming. /// public uint height { @@ -323,7 +323,7 @@ public uint height } /// - /// + /// Gets the codec information for the video stream. /// public VideoCodecInfo codec { @@ -331,7 +331,7 @@ public VideoCodecInfo codec } /// - /// + /// Whether request permission to use any video input sources. /// public bool autoRequestUserAuthorization { @@ -340,9 +340,17 @@ public bool autoRequestUserAuthorization } /// - /// + /// Sets the codec for the video stream. /// - /// + /// + /// + /// x.mimeType.Contains("VP9")); + /// videoStreamSender.SetCodec(codec); + /// ]]> + /// + /// + /// The codec information to set. public void SetCodec(VideoCodecInfo codec) { if (isPlaying) @@ -364,9 +372,15 @@ public void SetCodec(VideoCodecInfo codec) } /// - /// + /// Gets the available video codecs. /// - /// + /// + /// var codecs = VideoStreamSender.GetAvailableCodecs(); + /// foreach (var codec in codecs) + /// Debug.Log(codec.name); + /// + /// + /// A list of available codecs. public static IEnumerable GetAvailableCodecs() { string[] excludeCodecMimeType = { "video/red", "video/ulpfec", "video/rtx", "video/flexfec-03" }; @@ -375,9 +389,15 @@ public static IEnumerable GetAvailableCodecs() } /// - /// + /// Sets the frame rate for the video stream. /// - /// + /// + /// + /// videoStreamSender.SetFrameRate(30.0f); + /// + /// + /// The new frame rate. Must be greater than zero. + /// Thrown when the frame rate is less than or equal to zero. public void SetFrameRate(float frameRate) { if (frameRate < 0) @@ -392,9 +412,16 @@ public void SetFrameRate(float frameRate) } /// - /// + /// Sets the bitrate range for the video stream. /// - /// + /// + /// + /// videoStreamSender.SetBitrate(1000, 2500); + /// + /// + /// The minimum bitrate in kbps. Must be greater than zero. + /// The maximum bitrate in kbps. Must be greater than or equal to the minimum bitrate. + /// Thrown when the maximum bitrate is less than the minimum bitrate. public void SetBitrate(uint minBitrate, uint maxBitrate) { if (minBitrate > maxBitrate) @@ -410,9 +437,15 @@ public void SetBitrate(uint minBitrate, uint maxBitrate) } /// - /// + /// Sets the scale factor by which to reduce the video resolution to conserve bandwidth. /// - /// The parameter must be greater than 1.0f. + /// + /// + /// videoStreamSender.SetScaleResolutionDown(2.0f); + /// + /// + /// The scale factor by which to reduce the resolution. Must be greater than 1.0f. + /// Thrown when the scale factor is less than or equal to 1.0f. public void SetScaleResolutionDown(float scaleFactor) { if (scaleFactor < 1.0f) @@ -429,9 +462,14 @@ public void SetScaleResolutionDown(float scaleFactor) } /// - /// + /// Sets the size of the frame buffer used for streaming. /// - /// + /// + /// + /// SetTextureSize(new Vector2Int(1920, 1080)); + /// + /// + /// The new size of the texture as a Vector2Int. public void SetTextureSize(Vector2Int size) { m_TextureSize = size; @@ -670,6 +708,11 @@ static Vector2Int GetScreenSize() return new Vector2Int(screenWidth, screenHeight); } + public static void CopyTextureFunction(Texture source, RenderTexture dest) + { + Graphics.Blit(source, dest); + } + public override WaitForCreateTrack CreateTrack() { Vector2Int screenSize = GetScreenSize(); @@ -688,7 +731,13 @@ public override WaitForCreateTrack CreateTrack() m_coroutineScreenCapture = m_behaviour.StartCoroutine(RecordScreenFrame()); var instruction = new WaitForCreateTrack(); - instruction.Done(new VideoStreamTrack(m_screenCopyTexture, isOpenGl)); + + CopyTexture copyTexture = null; + if (!isOpenGl) + { + copyTexture = CopyTextureFunction; + } + instruction.Done(new VideoStreamTrack(m_screenCopyTexture, copyTexture)); return instruction; } diff --git a/Samples~/Example/Editor/PostProcess.cs b/Samples~/Example/Editor/PostProcess.cs new file mode 100644 index 0000000..afdcea0 --- /dev/null +++ b/Samples~/Example/Editor/PostProcess.cs @@ -0,0 +1,40 @@ +using UnityEditor; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; +#if UNITY_IOS +using UnityEditor.iOS.Xcode; +#endif + +class PostProcess : IPostprocessBuildWithReport +{ + public int callbackOrder { get { return 0; } } + + public void OnPostprocessBuild(BuildReport report) + { +#if UNITY_IOS + if (report.summary.platform == BuildTarget.iOS) + { + string projectPath = report.summary.outputPath + "/Unity-iPhone.xcodeproj/project.pbxproj"; + + PBXProject pbxProject = new PBXProject(); + pbxProject.ReadFromFile(projectPath); + + //Disabling Bitcode on all targets + + //Main + string target = pbxProject.GetUnityMainTargetGuid(); + pbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); + + //Unity Tests + target = pbxProject.TargetGuidByName(PBXProject.GetUnityTestTargetName()); + pbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); + + //Unity Framework + target = pbxProject.GetUnityFrameworkTargetGuid(); + pbxProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO"); + + pbxProject.WriteToFile(projectPath); + } +#endif + } +} diff --git a/Samples~/Example/Editor/PostProcess.cs.meta b/Samples~/Example/Editor/PostProcess.cs.meta new file mode 100644 index 0000000..6d1a574 --- /dev/null +++ b/Samples~/Example/Editor/PostProcess.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a6fe6dcd54394a62ba7efc4d7352432 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Runtime/CommandLineParserTest.cs b/Tests/Runtime/CommandLineParserTest.cs index 3123500..c1fe391 100644 --- a/Tests/Runtime/CommandLineParserTest.cs +++ b/Tests/Runtime/CommandLineParserTest.cs @@ -19,6 +19,7 @@ public void NothingArgument() Assert.That(CommandLineParser.TryParse(arguments), Is.True); Assert.That((string)CommandLineParser.SignalingUrl, Is.Null); Assert.That((int?)CommandLineParser.PollingInterval, Is.Null); + Assert.That((string[])CommandLineParser.IceServerUrls, Is.Null); } [Test] diff --git a/package.json b/package.json index 5ef9eea..c5823ab 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "com.unity.renderstreaming", "displayName": "Unity Render Streaming", - "version": "3.1.0-exp.7", + "version": "3.1.0-exp.9", "unity": "2020.3", "description": "This is a package for using Unity Render Streaming technology.", "dependencies": { - "com.unity.webrtc": "3.0.0-pre.6", + "com.unity.webrtc": "3.0.0-pre.8", "com.unity.inputsystem": "1.5.1", "com.unity.ugui": "1.0.0", "com.unity.modules.screencapture": "1.0.0" @@ -18,15 +18,15 @@ } ], "_upm": { - "changelog": "### Added\n\n- Added configurable logger to enable users to customize logging for their environment.\n\n### Changed\n\n- Upgrade the version of WebRTC package `3.0.0-pre.6`.\n- Add `AudioStreamSender.loopback` property.\n\n### Fixed\n\n- Fixed error on HTTP signaling when using short polling interval.\n- Fixed `SignalingManager` so that ICE server configurations aren't effected.\n- Added a workaround to fix an issue where `InputField` wasn't worked when entering characters from browsers or a `Receiver` scene of package sample.\n\n### Removed\n\n- Removed Furioos Integration." + "changelog": "### Changed\n- deps: use com.unity.webrtc@3.0.0-pre.8\n- doc: improve the API documentation of VideoCodecInfo\n- doc: improve the API documentation of AudioCodecInfo\n- doc: improve the API documentation of VideoStreamSender\n- doc: improve the API documentation of VideoStreamReceiver\n- doc: improve the API documentation of InputSender\n- doc: improve the API documentation of InputReceiver\n- doc: improve the API documentation of AudioStreamSender\n- doc: improve the API documentation of AudioStreamReceiver\n- doc: improve the API documentation of SignalingManager" }, "upmCi": { - "footprint": "8b2f5eeadcf42fdb20bc7093d52df42cecb60834" + "footprint": "53c7a2394e75942b6b9fde2a5be15a4e981f766e" }, "documentationUrl": "https://docs.unity3d.com/Packages/com.unity.renderstreaming@3.1/manual/index.html", "repository": { "url": "https://github.com/Unity-Technologies/UnityRenderStreaming.git", "type": "git", - "revision": "d6e6249765871f7ccb1acc1c55ba9e6acaf8d65f" + "revision": "d7297df8f441b213c856e4564b5b438a8d8f8a3e" } }