/*
* Copyright (C) 2021 because-why-not.com Limited
*
* Please refer to the license.txt for license information
*/
using System.Runtime.InteropServices;
using System;
using System.Text;
namespace Byn.Awrtc.Browser
{
//These call go via awrtc_unity.jslib to awrtc.jspre which has the same calls but starting with CAPI_
public static class CAPI
{
[DllImport("__Internal")]
public static extern void Unity_BrowserCallFactory_InjectJsCode(string jscode);
#region WebRtcNetwork CAPI imports
[DllImport("__Internal")]
public static extern bool Unity_WebRtcNetwork_IsAvailable();
[DllImport("__Internal")]
public static extern bool Unity_WebRtcNetwork_IsBrowserSupported();
[DllImport("__Internal")]
public static extern int Unity_WebRtcNetwork_Create(string lConfiguration);
[DllImport("__Internal")]
public static extern void Unity_WebRtcNetwork_Release(int lIndex);
[DllImport("__Internal")]
public static extern int Unity_WebRtcNetwork_Connect(int lIndex, string lRoom);
[DllImport("__Internal")]
public static extern void Unity_WebRtcNetwork_StartServer(int lIndex, string lRoom);
[DllImport("__Internal")]
public static extern void Unity_WebRtcNetwork_StopServer(int lIndex);
[DllImport("__Internal")]
public static extern void Unity_WebRtcNetwork_Disconnect(int lIndex, int lConnectionId);
[DllImport("__Internal")]
public static extern void Unity_WebRtcNetwork_Shutdown(int lIndex);
[DllImport("__Internal")]
public static extern void Unity_WebRtcNetwork_Update(int lIndex);
[DllImport("__Internal")]
public static extern void Unity_WebRtcNetwork_Flush(int lIndex);
[DllImport("__Internal")]
public static extern bool Unity_WebRtcNetwork_SendData(int lIndex, int lConnectionId, byte[] lUint8ArrayDataPtr, int lUint8ArrayDataOffset, int lUint8ArrayDataLength, bool lReliable);
[DllImport("__Internal")]
public static extern int Unity_WebRtcNetwork_GetBufferedAmount(int lIndex, int lConnectionId, bool lReliable);
[DllImport("__Internal")]
public static extern int Unity_WebRtcNetwork_PeekEventDataLength(int lIndex);
[DllImport("__Internal")]
public static extern bool Unity_WebRtcNetwork_Dequeue(int lIndex,
int[] lTypeIntArrayPtr,
int[] lConidIntArrayPtr,
byte[] lUint8ArrayDataPtr, int lUint8ArrayDataOffset, int lUint8ArrayDataLength,
int[] lDataLenIntArray);
[DllImport("__Internal")]
public static extern bool Unity_WebRtcNetwork_Peek(int lIndex,
int[] lTypeIntArrayPtr,
int[] lConidIntArrayPtr,
byte[] lUint8ArrayDataPtr, int lUint8ArrayDataOffset, int lUint8ArrayDataLength,
int[] lDataLenIntArray);
[DllImport("__Internal")]
public static extern int Unity_WebRtcNetwork_RequestStats(int lIndex);
[DllImport("__Internal")]
public static extern IntPtr Unity_WebRtcNetwork_DequeueRtcEvent(int lIndex, int[] lTypeIntArrayPtr, int[] lConidIntArrayPtr);
[DllImport("__Internal")]
public static extern IntPtr Unity_WebRtcNetwork_DequeueRtcEvent_Release(IntPtr ptr);
#endregion
#region MediaNetwork CAPI imports
[DllImport("__Internal")]
public static extern bool Unity_MediaNetwork_IsAvailable();
[DllImport("__Internal")]
public static extern bool Unity_MediaNetwork_HasUserMedia();
[DllImport("__Internal")]
public static extern int Unity_MediaNetwork_Create(string lJsonConfiguration);
[DllImport("__Internal")]
public static extern void Unity_MediaNetwork_Configure(int lIndex, bool audio, bool video,
int minWidth, int minHeight, int maxWidth, int maxHeight, int idealWidth, int idealHeight,
int minFps, int maxFps, int idealFps, string videoDeviceName,
string[] videoCodecsPtr, int videoCodecsLen, int videoBitrateKbits, string videoContentHint);
[DllImport("__Internal")]
public static extern int Unity_MediaNetwork_GetConfigurationState(int lIndex);
[DllImport("__Internal")]
public static extern int Unity_MediaNetwork_GetConfigurationError_Length(int lIndex);
[DllImport("__Internal")]
public static extern void Unity_MediaNetwork_GetConfigurationError(int lIndex, byte[] bufferPtr, int buffLen);
public static string MediaNetwork_GetConfigurationError(int lIndex){
int charLength = Unity_MediaNetwork_GetConfigurationError_Length(lIndex);
if(charLength == 0)
return null;
//oversized buffer
int bufflen = charLength * 4;
byte[] buffer = new byte[bufflen];
Unity_MediaNetwork_GetConfigurationError(lIndex, buffer, bufflen);
string result = Encoding.UTF8.GetString(buffer);
return result;
}
[DllImport("__Internal")]
public static extern void Unity_MediaNetwork_ResetConfiguration(int lIndex);
[DllImport("__Internal")]
public static extern bool Unity_MediaNetwork_TryGetFrame(int lIndex, int connectionId, int[] lWidth, int[] lHeight, byte[] lBuffer, int offset, int length);
[DllImport("__Internal")]
public static extern bool Unity_MediaNetwork_TryGetFrame_ToTexture(int lIndex, int connectionId, int lWidth, int lHeight, int lTextureId);
//[DllImport("__Internal")]
//public static extern bool Unity_MediaNetwork_TryGetFrame_ToTexture2(int lIndex, int connectionId, int[] lWidth, int[] lHeight, int[] lTextureId);
[DllImport("__Internal")]
public static extern bool Unity_MediaNetwork_TryGetFrame_Resolution(int lIndex, int connectionId, int[] lWidth, int[] lHeight);
[DllImport("__Internal")]
public static extern int Unity_MediaNetwork_TryGetFrameDataLength(int lIndex, int connectionId);
[DllImport("__Internal")]
public static extern void Unity_MediaNetwork_SetVolume(int lIndex, double volume, int connectionId);
[DllImport("__Internal")]
public static extern bool Unity_MediaNetwork_HasAudioTrack(int lIndex, int connectionId);
[DllImport("__Internal")]
public static extern bool Unity_MediaNetwork_HasVideoTrack(int lIndex, int connectionId);
[DllImport("__Internal")]
public static extern void Unity_MediaNetwork_SetMute(int lIndex, bool value);
[DllImport("__Internal")]
public static extern bool Unity_MediaNetwork_IsMute(int lIndex);
#endregion
//Device API
[DllImport("__Internal")]
public static extern void Unity_DeviceApi_Update();
[DllImport("__Internal")]
public static extern void Unity_DeviceApi_RequestUpdate();
[DllImport("__Internal")]
public static extern ulong Unity_DeviceApi_LastUpdate();
[DllImport("__Internal")]
public static extern uint Unity_Media_GetVideoDevices_Length();
[DllImport("__Internal")]
public static extern int Unity_Media_GetVideoDevices(int index, byte[] bufferPtr, int buffLen);
//video input api
[DllImport("__Internal")]
public static extern void Unity_VideoInput_AddDevice(string name, int width, int height, int fps);
[DllImport("__Internal")]
public static extern void Unity_VideoInput_RemoveDevice(string name);
//rotation & firstRowIsBottom might not be supported and are ignored on the java script side (not needed in WebGL anyway)
[DllImport("__Internal")]
public static extern bool Unity_VideoInput_UpdateFrame(string name, byte[] lBuffer, int offset, int length, int width, int height, int rotation, bool firstRowIsBottom);
//rotation & firstRowIsBottom might not be supported and are ignored on the java script side (not needed in WebGL anyway)
[DllImport("__Internal")]
public static extern bool Unity_VideoInput_UpdateFrame(string name, IntPtr ptr, int offset, int length, int width, int height, int rotation, bool firstRowIsBottom);
[DllImport("__Internal")]
public static extern void Unity_Media_EnableScreenCapture(string name, bool captureAudio);
//Adds an HTMLCanvasElement to be treated like a video device. query is used to find the canvas in the page using
//document.querySelector in java script.
[DllImport("__Internal")]
public static extern bool Unity_VideoInput_AddCanvasDevice(string query, string name, int width, int height, int fps);
//SLog
///
/// Verbose = 0
/// Info = 1,
/// Warnings = 2,
/// Errors = 3,
/// None = 4
///
/// Value for the corresponding log level.
[DllImport("__Internal")]
public static extern void Unity_SLog_SetLogLevel(int logLevel);
public enum InitMode : int
{
//Original mode. Devices will be unknown after startup
Default = 0,
//Waits for the desvice info to come in
//names might be missing though (browser security thing)
WaitForDevices = 1,
//Asks the user for camera / audio access to be able to
//get accurate device information
RequestAccess = 2
};
public enum InitState : int
{
Uninitialized = 0,
Initializing = 1,
Initialized = 2,
Failed = 3
};
[DllImport("__Internal")]
public static extern void Unity_InitAsync(InitMode initmode, bool useWebRtcAdapter);
[DllImport("__Internal")]
public static extern InitState Unity_PollInitState();
public static string ToJson(bool res)
{
if (res)
return "true";
return "false";
}
public static string NetworkConfigToJson(NetworkConfig config)
{
IceServer[] iceServers = null;
if (config.IceServers != null)
{
iceServers = config.IceServers.ToArray();
}
StringBuilder iceServersJson = new StringBuilder();
IceServersToJson(iceServers, iceServersJson);
//e.g. '{"IceServers":[{"urls":["turn.y-not.app:12345"],"credential":"testpass","username":"testuser"}],"SignalingUrl":"ws://s.y-not.app","IsConference":true,"MaxIceRestart":2,"KeepSignalingAlive":true}';
string conf = "{\"IceServers\":" + iceServersJson
+ ",\"SignalingUrl\":\"" + config.SignalingUrl
+ "\",\"IsConference\":" + ToJson(config.IsConference)
+ ",\"MaxIceRestart\":" + config.MaxIceRestart
+ ",\"KeepSignalingAlive\":" + ToJson(config.KeepSignalingAlive) + "}";
return conf;
}
static void IceServersToJson(IceServer[] lIceServers, StringBuilder jsout)
{
if (lIceServers == null)
{
jsout.Append("null");
}
else if (lIceServers.Length == 0)
{
jsout.Append("[]");
}
else
{
jsout.Append("["); //start iceServers array
for (int i = 0; i < lIceServers.Length; i++)
{
if (i > 0)
{
jsout.Append(",");
}
jsout.Append("{"); // start iceServers[i] object
//urls field is an array of strings for each url iceServers[i].urls
jsout.Append("\"");
jsout.Append("urls");
jsout.Append("\"");
jsout.Append(":");
if (lIceServers[i].Urls == null)
{
jsout.Append("null");
}
else if (lIceServers[i].Urls.Count == 0)
{
jsout.Append("[]");
}
else
{
jsout.Append("[");
for (int k = 0; k < lIceServers[i].Urls.Count; k++)
{
if (k > 0)
{
jsout.Append(",");
}
jsout.Append("\"");
jsout.Append(lIceServers[i].Urls[k]);
jsout.Append("\"");
}
jsout.Append("]");//end iceServers[i].urls array
}
if (lIceServers[i].Username != null)
{
jsout.Append(",");
jsout.Append("\"");
jsout.Append("username");
jsout.Append("\"");
jsout.Append(":");
jsout.Append("\"");
jsout.Append(lIceServers[i].Username);
jsout.Append("\"");
}
if (lIceServers[i].Credential != null)
{
jsout.Append(",");
jsout.Append("\"");
jsout.Append("credential");
jsout.Append("\"");
jsout.Append(":");
jsout.Append("\"");
jsout.Append(lIceServers[i].Credential);
jsout.Append("\"");
}
jsout.Append("}");// end iceServers[i] object
}
jsout.Append("]"); // end iceServers array
}
}
}
}