feat:1、添加项目
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BallKingdomCrush;
|
||||
using FairyGUI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Video;
|
||||
|
||||
internal class VideoLoadTask
|
||||
{
|
||||
public Coroutine coroutine;
|
||||
public string fileName;
|
||||
public bool isCancelled;
|
||||
public GLoader loader;
|
||||
public Action<VideoPlayer> onComplete;
|
||||
public bool play;
|
||||
public VideoPlayer player;
|
||||
|
||||
// loader 绑定的任务 ID
|
||||
public string taskId;
|
||||
}
|
||||
|
||||
internal class VideoLoadScheduler
|
||||
{
|
||||
private const int MaxConcurrent = 6; // 同时加载任务数
|
||||
private static readonly Queue<VideoLoadTask> taskQueue = new();
|
||||
private static readonly List<VideoLoadTask> runningTasks = new();
|
||||
|
||||
/// <summary>
|
||||
/// 入队视频加载任务
|
||||
/// </summary>
|
||||
public static void EnqueueLoad(VideoPlayer player, string fileName, GLoader loader, Action<VideoPlayer> onComplete, bool play = true)
|
||||
{
|
||||
// 🔑 检查重复任务
|
||||
bool isDuplicate = taskQueue.Any(t => t.fileName == fileName && t.loader == loader && !t.isCancelled);
|
||||
|
||||
if (isDuplicate)
|
||||
{
|
||||
Debug.LogWarning($"[VideoScheduler] 跳过重复任务: {fileName}, loader={loader.name}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成唯一 taskId,绑定到 loader
|
||||
var taskId = Guid.NewGuid().ToString();
|
||||
loader.SetData(taskId);
|
||||
|
||||
var task = new VideoLoadTask
|
||||
{
|
||||
fileName = fileName,
|
||||
loader = loader,
|
||||
onComplete = onComplete,
|
||||
play = play,
|
||||
player = player,
|
||||
taskId = taskId
|
||||
};
|
||||
|
||||
taskQueue.Enqueue(task);
|
||||
Debug.Log($"[VideoScheduler] 入队视频: {fileName}, taskId={taskId}, queueCount={taskQueue.Count}");
|
||||
|
||||
TryStartNext();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 尝试启动队列中的任务
|
||||
/// </summary>
|
||||
private static void TryStartNext()
|
||||
{
|
||||
Debug.Log($"[VideoScheduler] TryStartNext 调用,queue={taskQueue.Count}, running={runningTasks.Count}");
|
||||
|
||||
while (taskQueue.Count > 0 && runningTasks.Count < MaxConcurrent)
|
||||
{
|
||||
var task = taskQueue.Dequeue();
|
||||
|
||||
if (task.isCancelled)
|
||||
{
|
||||
Debug.Log($"[VideoScheduler] 跳过已取消任务: {task.fileName}, taskId={task.taskId}");
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Log($"[VideoScheduler] 启动任务: {task.fileName}, taskId={task.taskId}");
|
||||
var co = CrazyAsyKit.StartCoroutine(LoadVideoToPlayer(task.player, task));
|
||||
task.coroutine = co;
|
||||
runningTasks.Add(task);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 协程加载视频
|
||||
/// </summary>
|
||||
private static IEnumerator LoadVideoToPlayer(VideoPlayer player, VideoLoadTask task)
|
||||
{
|
||||
Debug.Log($"[VideoScheduler] 开始加载视频: {task.fileName}, taskId={task.taskId}");
|
||||
|
||||
var callbackTriggered = false;
|
||||
|
||||
yield return LiveVideoManager.LoadVideoToPlayer(player, task.fileName, task.loader, vp =>
|
||||
{
|
||||
callbackTriggered = true;
|
||||
Debug.Log(
|
||||
$"[VideoScheduler] 回调触发: {task.fileName}, loader taskId={task.loader.GetData()}, current taskId={task.taskId}");
|
||||
|
||||
if (task.loader.GetData() != task.taskId)
|
||||
{
|
||||
Debug.Log($"[VideoScheduler] 任务被覆盖,丢弃: {task.fileName}, taskId={task.taskId}");
|
||||
}
|
||||
else if (task.isCancelled)
|
||||
{
|
||||
Debug.Log($"[VideoScheduler] 任务被取消: {task.fileName}, taskId={task.taskId}");
|
||||
if (vp != null) vp.Stop();
|
||||
task.onComplete?.Invoke(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"[VideoScheduler] 任务完成: {task.fileName}, taskId={task.taskId}");
|
||||
task.onComplete?.Invoke(vp);
|
||||
}
|
||||
|
||||
runningTasks.Remove(task);
|
||||
Debug.Log($"[VideoScheduler] 移除任务,剩余: {runningTasks.Count}");
|
||||
TryStartNext();
|
||||
}, task.play);
|
||||
|
||||
// 🔴 兜底:防止 TextureHelper 出错导致回调不触发
|
||||
if (!callbackTriggered)
|
||||
{
|
||||
Debug.LogWarning($"[VideoScheduler] ⚠️ 没有回调就结束了,强制移除任务: {task.fileName}, taskId={task.taskId}");
|
||||
runningTasks.Remove(task);
|
||||
TryStartNext();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消某个任务
|
||||
/// </summary>
|
||||
public static void CancelTask(VideoLoadTask task)
|
||||
{
|
||||
if (task == null) return;
|
||||
task.isCancelled = true;
|
||||
if (task.coroutine != null)
|
||||
CrazyAsyKit.StopCoroutine(task.coroutine);
|
||||
|
||||
if (runningTasks.Remove(task))
|
||||
Debug.Log($"[VideoScheduler] 取消并移除任务: {task.fileName}, taskId={task.taskId}");
|
||||
|
||||
TryStartNext();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有任务
|
||||
/// </summary>
|
||||
public static void ClearAll()
|
||||
{
|
||||
foreach (var task in runningTasks)
|
||||
CancelTask(task);
|
||||
|
||||
taskQueue.Clear();
|
||||
runningTasks.Clear();
|
||||
Debug.Log("[VideoScheduler] 所有任务已清理");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扩展方法:GLoader 绑定当前任务 ID
|
||||
/// </summary>
|
||||
public static class GLoaderExtensions
|
||||
{
|
||||
private static readonly Dictionary<GLoader, string> loaderTaskMap = new();
|
||||
|
||||
public static void SetData(this GLoader loader, string taskId)
|
||||
{
|
||||
loaderTaskMap[loader] = taskId;
|
||||
}
|
||||
|
||||
public static string GetData(this GLoader loader)
|
||||
{
|
||||
if (loaderTaskMap.TryGetValue(loader, out var taskId))
|
||||
return taskId;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user