diff --git a/Runtime/Prefabs/Render Streaming Services.prefab b/Runtime/Prefabs/Render Streaming Services.prefab
index fe7f92f..31a455d 100644
--- a/Runtime/Prefabs/Render Streaming Services.prefab
+++ b/Runtime/Prefabs/Render Streaming Services.prefab
@@ -662,7 +662,7 @@ GameObject:
m_Component:
- component: {fileID: 1793859183747734309}
- component: {fileID: 1793859183747734314}
- - component: {fileID: 1793859183747734308}
+ - component: {fileID: 48972029}
m_Layer: 0
m_Name: RenderStreaming
m_TagString: Untagged
@@ -707,9 +707,9 @@ MonoBehaviour:
interval: 5
hardwareEncoderSupport: 1
handlers:
- - {fileID: 1793859183747734308}
+ - {fileID: 48972029}
runOnAwake: 1
---- !u!114 &1793859183747734308
+--- !u!114 &48972029
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@@ -718,7 +718,7 @@ MonoBehaviour:
m_GameObject: {fileID: 1793859183747734311}
m_Enabled: 1
m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: c2307e7ad91222841b562bebd81a69a0, type: 3}
+ m_Script: {fileID: 11500000, guid: 31b94e633688a294abc5410d3190b6f5, type: 3}
m_Name:
m_EditorClassIdentifier:
streams:
diff --git a/Runtime/Scripts/VRBroadcast.cs b/Runtime/Scripts/VRBroadcast.cs
new file mode 100644
index 0000000..58440a3
--- /dev/null
+++ b/Runtime/Scripts/VRBroadcast.cs
@@ -0,0 +1,97 @@
+/**
+ * Copyright 2021 Vasanth Mohan. All rights and licenses reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using Unity.RenderStreaming;
+
+namespace FusedVR.VRStreaming {
+ ///
+ /// VRBroadcast is very similar to the Broadcast script included with Render Streaming.
+ /// This script is responsible for listening for offers from the client and choosing when to respond.
+ ///
+ public class VRBroadcast : SignalingHandlerBase,
+ IOfferHandler, IAddChannelHandler, IDisconnectHandler, IDeletedConnectionHandler {
+
+ ///
+ /// Streams (video, audio, data) that need to be sent to the client
+ ///
+ [SerializeField]
+ private List streams = new List();
+
+ ///
+ /// List of all connectionIds that are connected
+ ///
+ private List connectionIds = new List();
+
+ #region Disconnect
+ public void OnDeletedConnection(SignalingEventData eventData) {
+ Disconnect(eventData.connectionId);
+ }
+
+ public void OnDisconnect(SignalingEventData eventData) {
+ Disconnect(eventData.connectionId);
+ }
+
+ private void Disconnect(string connectionId) {
+ if (!connectionIds.Contains(connectionId))
+ return;
+ connectionIds.Remove(connectionId);
+
+ foreach (var source in streams.OfType()) {
+ source.SetSender(connectionId, null);
+ }
+ foreach (var receiver in streams.OfType()) {
+ receiver.SetReceiver(connectionId, null);
+ }
+ foreach (var channel in streams.OfType()) {
+ channel.SetChannel(connectionId, null);
+ }
+ }
+ #endregion
+
+ ///
+ /// Event that is called when an Offer is made by a client
+ /// Determines whether to accept offer and if so that to apply sources and submit answer
+ ///
+ public void OnOffer(SignalingEventData data) {
+ if (connectionIds.Count >= 1) { //if there is more than 1 connection, let's skip this offer
+ Debug.Log($"Already answered this connectionId : {connectionIds[0]}");
+ return;
+ }
+
+ if (connectionIds.Contains(data.connectionId)) { //if connection is already connected, skip offer
+ Debug.Log($"Already answered this connectionId : {data.connectionId}");
+ return;
+ }
+ connectionIds.Add(data.connectionId); //confirm we will use this connection
+
+ foreach (var source in streams.OfType()) {
+ var transceiver = AddTrack(data.connectionId, source.Track);
+ source.SetSender(data.connectionId, transceiver.Sender);
+ }
+ foreach (var channel in streams.OfType().Where(c => c.IsLocal)) {
+ var _channel = CreateChannel(data.connectionId, channel.Label);
+ channel.SetChannel(data.connectionId, _channel);
+ }
+ SendAnswer(data.connectionId); //accept offer with an answer
+ }
+
+ ///
+ /// Apply Data Channel
+ ///
+ public void OnAddChannel(SignalingEventData data) {
+ var channel = streams.OfType().
+ FirstOrDefault(r => r.Channel == null && !r.IsLocal);
+ channel?.SetChannel(data.connectionId, data.channel);
+ }
+ }
+}
diff --git a/Runtime/Scripts/VRBroadcast.cs.meta b/Runtime/Scripts/VRBroadcast.cs.meta
new file mode 100644
index 0000000..917872b
--- /dev/null
+++ b/Runtime/Scripts/VRBroadcast.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 31b94e633688a294abc5410d3190b6f5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: