using UnityEngine;
using System.Collections;
//-----------------------------------------------------------------------------
// Copyright 2012-2022 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProMovieCapture.Demos
{
///
/// Allows the user to select from a list of webcams and creates a capture instance for the webcam recording.
/// Currently only a single webcam can be captured at once.
///
public class WebcamCaptureDemo : MonoBehaviour
{
#pragma warning disable 0414 // x is assigned but its value is never used
[SerializeField] GUISkin _skin = null;
[SerializeField] GameObject _prefab = null;
[SerializeField] int _webcamResolutionWidth = 640;
[SerializeField] int _webcamResolutionHeight = 480;
[SerializeField] int _webcamFrameRate = 30;
#pragma warning restore 0414
#if AVPRO_MOVIECAPTURE_WEBCAMTEXTURE_SUPPORT
private class Instance
{
public string name;
public WebCamTexture texture;
public CaptureFromWebCamTexture capture;
public CaptureGUI gui;
}
// State
private Instance[] _instances;
private int _selectedWebcamIndex = -1;
private IEnumerator Start()
{
// Make sure we're authorised for using the camera. On iOS the OS will forcibly
// close the application if authorisation has not been granted. Make sure the
// "Camera Usage Description" field has been filled in the player settings.
// This needs to be done first otherwise no cameras will be reported.
if (!Application.HasUserAuthorization(UserAuthorization.WebCam))
{
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
}
// Make sure we're authorised for using the microphone. On iOS the OS will forcibly
// close the application if authorisation has not been granted. Make sure the
// "Microphone Usage Description" field has been filled in the player settings.
// if (_capture.AudioCaptureSource == AudioCaptureSource.Microphone)
{
if (!Application.HasUserAuthorization(UserAuthorization.Microphone))
{
yield return Application.RequestUserAuthorization(UserAuthorization.Microphone);
}
if (Application.HasUserAuthorization(UserAuthorization.Microphone))
{
// On iOS modified the audio session to allow recording from the microphone.
NativePlugin.SetMicrophoneRecordingHint(true);
}
}
// Create instance data per webcam
int numCams = WebCamTexture.devices.Length;
_instances = new Instance[numCams];
GameObject go = this.gameObject;
Instance instance = new Instance();
instance.name = WebCamTexture.devices[0].name;
instance.capture = go.GetComponent();
instance.capture.FilenamePrefix = "Demo4Webcam-" + 0;
//instance.gui = go.GetComponent();
//instance.gui.ShowUI = false;
_instances[0] = instance;
if (numCams > 0)
{
SelectWebcam(0);
}
}
private void StartWebcam(Instance instance)
{
// NOTE: WebcamTexture can be slow for high resolutions, this can cause issues with audio-video sync.
// Our plugins AVPro Live Camera or AVPro DeckLink can be used to capture high resolution devices
#if UNITY_2018_4_OR_NEWER
Debug.Log($"_webcamResolutionWidth: {_webcamResolutionWidth}, _webcamResolutionHeight: {_webcamResolutionHeight}, _webcamFrameRate: {_webcamFrameRate}");
#endif
instance.texture = new WebCamTexture(instance.name, _webcamResolutionWidth, _webcamResolutionHeight, _webcamFrameRate);
instance.texture.Play();
if (instance.texture.isPlaying)
{
instance.capture.WebCamTexture = instance.texture;
Debug.Log(string.Format("Running webcam in mode {0}x{1}", instance.texture.width, instance.texture.height));
}
else
{
Debug.Log(string.Format("Unable to start webcam in mode {0}x{1}@{2}", _webcamResolutionWidth, _webcamResolutionHeight, _webcamFrameRate));
StopWebcam(instance);
}
}
private void StopWebcam(Instance instance)
{
if (instance.texture != null)
{
if (instance.capture != null && instance.capture.IsCapturing())
{
instance.capture.WebCamTexture = null;
instance.capture.StopCapture();
}
instance.texture.Stop();
Destroy(instance.texture);
instance.texture = null;
}
_selectedWebcamIndex = -1;
}
private void OnDestroy()
{
for (int i = 0; i < _instances.Length; i++)
{
StopWebcam(_instances[i]);
}
}
private void SelectWebcam(int index)
{
// Stop any currently
if (_selectedWebcamIndex >= 0)
{
StopWebcam(_instances[_selectedWebcamIndex]);
_selectedWebcamIndex = -1;
}
if (index >= 0)
{
_selectedWebcamIndex = index;
for (int j = 0; j < _instances.Length; j++)
{
// _instances[j].gui.ShowUI = (j == _selectedWebcamIndex);
}
StartWebcam(_instances[_selectedWebcamIndex]);
}
}
private void OnGUI()
{
GUI.skin = _skin;
GUILayout.BeginArea(new Rect(Screen.width - 512, 0, 512, Screen.height));
GUILayout.BeginVertical();
GUILayout.Label("Select webcam:");
for (int i = 0; i < _instances.Length; i++)
{
Instance webcam = _instances[i];
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
if (webcam.capture.IsCapturing())
{
float t = Mathf.PingPong(Time.timeSinceLevelLoad, 0.25f) * 4f;
GUI.backgroundColor = Color.Lerp(GUI.backgroundColor, Color.white, t);
GUI.color = Color.Lerp(Color.red, Color.white, t);
}
if (_selectedWebcamIndex == i)
{
GUI.backgroundColor = Color.green;
}
if (GUILayout.Button(webcam.name, GUILayout.Width(200), GUILayout.ExpandWidth(true)))
{
if (_selectedWebcamIndex != i)
{
SelectWebcam(i);
}
else
{
StopWebcam(webcam);
}
}
GUI.backgroundColor = Color.white;
GUI.color = Color.white;
if (webcam.texture != null)
{
Rect camRect = GUILayoutUtility.GetRect(256, 256.0f / (webcam.texture.width / (float)webcam.texture.height));
GUI.DrawTexture(camRect, webcam.texture);
}
else
{
GUILayout.Label(string.Empty, GUILayout.MinWidth(256.0f), GUILayout.MaxWidth(256.0f), GUILayout.ExpandWidth(false));
}
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
GUILayout.EndArea();
}
#else
void Start()
{
Debug.LogError("[AVProMovieCapture] To use WebCamTexture capture component/demo you must add the string AVPRO_MOVIECAPTURE_WEBCAMTEXTURE_SUPPORT must be added to `Scriping Define Symbols` in `Player Settings > Other Settings > Script Compilation`");
}
#endif // AVPRO_MOVIECAPTURE_WEBCAMTEXTURE_SUPPORT
}
}