2022-08-25 23:31:20 +02:00
|
|
|
using UnityEngine;
|
2022-08-24 04:03:27 +02:00
|
|
|
using System.Collections;
|
|
|
|
using uWindowCapture;
|
|
|
|
using Unity.Netcode;
|
2022-08-25 23:31:20 +02:00
|
|
|
using Newtonsoft.Json.Linq;
|
2022-08-24 04:03:27 +02:00
|
|
|
|
|
|
|
public class WindowEncoder : NetworkBehaviour
|
|
|
|
{
|
|
|
|
[SerializeField]
|
|
|
|
public UwcWindowTexture texture = null;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
public uNvEncoder.Encoder encoder = null;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
public uNvEncoder.EncoderDesc setting = new uNvEncoder.EncoderDesc
|
|
|
|
{
|
|
|
|
width = 1920,
|
|
|
|
height = 1080,
|
|
|
|
frameRate = 24,
|
|
|
|
format = uNvEncoder.Format.B8G8R8A8_UNORM,
|
2022-08-25 23:31:20 +02:00
|
|
|
bitRate = 196608,
|
|
|
|
maxFrameSize = 8192,
|
2022-08-24 04:03:27 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
public int idrFrameIntervalFrame = 24;
|
|
|
|
int idrFrameCounter_ = 0;
|
|
|
|
public int ResolutionDivider = 2;
|
2022-08-25 23:31:20 +02:00
|
|
|
Texture2D sTexture;
|
2022-08-24 04:03:27 +02:00
|
|
|
|
|
|
|
void Start()
|
|
|
|
{
|
|
|
|
if (!IsOwner) return;
|
2022-08-25 23:31:20 +02:00
|
|
|
GetSetting();
|
2022-08-24 04:03:27 +02:00
|
|
|
StartCoroutine(EncodeLoop());
|
|
|
|
}
|
|
|
|
|
|
|
|
void OnDisable()
|
|
|
|
{
|
|
|
|
if (!IsOwner) return;
|
|
|
|
StopAllCoroutines();
|
|
|
|
encoder.Destroy();
|
|
|
|
}
|
2022-08-25 23:31:20 +02:00
|
|
|
void GetSetting()
|
|
|
|
{
|
|
|
|
if (JsonConfig.HasKey("EncoderSetting"))
|
|
|
|
{
|
|
|
|
var _setting = JsonConfig.GetJObject("EncoderSetting");
|
|
|
|
ResolutionDivider = _setting.Value<int>("ResolutionDivider");
|
|
|
|
_setting.Remove("ResolutionDivider");
|
|
|
|
setting = _setting.ToObject<uNvEncoder.EncoderDesc>();
|
|
|
|
}
|
|
|
|
|
|
|
|
SetSetting(setting, ResolutionDivider);
|
|
|
|
}
|
|
|
|
void SetSetting(uNvEncoder.EncoderDesc _setting, int resolutionDivider)
|
|
|
|
{
|
|
|
|
var JObj= JObject.FromObject(_setting);
|
|
|
|
JObj.Remove("width"); JObj.Remove("height");
|
|
|
|
JObj["ResolutionDivider"] = resolutionDivider;
|
|
|
|
JsonConfig.SetJObject("EncoderSetting", JObj);
|
|
|
|
}
|
2022-08-24 04:03:27 +02:00
|
|
|
|
|
|
|
RenderTexture rt;
|
|
|
|
void Resize()
|
|
|
|
{
|
|
|
|
Graphics.Blit(texture.window.texture, rt);
|
|
|
|
sTexture.ReadPixels(new Rect(0,0,setting.width, setting.height),0,0);
|
|
|
|
sTexture.Apply();
|
|
|
|
}
|
|
|
|
IEnumerator EncodeLoop()
|
|
|
|
{
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
if (texture.window != null) break;
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
}
|
|
|
|
|
|
|
|
setting.width = texture.window.width / ResolutionDivider;
|
|
|
|
setting.height = texture.window.height / ResolutionDivider;
|
|
|
|
encoder.Create(setting);
|
|
|
|
|
|
|
|
rt = new RenderTexture(setting.width, setting.height, 24);
|
|
|
|
sTexture = new Texture2D(setting.width, setting.height, TextureFormat.BGRA32, false);
|
|
|
|
RenderTexture.active = rt;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
if (setting.frameRate < 60)
|
|
|
|
{
|
|
|
|
yield return new WaitForSeconds(1f / setting.frameRate);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool idr = idrFrameCounter_++ % idrFrameIntervalFrame == 0;
|
|
|
|
Resize();
|
|
|
|
encoder.Encode(sTexture, idr);
|
|
|
|
encoder.Update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[ContextMenu("Reconfigure")]
|
|
|
|
public void Reconfigure()
|
|
|
|
{
|
|
|
|
if (encoder == null) return;
|
|
|
|
encoder.Reconfigure(setting);
|
|
|
|
}
|
|
|
|
}
|