237 lines
5.7 KiB
C#
237 lines
5.7 KiB
C#
using Godot;
|
|
using System;
|
|
using System.Timers;
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
namespace BITKit;
|
|
|
|
/// <summary>
|
|
/// 默认的String数据播放器,主要应用于播放json
|
|
/// </summary>
|
|
public partial class DataPlayer : Node
|
|
{
|
|
//参数
|
|
/// <summary>
|
|
/// 当前帧
|
|
/// </summary>
|
|
[Export]
|
|
public int CurrentFrame
|
|
{
|
|
get => _currentFrame;
|
|
set => _currentFrame = Math.Clamp(value, 0, Values?.Length-1 ?? 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 播放帧率
|
|
/// </summary>
|
|
[Export] private int frameRate = 60;
|
|
|
|
[Export] private string timeFormat="mm:ss:fff";
|
|
|
|
/// <summary>
|
|
/// 基于帧率的每帧播放数据
|
|
/// </summary>
|
|
[Signal]
|
|
public delegate void OnProcessPlayEventHandler(string value);
|
|
|
|
/// <summary>
|
|
/// 开始播放回调
|
|
/// </summary>
|
|
[Signal]
|
|
public delegate void OnPlayEventHandler();
|
|
|
|
/// <summary>
|
|
/// 停止播放回调
|
|
/// </summary>
|
|
[Signal]
|
|
public delegate void OnStopEventHandler();
|
|
|
|
/// <summary>
|
|
/// 暂停回调
|
|
/// </summary>
|
|
[Signal]
|
|
public delegate void OnPauseEventHandler();
|
|
|
|
/// <summary>
|
|
/// 播放和暂停回调
|
|
/// </summary>
|
|
[Signal]
|
|
public delegate void OnPlayOrPauseEventHandler(bool isPlaying);
|
|
|
|
/// <summary>
|
|
/// 设置总播放时间的回调
|
|
/// </summary>
|
|
[Signal]
|
|
public delegate void OnSetTotalTimeEventHandler(string dateTimeString);
|
|
|
|
/// <summary>
|
|
/// 设置当前播放时间的回调
|
|
/// </summary>
|
|
[Signal]
|
|
public delegate void OnSetPlaybackTimeEventHandler(string dateTimeString);
|
|
|
|
/// <summary>
|
|
/// 设置标准化播放时间的回调
|
|
/// </summary>
|
|
[Signal]
|
|
public delegate void OnSetNormalizeTimeEventHandler(double normalizeTime);
|
|
|
|
/// <summary>
|
|
/// 是否正在播放
|
|
/// </summary>
|
|
public bool IsPlaying { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// 是否已暂停播放
|
|
/// </summary>
|
|
public bool IsPaused { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// 内部计时器
|
|
/// </summary>
|
|
private readonly System.Timers.Timer timer = new();
|
|
|
|
/// <summary>
|
|
/// 内部数组
|
|
/// </summary>
|
|
private string[] Values;
|
|
|
|
//内部当前帧
|
|
private int _currentFrame;
|
|
|
|
public override void _Ready()
|
|
{
|
|
timer.Elapsed += Play;
|
|
EmitSignal(nameof(OnStop));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 播放
|
|
/// </summary>
|
|
/// <param name="values">播放数据的数组</param>
|
|
public bool Play(string[] values)
|
|
{
|
|
if (values?.Length is 0) return false;
|
|
if (values?.Length != Values?.Length)
|
|
{
|
|
CurrentFrame = 0;
|
|
}
|
|
|
|
Values = values;
|
|
timer.Interval = TimeSpan.FromSeconds(1f / frameRate).Milliseconds;
|
|
Play();
|
|
timer.Start();
|
|
|
|
var totalTime = new DateTime().AddSeconds((float)Values!.Length / frameRate);
|
|
EmitSignal(nameof(OnSetTotalTime), totalTime.ToString(timeFormat));
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 播放(在暂停时)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool Play()
|
|
{
|
|
IsPaused = false;
|
|
IsPlaying = true;
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止播放
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool Stop()
|
|
{
|
|
if (!IsPlaying) return false;
|
|
timer.Stop();
|
|
IsPlaying = IsPaused = false;
|
|
EmitSignal(nameof(OnStop));
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 暂停播放
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool Pause()
|
|
{
|
|
if (!IsPlaying) return false;
|
|
IsPaused = true;
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 继续播放或暂停播放
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public void PlayOrPause()
|
|
{
|
|
PlayOrPause(!IsPaused);
|
|
}
|
|
|
|
public void PlayOrPause(bool play)
|
|
{
|
|
IsPaused = !play;
|
|
EmitSignal(nameof(OnPlayOrPause), play);
|
|
}
|
|
//设置标准化播放时间(0-1进度)
|
|
public void SetNormalizeTime(float normalizeTime)
|
|
{
|
|
CurrentFrame = (int)(Values.Length * normalizeTime);
|
|
Process(CurrentFrame);
|
|
}
|
|
|
|
public void SetNormalizeTimeThen(float normalizeTime, bool play)
|
|
{
|
|
SetNormalizeTime(normalizeTime);
|
|
PlayOrPause(play);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
timer.Stop();
|
|
timer.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 内部调用方法
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
protected virtual async void Play(object sender, ElapsedEventArgs e)
|
|
{
|
|
//等待返回主线程
|
|
await UniTask.SwitchToSynchronizationContext(BITApp.SynchronizationContext);
|
|
|
|
if (IsPaused) return;
|
|
|
|
//如果超过了播放长度,停止播放
|
|
if (CurrentFrame >= Values?.Length-1)
|
|
{
|
|
Stop();
|
|
return;
|
|
}
|
|
EmitSignal(nameof(OnPlay));
|
|
Process(CurrentFrame++);
|
|
}
|
|
|
|
private void Process(int currentFrame)
|
|
{
|
|
//获取当前播放信息
|
|
var current = Values?[currentFrame];
|
|
var currentNormalizeTime = (float)CurrentFrame / Values!.Length;
|
|
var currentTime = new DateTime().AddSeconds((float)CurrentFrame / frameRate);
|
|
|
|
//调用信号
|
|
EmitSignal(nameof(OnProcessPlay), current);
|
|
EmitSignal(nameof(OnSetPlaybackTime), currentTime.ToString(timeFormat));
|
|
EmitSignal(nameof(OnSetNormalizeTime), currentNormalizeTime);
|
|
|
|
//设置Meta
|
|
SetMeta(nameof(OnProcessPlay),current);
|
|
SetMeta(nameof(OnSetNormalizeTime),currentNormalizeTime);
|
|
}
|
|
}
|