BroadcastSample.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. using UnityEngine.InputSystem;
  7. using UnityEngine.InputSystem.Layouts;
  8. using UnityEngine.InputSystem.XR;
  9. namespace Unity.RenderStreaming.Samples
  10. {
  11. using InputSystem = UnityEngine.InputSystem.InputSystem;
  12. static class InputReceiverExtension
  13. {
  14. public static void CalculateInputRegion(this InputReceiver reveiver, Vector2Int size)
  15. {
  16. reveiver.CalculateInputRegion(size, new Rect(0, 0, Screen.width, Screen.height));
  17. }
  18. }
  19. static class InputActionExtension
  20. {
  21. public static void AddListener(this InputAction action, Action<InputAction.CallbackContext> callback)
  22. {
  23. action.started += callback;
  24. action.performed += callback;
  25. action.canceled += callback;
  26. }
  27. }
  28. class BroadcastSample : MonoBehaviour
  29. {
  30. [SerializeField] private SignalingManager renderStreaming;
  31. [SerializeField] private InputReceiver inputReceiver;
  32. [SerializeField] private SimpleCameraControllerV2 cameraController;
  33. [SerializeField] private UIControllerV2 uiController;
  34. [SerializeField] private VideoStreamSender videoStreamSender;
  35. [SerializeField] private Dropdown videoSourceTypeSelector;
  36. [SerializeField] private Dropdown bandwidthSelector;
  37. [SerializeField] private Dropdown scaleResolutionDownSelector;
  38. [SerializeField] private Dropdown framerateSelector;
  39. [SerializeField] private Dropdown resolutionSelector;
  40. private Dictionary<string, VideoStreamSource> videoSourceTypeOptions = new Dictionary<string, VideoStreamSource>
  41. {
  42. {"Screen", VideoStreamSource.Screen },
  43. {"Camera", VideoStreamSource.Camera },
  44. {"Texture", VideoStreamSource.Texture },
  45. {"WebCam", VideoStreamSource.WebCamera }
  46. };
  47. private Dictionary<string, uint> bandwidthOptions =
  48. new Dictionary<string, uint>()
  49. {
  50. { "10000", 10000 },
  51. { "2000", 2000 },
  52. { "1000", 1000 },
  53. { "500", 500 },
  54. { "250", 250 },
  55. { "125", 125 },
  56. };
  57. private Dictionary<string, float> scaleResolutionDownOptions =
  58. new Dictionary<string, float>()
  59. {
  60. { "Not scaling", 1.0f },
  61. { "Down scale by 2.0", 2.0f },
  62. { "Down scale by 4.0", 4.0f },
  63. { "Down scale by 8.0", 8.0f },
  64. { "Down scale by 16.0", 16.0f }
  65. };
  66. private Dictionary<string, float> framerateOptions =
  67. new Dictionary<string, float>
  68. {
  69. { "90", 90f },
  70. { "60", 60f },
  71. { "30", 30f },
  72. { "20", 20f },
  73. { "10", 10f },
  74. { "5", 5f },
  75. };
  76. private Dictionary<string, Vector2Int> resolutionOptions =
  77. new Dictionary<string, Vector2Int>
  78. {
  79. { "640x480", new Vector2Int(640, 480) },
  80. { "1280x720", new Vector2Int(1280, 720) },
  81. { "1600x1200", new Vector2Int(1600, 1200) },
  82. { "1920x1200", new Vector2Int(1920, 1200) },
  83. { "2560x1440", new Vector2Int(2560, 1440) },
  84. };
  85. private RenderStreamingSettings settings;
  86. private int lastWidth;
  87. private int lastHeight;
  88. private void Awake()
  89. {
  90. #if URS_USE_AR_FOUNDATION
  91. InputSystem.RegisterLayout<UnityEngine.XR.ARSubsystems.HandheldARInputDevice>(
  92. matches: new InputDeviceMatcher()
  93. .WithInterface(XRUtilities.InterfaceMatchAnyVersion)
  94. );
  95. #endif
  96. settings = SampleManager.Instance.Settings;
  97. if (settings != null)
  98. {
  99. if (videoStreamSender.source != VideoStreamSource.Texture)
  100. {
  101. videoStreamSender.width = (uint)settings.StreamSize.x;
  102. videoStreamSender.height = (uint)settings.StreamSize.y;
  103. }
  104. videoStreamSender.SetCodec(settings.SenderVideoCodec);
  105. }
  106. videoSourceTypeSelector.options = videoSourceTypeOptions
  107. .Select(pair => new Dropdown.OptionData { text = pair.Key })
  108. .ToList();
  109. videoSourceTypeSelector.onValueChanged.AddListener(ChangeVideoSourceType);
  110. bandwidthSelector.options = bandwidthOptions
  111. .Select(pair => new Dropdown.OptionData {text = pair.Key})
  112. .ToList();
  113. bandwidthSelector.options.Add(new Dropdown.OptionData {text = "Custom"});
  114. bandwidthSelector.onValueChanged.AddListener(ChangeBandwidth);
  115. scaleResolutionDownSelector.options = scaleResolutionDownOptions
  116. .Select(pair => new Dropdown.OptionData {text = pair.Key})
  117. .ToList();
  118. scaleResolutionDownSelector.options.Add(new Dropdown.OptionData {text = "Custom"});
  119. scaleResolutionDownSelector.onValueChanged.AddListener(ChangeScaleResolutionDown);
  120. framerateSelector.options = framerateOptions
  121. .Select(pair => new Dropdown.OptionData {text = pair.Key})
  122. .ToList();
  123. framerateSelector.options.Add(new Dropdown.OptionData {text = "Custom"});
  124. framerateSelector.onValueChanged.AddListener(ChangeFramerate);
  125. resolutionSelector.options = resolutionOptions
  126. .Select(pair => new Dropdown.OptionData {text = pair.Key})
  127. .ToList();
  128. resolutionSelector.options.Add(new Dropdown.OptionData {text = "Custom"});
  129. resolutionSelector.onValueChanged.AddListener(ChangeResolution);
  130. }
  131. private void ChangeVideoSourceType(int index)
  132. {
  133. var source = videoSourceTypeOptions.Values.ElementAt(index);
  134. videoStreamSender.source = source;
  135. }
  136. private void ChangeBandwidth(int index)
  137. {
  138. var bitrate = bandwidthOptions.Values.ElementAt(index);
  139. videoStreamSender.SetBitrate(bitrate, bitrate);
  140. }
  141. private void ChangeScaleResolutionDown(int index)
  142. {
  143. var scale = scaleResolutionDownOptions.Values.ElementAt(index);
  144. videoStreamSender.SetScaleResolutionDown(scale);
  145. CalculateInputRegion();
  146. }
  147. private void ChangeFramerate(int index)
  148. {
  149. var framerate = framerateOptions.Values.ElementAt(index);
  150. videoStreamSender.SetFrameRate(framerate);
  151. }
  152. private void ChangeResolution(int index)
  153. {
  154. var resolution = resolutionOptions.Values.ElementAt(index);
  155. videoStreamSender.SetTextureSize(resolution);
  156. CalculateInputRegion();
  157. }
  158. private void Start()
  159. {
  160. SyncDisplayVideoSenderParameters();
  161. if (renderStreaming.runOnAwake)
  162. return;
  163. if(settings != null)
  164. renderStreaming.useDefaultSettings = settings.UseDefaultSettings;
  165. if (settings?.SignalingSettings != null)
  166. renderStreaming.SetSignalingSettings(settings.SignalingSettings);
  167. renderStreaming.Run();
  168. inputReceiver.OnStartedChannel += OnStartedChannel;
  169. var map = inputReceiver.currentActionMap;
  170. map["Movement"].AddListener(cameraController.OnMovement);
  171. map["Look"].AddListener(cameraController.OnLook);
  172. map["ResetCamera"].AddListener(cameraController.OnResetCamera);
  173. map["Rotate"].AddListener(cameraController.OnRotate);
  174. map["Position"].AddListener(cameraController.OnPosition);
  175. map["Point"].AddListener(uiController.OnPoint);
  176. map["Press"].AddListener(uiController.OnPress);
  177. map["PressAnyKey"].AddListener(uiController.OnPressAnyKey);
  178. }
  179. private void OnStartedChannel(string connectionId)
  180. {
  181. CalculateInputRegion();
  182. }
  183. // Parameters can be changed from the Unity Editor inspector when in Play Mode,
  184. // So this method monitors the parameters every frame and updates scene UI.
  185. private void Update()
  186. {
  187. #if UNITY_EDITOR
  188. SyncDisplayVideoSenderParameters();
  189. #endif
  190. // Call SetInputChange if window size is changed.
  191. var width = Screen.width;
  192. var height = Screen.height;
  193. if (lastWidth == width && lastHeight == height)
  194. return;
  195. lastWidth = width;
  196. lastHeight = height;
  197. CalculateInputRegion();
  198. }
  199. private void CalculateInputRegion()
  200. {
  201. if (!inputReceiver.IsConnected)
  202. return;
  203. var width = (int)(videoStreamSender.width / videoStreamSender.scaleResolutionDown);
  204. var height = (int)(videoStreamSender.height / videoStreamSender.scaleResolutionDown);
  205. inputReceiver.CalculateInputRegion(new Vector2Int(width, height));
  206. inputReceiver.SetEnableInputPositionCorrection(true);
  207. }
  208. private void SyncDisplayVideoSenderParameters()
  209. {
  210. if (videoStreamSender == null)
  211. {
  212. return;
  213. }
  214. var bandwidthIndex = Array.IndexOf(bandwidthOptions.Values.ToArray(), videoStreamSender.maxBitrate);
  215. if (bandwidthIndex < 0)
  216. {
  217. bandwidthSelector.SetValueWithoutNotify(bandwidthSelector.options.Count - 1);
  218. }
  219. else
  220. {
  221. bandwidthSelector.SetValueWithoutNotify(bandwidthIndex);
  222. }
  223. var scaleDownIndex = Array.IndexOf(scaleResolutionDownOptions.Values.ToArray(), videoStreamSender.scaleResolutionDown);
  224. if (scaleDownIndex < 0)
  225. {
  226. scaleResolutionDownSelector.SetValueWithoutNotify(bandwidthSelector.options.Count - 1);
  227. }
  228. else
  229. {
  230. scaleResolutionDownSelector.SetValueWithoutNotify(scaleDownIndex);
  231. }
  232. var framerateIndex = Array.IndexOf(framerateOptions.Values.ToArray(), videoStreamSender.frameRate);
  233. if (framerateIndex < 0)
  234. {
  235. framerateSelector.SetValueWithoutNotify(framerateSelector.options.Count - 1);
  236. }
  237. else
  238. {
  239. framerateSelector.SetValueWithoutNotify(framerateIndex);
  240. }
  241. var target = new Vector2Int((int) videoStreamSender.width, (int) videoStreamSender.height);
  242. var resolutionIndex = Array.IndexOf(resolutionOptions.Values.ToArray(), target);
  243. if (resolutionIndex < 0)
  244. {
  245. resolutionSelector.SetValueWithoutNotify(resolutionSelector.options.Count - 1);
  246. }
  247. else
  248. {
  249. resolutionSelector.SetValueWithoutNotify(resolutionIndex);
  250. }
  251. }
  252. }
  253. }