Files
monde-usage-unity/Assets/Scripts/VideoDownloader.cs
2024-10-09 20:42:46 +02:00

230 lines
5.7 KiBLFS
C#

using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using System.Threading.Tasks;
using System.Linq;
using System;
using Unity.VisualScripting;
public static class VideoPlayManager
{
public static Dictionary<VideoAsset, int> PlayCounts = new();
public static int TotalVideoPlays
{
get
{
int total = 0;
foreach (var video in PlayCounts)
{
total += video.Value;
}
return total;
}
}
public static void RegisterPlay(VideoAsset videoAsset)
{
if (PlayCounts.ContainsKey(videoAsset))
{
PlayCounts[videoAsset]++;
}
else
{
PlayCounts[videoAsset] = 1;
}
}
public static void Reset()
{
PlayCounts = new Dictionary<VideoAsset, int>();
}
public static int GetPlayCount(VideoAsset videoAsset)
{
if (PlayCounts.ContainsKey(videoAsset))
{
return PlayCounts[videoAsset];
}
return 0;
}
}
public class VideoDownloader : MonoBehaviour
{
[SerializeField] private List<VideoAsset> videoAssets;
public List<VideoAsset> VideoAssets => videoAssets;
[SerializeField] private int downloadsInParallel = 4; // Number of parallel downloads
// private List<VideoAsset> videosToDownload = new();
private System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
[SerializeField] private bool downloadInParallel = false;
private
void Start()
{
videoAssets.ForEach(video => { video.Init(); });
StartCoroutine(DownloadVideos());
onStartDownload += () =>
{
CanvasManager.singleton.loadingScreen.Show(videosToDownload.Count);
Debug.Log($"Downloading {videosToDownload.Count} videos to {Application.persistentDataPath} {(downloadInParallel ? "in parallel" : "sequentially")}");
stopwatch.Start();
};
onDownloadComplete += () =>
{
stopwatch.Stop();
Debug.Log($"Downloaded {videosToDownload.Count} videos in {stopwatch.Elapsed.TotalSeconds} seconds.");
CanvasManager.singleton.loadingScreen.Hide();
};
ProgressCallBack += (int downloaded, int total) =>
{
CanvasManager.singleton.loadingScreen.ProgressCallback(downloaded, total);
};
}
[SerializeField] private List<VideoAsset> videosToDownload = new();
private void ComputeVideosToDownload()
{
videosToDownload = videoAssets
.Where(video => video.NeedDownloading).ToList();
}
public int NewVideosToDownloadCount => videosToDownload.Count;
public void ReDownloadVideos()
{
StartCoroutine(DownloadVideos());
}
public Action onStartDownload;
public Action onDownloadComplete;
private IEnumerator DownloadVideos()
{
ComputeVideosToDownload();
yield return new WaitForSeconds(0.5f);
if (videosToDownload.Count == 0)
{
Debug.Log("No videos to download!");
CanvasManager.singleton.loadingScreen.Hide();
yield break;
}
//CanvasManager.singleton.loadingScreen.Show(videosToDownload.Count);
onStartDownload?.Invoke();
yield return downloadInParallel ? DownloadVideosParallel() : DownloadVideosSeq();
onDownloadComplete?.Invoke();
}
public Dictionary<VideoAsset, int> PlayCounts = new();
public void RegisterPlayVideo(VideoAsset videoAsset)
{
if (PlayCounts.ContainsKey(videoAsset))
{
PlayCounts[videoAsset]++;
}
else
{
PlayCounts[videoAsset] = 1;
}
}
private IEnumerator DownloadVideosParallel()
{
// Start the downloads in parallel
List<Task> downloadTasks = new List<Task>();
int i = 0;
for (i = 0; i < downloadsInParallel && i < videosToDownload.Count; i++)
downloadTasks.Add(DownloadVideoTask(videosToDownload[i]));
int downloaded = 0;
// Monitor progress and add new downloads as previous ones complete
while (i - downloadTasks.Count < videosToDownload.Count)
{
for (int j = 0; j < downloadTasks.Count; j++)
{
if (downloadTasks[j].IsCompleted)
{
downloaded++;
Debug.Log($"Downloaded {downloaded}/{videosToDownload.Count} videos.");
ProgressCallBack.Invoke(downloaded, videosToDownload.Count);
// Start the next video download if available
if (i < videosToDownload.Count)
{
downloadTasks[j] = DownloadVideoTask(videosToDownload[i]);
i++;
}
}
}
// Remove completed tasks
downloadTasks.RemoveAll(task => task.IsCompleted);
yield return new WaitForSeconds(0.3f); // Wait a bit before checking again
}
}
private async Task DownloadVideoTask(VideoAsset videoAsset)
{
videoAsset.Prepare();
while (videoAsset.Loading)
{
await Task.Yield();
await Task.Delay(500);
}
}
private IEnumerator DownloadVideosSeq()
{
int i = 0;
// Process each video download sequentially
while (i < videosToDownload.Count)
{
Debug.Log($"Starting download for video {i + 1}/{videosToDownload.Count}");
// Wait for the current video to be downloaded
yield return DownloadVideoSeq(videosToDownload[i]);
Debug.Log($"Downloaded video {i + 1}/{videosToDownload.Count}");
i++;
ProgressCallBack.Invoke(i, videosToDownload.Count);
}
}
public Action<int, int> ProgressCallBack { get; set; }
private IEnumerator DownloadVideoSeq(VideoAsset videoAsset)
{
videoAsset.Prepare();
// Wait until the video is fully loaded
while (videoAsset.Loading) yield return null; // Wait until next frame
}
public void FirebaseStorageWebCallback(string response)
{
FirebaseFileDownloader.DownloadFileCallback(response);
}
public void FirebaseStorageWebFallback(string response)
{
FirebaseFileDownloader.DownloadFileFallback(response);
}
}