194 lines
5.7 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|