diff --git a/.gitignore b/.gitignore
index 5cc452b..2b8d4cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,4 +11,5 @@ discord_bot/graph.png
discord_bot/config.py
env_win/
velconnect.db
+velconnect*.db
.idea/
diff --git a/unity_package/Runtime/VELConnectManager.cs b/unity_package/Runtime/VELConnectManager.cs
index a34ff96..46e8034 100644
--- a/unity_package/Runtime/VELConnectManager.cs
+++ b/unity_package/Runtime/VELConnectManager.cs
@@ -14,7 +14,7 @@ namespace VELConnect
public class VELConnectManager : MonoBehaviour
{
public string velConnectUrl = "http://localhost";
- public static VELConnectManager instance;
+ private static VELConnectManager instance;
public class State
{
@@ -36,7 +36,8 @@ namespace VELConnect
///
public string TryGetData(string key)
{
- return data?.TryGetValue(key, out string val) == true ? val : null;
+ string val = null;
+ return data?.TryGetValue(key, out val) == true ? val : null;
}
}
@@ -50,6 +51,15 @@ namespace VELConnect
public string last_modified;
public string last_accessed;
public Dictionary data;
+
+ ///
+ /// Returns the value if it exists, otherwise null
+ ///
+ public string TryGetData(string key)
+ {
+ string val = null;
+ return data?.TryGetValue(key, out val) == true ? val : null;
+ }
}
public Device device;
@@ -63,6 +73,25 @@ namespace VELConnect
public static Action OnDeviceDataChanged;
public static Action OnRoomDataChanged;
+ private static readonly Dictionary> deviceFieldCallbacks = new Dictionary>();
+ private static readonly Dictionary> deviceDataCallbacks = new Dictionary>();
+ private static readonly Dictionary> roomDataCallbacks = new Dictionary>();
+
+ private struct CallbackListener
+ {
+ ///
+ /// Used so that other objects don't have to remove listeners themselves
+ ///
+ public MonoBehaviour keepAliveObject;
+
+ public Action callback;
+
+ ///
+ /// Sends the first state received from the network or the state at binding time
+ ///
+ public bool sendInitialState;
+ }
+
public static int PairingCode
{
get
@@ -80,10 +109,10 @@ namespace VELConnect
{
get
{
-#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
- // allows running multiple builds on the same computer
- // return SystemInfo.deviceUniqueIdentifier + Hash128.Compute(Application.dataPath);
- return SystemInfo.deviceUniqueIdentifier + "_BUILD";
+#if UNITY_EDITOR
+ // allows running multiple builds on the same computer
+ // return SystemInfo.deviceUniqueIdentifier + Hash128.Compute(Application.dataPath);
+ return SystemInfo.deviceUniqueIdentifier + "_EDITOR";
#else
return SystemInfo.deviceUniqueIdentifier;
#endif
@@ -137,7 +166,7 @@ namespace VELConnect
{ "version", Application.version },
{ "platform", SystemInfo.operatingSystem },
};
- PostRequestCallback(velConnectUrl + "/api/v2/update_user_count", JsonConvert.SerializeObject(postData));
+ PostRequestCallback(velConnectUrl + "/api/update_user_count", JsonConvert.SerializeObject(postData));
});
}
@@ -147,11 +176,13 @@ namespace VELConnect
{
try
{
- GetRequestCallback(velConnectUrl + "/api/v2/get_state/" + DeviceId, json =>
+ GetRequestCallback(velConnectUrl + "/api/v2/device/get_data/" + DeviceId, json =>
{
State state = JsonConvert.DeserializeObject(json);
if (state == null) return;
+ bool isInitialState = false;
+
// first load stuff
if (lastState == null)
{
@@ -164,8 +195,9 @@ namespace VELConnect
Debug.LogError(e);
}
- lastState = state;
- return;
+ isInitialState = true;
+ // lastState = state;
+ // return;
}
@@ -176,52 +208,126 @@ namespace VELConnect
foreach (FieldInfo fieldInfo in fields)
{
string newValue = fieldInfo.GetValue(state.device) as string;
- string oldValue = fieldInfo.GetValue(lastState.device) as string;
+ string oldValue = lastState != null ? fieldInfo.GetValue(lastState.device) as string : null;
if (newValue != oldValue)
{
try
{
- OnDeviceFieldChanged?.Invoke(fieldInfo.Name, newValue);
+ if (!isInitialState) OnDeviceFieldChanged?.Invoke(fieldInfo.Name, newValue);
}
catch (Exception e)
{
Debug.LogError(e);
}
+
+ // send specific listeners data
+ if (deviceFieldCallbacks.ContainsKey(fieldInfo.Name))
+ {
+ // clear the list of old listeners
+ deviceFieldCallbacks[fieldInfo.Name].RemoveAll(e => e.keepAliveObject == null);
+
+ // send the callbacks
+ deviceFieldCallbacks[fieldInfo.Name].ForEach(e =>
+ {
+ if (!isInitialState || e.sendInitialState)
+ {
+ try
+ {
+ e.callback(newValue);
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError(ex);
+ }
+ }
+ });
+ }
}
}
- foreach (KeyValuePair elem in state.device.data)
+ if (state.device.data != null)
{
- lastState.device.data.TryGetValue(elem.Key, out string oldValue);
- if (elem.Value != oldValue)
+ foreach (KeyValuePair elem in state.device.data)
{
- try
+ string oldValue = null;
+ lastState?.device.data.TryGetValue(elem.Key, out oldValue);
+ if (elem.Value != oldValue)
{
- OnDeviceDataChanged?.Invoke(elem.Key, elem.Value);
- }
- catch (Exception e)
- {
- Debug.LogError(e);
+ try
+ {
+ if (!isInitialState) OnDeviceDataChanged?.Invoke(elem.Key, elem.Value);
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError(ex);
+ }
+
+ // send specific listeners data
+ if (deviceDataCallbacks.ContainsKey(elem.Key))
+ {
+ // clear the list of old listeners
+ deviceDataCallbacks[elem.Key].RemoveAll(e => e.keepAliveObject == null);
+
+ // send the callbacks
+ deviceDataCallbacks[elem.Key].ForEach(e =>
+ {
+ if (!isInitialState || e.sendInitialState)
+ {
+ try
+ {
+ e.callback(elem.Value);
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError(ex);
+ }
+ }
+ });
+ }
}
}
}
}
- if (state.room.modified_by != DeviceId)
+ if (state.room.modified_by != DeviceId && state.room.data != null)
{
foreach (KeyValuePair elem in state.room.data)
{
- lastState.room.data.TryGetValue(elem.Key, out string oldValue);
+ string oldValue = null;
+ lastState?.room.data.TryGetValue(elem.Key, out oldValue);
if (elem.Value != oldValue)
{
try
{
- OnRoomDataChanged?.Invoke(elem.Key, elem.Value);
+ if (!isInitialState) OnRoomDataChanged?.Invoke(elem.Key, elem.Value);
}
catch (Exception e)
{
Debug.LogError(e);
}
+
+ // send specific listeners data
+ if (roomDataCallbacks.ContainsKey(elem.Key))
+ {
+ // clear the list of old listeners
+ roomDataCallbacks[elem.Key].RemoveAll(e => e.keepAliveObject == null);
+
+ // send the callbacks
+ roomDataCallbacks[elem.Key].ForEach(e =>
+ {
+ if (!isInitialState || e.sendInitialState)
+ {
+ try
+ {
+ e.callback(elem.Value);
+ }
+ catch (Exception ex)
+ {
+ Debug.LogError(ex);
+ }
+ }
+ });
+ }
}
}
}
@@ -239,16 +345,130 @@ namespace VELConnect
}
}
+ ///
+ /// Adds a change listener callback to a particular field name within the Device main fields.
+ ///
+ public static void AddDeviceFieldListener(string key, MonoBehaviour keepAliveObject, Action callback, bool sendInitialState = false)
+ {
+ if (!deviceFieldCallbacks.ContainsKey(key))
+ {
+ deviceFieldCallbacks[key] = new List();
+ }
+
+ deviceFieldCallbacks[key].Add(new CallbackListener()
+ {
+ keepAliveObject = keepAliveObject,
+ callback = callback,
+ sendInitialState = sendInitialState
+ });
+
+ if (sendInitialState)
+ {
+ if (instance != null && instance.lastState?.device != null)
+ {
+ if (instance.lastState.device.GetType().GetField(key)?.GetValue(instance.lastState.device) is string val)
+ {
+ try
+ {
+ callback(val);
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Adds a change listener callback to a particular field name within the Device data JSON.
+ ///
+ public static void AddDeviceDataListener(string key, MonoBehaviour keepAliveObject, Action callback, bool sendInitialState = false)
+ {
+ if (!deviceDataCallbacks.ContainsKey(key))
+ {
+ deviceDataCallbacks[key] = new List();
+ }
+
+ deviceDataCallbacks[key].Add(new CallbackListener()
+ {
+ keepAliveObject = keepAliveObject,
+ callback = callback,
+ sendInitialState = sendInitialState
+ });
+
+ if (sendInitialState)
+ {
+ string val = GetDeviceData(key);
+ if (val != null)
+ {
+ try
+ {
+ callback(val);
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Adds a change listener callback to a particular field name within the Room data JSON.
+ ///
+ public static void AddRoomDataListener(string key, MonoBehaviour keepAliveObject, Action callback, bool sendInitialState = false)
+ {
+ if (!roomDataCallbacks.ContainsKey(key))
+ {
+ roomDataCallbacks[key] = new List();
+ }
+
+ roomDataCallbacks[key].Add(new CallbackListener()
+ {
+ keepAliveObject = keepAliveObject,
+ callback = callback,
+ sendInitialState = sendInitialState
+ });
+
+ if (sendInitialState)
+ {
+ string val = GetRoomData(key);
+ if (val != null)
+ {
+ try
+ {
+ callback(val);
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e);
+ }
+ }
+ }
+ }
+
+ public static string GetDeviceData(string key)
+ {
+ return instance != null ? instance.lastState?.device?.TryGetData(key) : null;
+ }
+
+ public static string GetRoomData(string key)
+ {
+ return instance != null ? instance.lastState?.room?.TryGetData(key) : null;
+ }
+
///
/// Sets data on the device keys themselves
///
public static void SetDeviceBaseData(Dictionary data)
{
- data["modified_by"] = DeviceId;
instance.PostRequestCallback(
instance.velConnectUrl + "/api/v2/device/set_data/" + DeviceId,
- JsonConvert.SerializeObject(data)
+ JsonConvert.SerializeObject(data),
+ new Dictionary { { "modified_by", DeviceId } }
);
}
@@ -259,11 +479,8 @@ namespace VELConnect
{
instance.PostRequestCallback(
instance.velConnectUrl + "/api/v2/device/set_data/" + DeviceId,
- JsonConvert.SerializeObject(new Dictionary
- {
- { "modified_by", DeviceId },
- { "data", data }
- })
+ JsonConvert.SerializeObject(new Dictionary { { "data", data } }),
+ new Dictionary { { "modified_by", DeviceId } }
);
}
@@ -275,10 +492,10 @@ namespace VELConnect
return;
}
- data["modified_by"] = DeviceId;
instance.PostRequestCallback(
instance.velConnectUrl + "/api/v2/set_data/" + Application.productName + "_" + VelNetManager.Room,
- JsonConvert.SerializeObject(data)
+ JsonConvert.SerializeObject(data),
+ new Dictionary { { "modified_by", DeviceId } }
);
}
@@ -308,13 +525,13 @@ namespace VELConnect
}
}
- public void PostRequestCallback(string url, string postData, Action successCallback = null,
+ public void PostRequestCallback(string url, string postData, Dictionary headers = null, Action successCallback = null,
Action failureCallback = null)
{
- StartCoroutine(PostRequestCallbackCo(url, postData, successCallback, failureCallback));
+ StartCoroutine(PostRequestCallbackCo(url, postData, headers, successCallback, failureCallback));
}
- private static IEnumerator PostRequestCallbackCo(string url, string postData, Action successCallback = null,
+ private static IEnumerator PostRequestCallbackCo(string url, string postData, Dictionary headers = null, Action successCallback = null,
Action failureCallback = null)
{
UnityWebRequest webRequest = new UnityWebRequest(url, "POST");
@@ -322,6 +539,14 @@ namespace VELConnect
UploadHandlerRaw uploadHandler = new UploadHandlerRaw(bodyRaw);
webRequest.uploadHandler = uploadHandler;
webRequest.SetRequestHeader("Content-Type", "application/json");
+ if (headers != null)
+ {
+ foreach (KeyValuePair keyValuePair in headers)
+ {
+ webRequest.SetRequestHeader(keyValuePair.Key, keyValuePair.Value);
+ }
+ }
+
yield return webRequest.SendWebRequest();
switch (webRequest.result)
diff --git a/velconnect/db.py b/velconnect/db.py
index 8f5927f..6356ea1 100644
--- a/velconnect/db.py
+++ b/velconnect/db.py
@@ -24,6 +24,7 @@ class DB:
return conn, curr
def query(self, query_string: str, data: dict = None) -> list:
+ conn = None
try:
conn, curr = self.create_or_connect()
if data is not None:
@@ -35,7 +36,8 @@ class DB:
return values
except:
print(traceback.print_exc())
- conn.close()
+ if conn is not None:
+ conn.close()
raise
def insert(self, query_string: str, data: dict = None) -> bool:
diff --git a/velconnect/routes/api_v2.py b/velconnect/routes/api_v2.py
index 790d804..a4e0723 100644
--- a/velconnect/routes/api_v2.py
+++ b/velconnect/routes/api_v2.py
@@ -64,12 +64,12 @@ def get_device_by_pairing_code(pairing_code: str):
def create_device(hw_id: str):
db.insert("""
- INSERT IGNORE INTO `Device`(hw_id) VALUES (:hw_id);
+ INSERT OR IGNORE INTO `Device`(hw_id) VALUES (:hw_id);
""", {'hw_id': hw_id})
@router.get('/device/get_data/{hw_id}')
-def get_state(hw_id: str):
+def get_state(request: fastapi.Request, hw_id: str):
"""Gets the device state"""
devices = db.query("""
@@ -77,26 +77,35 @@ def get_state(hw_id: str):
""", {'hw_id': hw_id})
if len(devices) == 0:
return {'error': "Can't find device with that id."}
+ block = dict(devices[0])
+ if 'data' in block and block['data'] is not None:
+ block['data'] = json.loads(block['data'])
- room_data = get_data(f"{devices[0]['current_app']}_{devices[0]['current_room']}")
+ room_key: str = f"{devices[0]['current_app']}_{devices[0]['current_room']}"
+ room_data = get_data(room_key)
- return {'device': devices[0], 'room': room_data}
+ if "error" in room_data:
+ set_data(request, data={}, key=room_key, modified_by=None, category="room")
+ room_data = get_data(room_key)
+
+ return {'device': block, 'room': room_data}
@router.post('/device/set_data/{hw_id}')
-def set_state(hw_id: str, data: dict, request: fastapi.Request):
+def set_state(request: fastapi.Request, hw_id: str, data: dict, modified_by: str = None):
"""Sets the device state"""
create_device(hw_id)
# add the client's IP address if no sender specified
- if 'modified_by' not in data:
- data['modified_by'] = str(request.client) + "_" + str(request.headers)
+ if 'modified_by' in data:
+ modified_by = data['modified_by']
+ if modified_by is None:
+ modified_by: str = str(request.client) + "_" + str(request.headers)
allowed_keys: list[str] = [
'os_info',
'friendly_name',
- 'modified_by',
'current_app',
'current_room',
'pairing_code',
@@ -107,15 +116,17 @@ def set_state(hw_id: str, data: dict, request: fastapi.Request):
db.insert(f"""
UPDATE `Device`
SET {key}=:value,
- last_modified=CURRENT_TIMESTAMP
+ last_modified=CURRENT_TIMESTAMP,
+ modified_by=:modified_by
WHERE `hw_id`=:hw_id;
""",
{
'value': data[key],
'hw_id': hw_id,
- 'sender_id': data['sender_id']
+ 'modified_by': modified_by
})
if key == "data":
+ new_data = data['data']
# get the old json values and merge the data
old_data_query = db.query("""
SELECT data
@@ -124,8 +135,10 @@ def set_state(hw_id: str, data: dict, request: fastapi.Request):
""", {"hw_id": hw_id})
if len(old_data_query) == 1:
- old_data: dict = json.loads(old_data_query[0]["data"])
- data = {**old_data, **data}
+ old_data: dict = {}
+ if old_data_query[0]['data'] is not None:
+ old_data = json.loads(old_data_query[0]["data"])
+ new_data = {**old_data, **new_data}
# add the data to the db
db.insert("""
@@ -133,7 +146,7 @@ def set_state(hw_id: str, data: dict, request: fastapi.Request):
SET data=:data,
last_modified=CURRENT_TIMESTAMP
WHERE hw_id=:hw_id;
- """, {"hw_id": hw_id, "data": json.dumps(data)})
+ """, {"hw_id": hw_id, "data": json.dumps(new_data)})
return {'success': True}
@@ -143,18 +156,22 @@ def generate_id(length: int = 4) -> str:
@router.post('/set_data')
-def store_data_with_random_key(request: fastapi.Request, data: dict, category: str = None) -> dict:
+def set_data_with_random_key(request: fastapi.Request, data: dict, modified_by: str = None,
+ category: str = None) -> dict:
"""Creates a little storage bucket for arbitrary data with a random key"""
- return store_data(request, data, None, category)
+ return set_data(request, data, None, modified_by, category)
@router.post('/set_data/{key}')
-def store_data(request: fastapi.Request, data: dict, key: str = None, modified_by: str = None, category: str = None) -> dict:
+def set_data(request: fastapi.Request, data: dict, key: str = None, modified_by: str = None,
+ category: str = None) -> dict:
"""Creates a little storage bucket for arbitrary data"""
# add the client's IP address if no sender specified
+ if 'modified_by' in data:
+ modified_by = data['modified_by']
if modified_by is None:
- modified_by = str(request.client) + "_" + str(request.headers)
+ modified_by: str = str(request.client) + "_" + str(request.headers)
# generates a key if none was supplied
if key is None:
@@ -189,7 +206,7 @@ def get_data(key: str) -> dict:
"""Gets data from a storage bucket for arbitrary data"""
data = db.query("""
- SELECT data
+ SELECT *
FROM `DataBlock`
WHERE id=:id
""", {"id": key})
@@ -202,7 +219,11 @@ def get_data(key: str) -> dict:
try:
if len(data) == 1:
- return json.loads(data[0])
+ block = dict(data[0])
+ if 'data' in block and block['data'] is not None:
+ block['data'] = json.loads(block['data'])
+ return block
return {'error': 'Not found'}
- except:
+ except Exception as e:
+ print(e)
return {'error': 'Unknown. Maybe no data at this key.'}
diff --git a/velconnect/static/js/util.js b/velconnect/static/js/util.js
index dae3ab8..47a1c2f 100644
--- a/velconnect/static/js/util.js
+++ b/velconnect/static/js/util.js
@@ -18,8 +18,8 @@ function httpGetAsync(theUrl, callback, failCallback) {
function httpPostAsync(theUrl, data, callback, failCallback) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function () {
- if (xmlHttp.readyState == 4) {
- if (xmlHttp.status == 200) {
+ if (xmlHttp.readyState === 4) {
+ if (xmlHttp.status === 200) {
callback(xmlHttp.responseText);
} else {
failCallback(xmlHttp.status);
diff --git a/velconnect/templates/index.html b/velconnect/templates/index.html
index a6adf72..f1b2c4f 100644
--- a/velconnect/templates/index.html
+++ b/velconnect/templates/index.html
@@ -94,7 +94,7 @@
@@ -167,6 +167,8 @@
+
+
+
+
@@ -208,6 +232,7 @@
let headset_details = document.getElementById('headset_details');
let hw_id_field = document.getElementById('hw_id');
let failure = document.getElementById('failure');
+ let current_app = document.getElementById('current_app');
let current_room = document.getElementById('current_room');
let set_room_id = document.getElementById('set_room_id');
let set_user_color = document.getElementById('set_user_color');
@@ -221,9 +246,10 @@
// check cookie
let hw_id = getCookie('hw_id');
+
if (hw_id !== "" && hw_id !== undefined && hw_id !== "undefined") {
- httpGetAsync('/api/get_state/' + hw_id, (resp) => {
+ httpGetAsync('/api/v2/device/get_data/' + hw_id, (resp) => {
console.log(resp);
let respData = JSON.parse(resp);
@@ -231,20 +257,17 @@
window.location.href = "/pair";
}
- writeClass('hw_id', respData['user']['hw_id']);
- writeClass('pairing_code', respData['user']['pairing_code']);
- writeValue('current_room', respData['user']['current_room']);
- writeClass('date_created', respData['user']['date_created'] + "
" + timeSinceString(respData['user']['date_created']) + " ago");
- writeClass('last_used', respData['user']['last_used'] + "
" + timeSinceString(respData['user']['last_used']) + " ago");
- writeValue('user_color', respData['user']['user_color']);
- if (user_color) user_color.parentElement.style.color = "" + respData['user']['user_color'];
- writeValue('user_name', respData['user']['user_name']);
- writeValue('avatar_url', respData['user']['avatar_url']);
- if (respData['room']) {
- writeValue('tv_url', respData['room']['tv_url']);
- writeValue('carpet_color', respData['room']['carpet_color']);
- if (carpet_color) carpet_color.parentElement.style.color = "" + respData['room']['carpet_color'];
- }
+ writeClass('hw_id', respData['device']['hw_id']);
+ writeClass('pairing_code', respData['device']['pairing_code']);
+ writeValue('current_app', respData['device']['current_app']);
+ writeValue('current_room', respData['device']['current_room']);
+ writeClass('date_created', respData['device']['date_created'] + "
" + timeSinceString(respData['device']['date_created']) + " ago");
+ writeClass('last_modified', respData['device']['last_modified'] + "
" + timeSinceString(respData['device']['last_modified']) + " ago");
+ writeValue('user_name', respData['device']['friendly_name']);
+ writeValue('avatar_url', respData['device']['data']?.['avatar_url']);
+ writeValue('tv_url', respData['room']?.['data']?.['tv_url']);
+ writeValue('carpet_color', respData['room']?.['data']?.['carpet_color']);
+ if (carpet_color) carpet_color.parentElement.style.color = "" + respData['room']?.['data']?.['carpet_color'];
Coloris({
@@ -271,45 +294,61 @@
failure.style.display = "block";
});
- function setUserData(data) {
- data["sender_id"] = "web";
- httpPostAsync('/api/set_headset_details/' + hw_id,
- data,
- (resp) => {
- console.log('success');
+
+ function setDeviceField(data) {
+ fetch('/api/v2/device/set_data/' + hw_id, {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
},
- (status) => {
- console.log('fail');
- }
- );
+
+ body: JSON.stringify(data)
+ })
+ .then(_ => console.log('success'))
+ .catch(_ => console.log('fail'));
+ }
+
+ function setDeviceData(data) {
+ fetch('/api/v2/device/set_data/' + hw_id, {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+
+ body: JSON.stringify({"data": data})
+ })
+ .then(_ => console.log('success'))
+ .catch(_ => console.log('fail'));
}
function setRoomData(data) {
- data["sender_id"] = "web";
- httpPostAsync('/api/set_room_details/' + current_room.value,
- data,
- (resp) => {
- console.log('success');
+ fetch('/api/v2/set_data/' + current_app.value + "_" + current_room.value, {
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
},
- (status) => {
- console.log('fail');
- }
- );
+ body: JSON.stringify(data)
+ })
+ .then(_ => console.log('success'))
+ .catch(_ => console.log('fail'));
}
if (set_room_id) {
set_room_id.addEventListener('click', () => {
- setUserData({"current_room": current_room.value});
+ setDeviceField({"current_room": current_room.value});
});
}
if (set_user_color) {
set_user_color.addEventListener('click', () => {
- setUserData({"user_color": document.getElementById('user_color').value});
+ setDeviceData({"user_color": document.getElementById('user_color').value});
});
}
if (set_user_name) {
set_user_name.addEventListener('click', () => {
- setUserData({"user_name": document.getElementById('user_name').value});
+ setDeviceField({"friendly_name": document.getElementById('user_name').value});
});
}
if (set_tv_url) {
@@ -324,7 +363,7 @@
}
if (set_avatar_url) {
set_avatar_url.addEventListener('click', () => {
- setUserData({"avatar_url": document.getElementById('avatar_url').value});
+ setDeviceData({"avatar_url": document.getElementById('avatar_url').value});
});
}
@@ -351,6 +390,84 @@
});
+ const roomName = (Math.random() + 1).toString(36).substring(7);
+ const pubVideo = document.getElementById("pub_video");
+ const subVideo = document.getElementById("sub_video");
+ const bntPubCam = document.getElementById("bnt_pubcam");
+ const bntPubScreen = document.getElementById("bnt_pubscreen");
+
+ setDeviceData({"streamer_stream_id": roomName});
+
+ const serverURL = "wss://velnet.ugavel.com/ws";
+
+ const config = {
+ iceServers: [
+ {
+ urls: "stun:stun.l.google.com:19302",
+ },
+ ],
+ };
+
+ const signalLocal = new Signal.IonSFUJSONRPCSignal(serverURL);
+ const clientLocal = new IonSDK.Client(signalLocal, config);
+
+ signalLocal.onopen = () => clientLocal.join(roomName);
+
+ const start = (type) => {
+ if (type) {
+ IonSDK.LocalStream.getUserMedia({
+ resolution: "vga",
+ audio: true,
+ video: true,
+ codec: "vp8",
+ }).then((media) => {
+ pubVideo.srcObject = media;
+ pubVideo.autoplay = true;
+ pubVideo.controls = true;
+ pubVideo.muted = true;
+ bntPubCam.disabled = true;
+ bntPubScreen.disabled = true;
+ clientLocal.publish(media);
+ }).catch(console.error);
+ } else {
+ IonSDK.LocalStream.getDisplayMedia({
+ audio: true,
+ video: true,
+ codec: "vp8",
+ }).then((media) => {
+ pubVideo.srcObject = media;
+ pubVideo.autoplay = true;
+ pubVideo.controls = true;
+ pubVideo.muted = true;
+ bntPubCam.disabled = true;
+ bntPubScreen.disabled = true;
+ clientLocal.publish(media);
+ }).catch(console.error);
+ }
+ }
+
+ clientLocal.ontrack = (track, stream) => {
+ console.log("got track: ", track.id, "for stream: ", stream.id);
+ stream.mute();
+ stream.unmute();
+ if (track.kind === "video") {
+ subVideo.srcObject = stream;
+ subVideo.play();
+ }
+ //track.onunmute = () => {
+ //subVideo.srcObject = stream;
+ //subVideo.autoplay = true;
+ //subVideo.muted = true;
+
+ //subVideo.play();
+
+ //stream.onremovetrack = () => {
+ //subVideo.srcObject = null;
+ //}
+ //}
+ }
+
+
-
-
+
+
-
-
-

-
-
-
- You can find the code in the bottom left of your menu tablet in conVRged.
-
-
+
+
+

+
+
+
+ You can find the code in the bottom left of your menu tablet in conVRged.
+
+
+
-
+ });
+