batteryDiagnosis/Assets/3rdParty/FFmpegPlayer/Scripts/FFmpegPlayerBasicRawImage.cs

194 lines
5.7 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading.Tasks;
using UnityEngine.EventSystems;
namespace Hanatric.Unity.Video.FFmpegPlayer
{
[RequireComponent(typeof(RawImage))]
public class FFmpegPlayerBasicRawImage : FFmpegPlayerMono, IPointerDownHandler
{
private RawImage rawimage;
public Image mask;
public Image loading;
public Text text;
public InputField input;
public Func<Task<string>> GetConnectUrl;
public Color inactiveColor = Color.clear;
public bool autoReconnect = true;
public float frameUpdateTimeTimeout = 2;
public float reconnectWaitTime = 5;
public bool loop = false;
private float reconnectWaitTimeRemain;
private float frameUpdateTimeTimeoutRemain;
private string exceptionMsg;
private string info;
private bool refreshInfo = false;
private Material mat;
private void Awake()
{
rawimage = GetComponent<RawImage>();
mat = rawimage.material;
reconnectWaitTimeRemain = float.MaxValue;
frameUpdateTimeTimeoutRemain = float.MaxValue;
input.onEndEdit.AddListener((s) =>
{
input.gameObject.SetActive(false);
});
}
protected override void Update()
{
base.Update();
HandleExceptionMsg();
rawimage.color = rawimage.texture ? Color.white : inactiveColor;
rawimage.material = rawimage.texture ? mat : null;
loading.transform.Rotate(0, 0, -300 * Time.deltaTime);
if (refreshInfo)
{
refreshInfo = false;
info = info.Substring(0, info.Length > 2000 ? 2000 : info.Length);
input.text = info;
}
}
protected override void BeforeOpenCall()
{
base.BeforeOpenCall();
exceptionMsg = "";
reconnectWaitTimeRemain = float.MaxValue;
text.text = "正在加载/连接";
info = $"[Info] Url:{Url}" + "\r\n" + info;
}
private void HandleExceptionMsg()
{
if (!string.IsNullOrWhiteSpace(exceptionMsg))
{
text.text = exceptionMsg;
exceptionMsg = "";
mask.gameObject.SetActive(true);
if (reconnectWaitTimeRemain > reconnectWaitTime)
{
reconnectWaitTimeRemain = reconnectWaitTime;
}
}
if (reconnectWaitTimeRemain <= reconnectWaitTime)
{
reconnectWaitTimeRemain -= Time.deltaTime;
}
if (reconnectWaitTimeRemain < 0)
{
reconnectWaitTimeRemain = float.MaxValue;
if (autoReconnect)
{
text.text = "正在重新加载/连接";
DoReconnect();
}
}
frameUpdateTimeTimeoutRemain -= Time.deltaTime;
if (frameUpdateTimeTimeoutRemain < 0)
{
mask.gameObject.SetActive(true);
}
}
private async void DoReconnect()
{
if (GetConnectUrl != null)
{
string url = await Task.Run(GetConnectUrl);
Url = url;
}
Reconnect();
}
protected override void OnTextureCreatedFunc(Texture2D texture)
{
base.OnTextureCreatedFunc(texture);
rawimage.texture = texture;
}
public override void OnVideoOpenedInThread()
{
base.OnVideoOpenedInThread();
info = $"[Info] Width:{Width},Height:{Height},FPStime:{FrameRateFTime}" + "\r\n" + info;
refreshInfo = true;
}
public override void OnExceptionInThread(FFmpegLibMsg msg, int decoderIndex)
{
base.OnExceptionInThread(msg, decoderIndex);
if (msg == FFmpegLibMsg.UrlOpenException)
{
exceptionMsg = "无法连接或连接超时";
}
if (msg == FFmpegLibMsg.UrlBlank || msg == FFmpegLibMsg.UrlError)
{
exceptionMsg = "URL格式错误";
}
if (msg == FFmpegLibMsg.UrlFileNotExist)
{
exceptionMsg = "文件不存在";
}
if (msg == FFmpegLibMsg.EOF)
{
exceptionMsg = "EOF 流终止";
if (loop)
{
reconnectWaitTimeRemain = -1;
}
}
if (msg == FFmpegLibMsg.ReadTimeout)
{
exceptionMsg = "流读取超时";
}
if (msg == FFmpegLibMsg.DecoderOverNum)
{
exceptionMsg = "打开失败";
reconnectWaitTimeRemain = 0.5f;
}
Debug.Log("[Exception] " + msg.Message + " " + Url);
info = "[Exception] " + msg.Message + "\r\n" + info;
refreshInfo = true;
}
protected override void OnTextureRefreshedFunc(Texture2D texture)
{
base.OnTextureRefreshedFunc(texture);
frameUpdateTimeTimeoutRemain = frameUpdateTimeTimeout;
mask.gameObject.SetActive(false);
}
public override void Stop()
{
base.Stop();
reconnectWaitTimeRemain = float.MaxValue;
exceptionMsg = "";
}
public void OnPointerDown(PointerEventData eventData)
{
if (Input.GetMouseButtonDown(1))
{
input.gameObject.SetActive(true);
input.Select();
}
}
}
}