using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using System.Collections.Generic;
namespace DownloadResources
{
internal class EduResDownloader
{
private static EduResDownloader _Instance = null;
private static readonly object locker = new object();
private readonly string serverUrl = "https://............";
private Dictionary cacheAudioClips = new Dictionary();
public static EduResDownloader Instance
{
get
{
if (_Instance == null)
{
lock (locker)
{
if (_Instance == null)
{
_Instance = new EduResDownloader();
}
}
}
return _Instance;
}
}
#region private methods
private EduResDownloader() { }
private void CheckAndCreateDirectory(string path)
{
string localPath = GetSaveLocalPathPre();
string str = path.Substring(localPath.LastIndexOf('/') + 1);
string[] strs = str.Split('/');
string itemPath = localPath;
for (int i = 0; i < strs.Length - 1; i++)
{
itemPath = Path.Combine(itemPath, strs[i]);
if (!Directory.Exists(itemPath))
{
Directory.CreateDirectory(itemPath);
}
}
}
private IEnumerator DownloadFromLocal(string url, System.Action callBack = null) where T : UnityEngine.Object
{
url = url.Replace("\\", "/");
string localPath = GetSaveLocalPathPre() + url;
if (File.Exists(localPath))
{
if (typeof(T) == typeof(Sprite))
{
yield return DownloadLocalSprite(url, (s) =>
{
if (callBack != null)
{
callBack(s as T);
}
});
}
else if (typeof(T) == typeof(Texture2D))
{
yield return DownloadLocalTexture2D(url, (s) =>
{
if (callBack != null)
{
callBack(s as T);
}
});
}
else if (typeof(T) == typeof(AudioClip))
{
yield return DownloadLocalAudioClip(url, (s) =>
{
if (callBack != null)
{
callBack(s as T);
}
});
}
else
{
Debug.LogError("Now do not support T = " + typeof(T).ToString());
}
}
}
private IEnumerator DownloadByUrl(string url, System.Action callBack = null) where T : UnityEngine.Object
{
url = url.Replace("\\", "/");
string localPath = GetSaveLocalPathPre() + url;
if (!File.Exists(localPath))
{
yield return DownloadFormServer(url);
}
yield return DownloadFromLocal(url, callBack);
}
private IEnumerator DownloadLocalSprite(string url, System.Action callBack = null)
{
string readLocalPath = GetReadLocalPathPre() + url;
UnityWebRequest webRequest = UnityWebRequest.Get(readLocalPath);
DownloadHandlerTexture handlerTexture = new DownloadHandlerTexture(true);
webRequest.downloadHandler = handlerTexture;
webRequest.timeout = 20;
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError || !string.IsNullOrEmpty(webRequest.error))
{
Debug.LogError("DownLocalSprite Error : " + webRequest.error + " url = " + readLocalPath);
}
else
{
Texture2D texture2D = null;
texture2D = handlerTexture.texture;
Sprite sprite = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), Vector2.one * 0.5f);
if (callBack != null)
{
callBack(sprite);
}
}
webRequest.Dispose();
}
private IEnumerator DownloadLocalTexture2D(string url, System.Action callBack = null)
{
string readLocalPath = GetReadLocalPathPre() + url;
UnityWebRequest webRequest = UnityWebRequest.Get(readLocalPath);
DownloadHandlerTexture handlerTexture = new DownloadHandlerTexture(true);
webRequest.downloadHandler = handlerTexture;
webRequest.timeout = 20;
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError || !string.IsNullOrEmpty(webRequest.error))
{
Debug.LogError("DownloadLocalTexture2D Error : " + webRequest.error + " url = " + readLocalPath);
}
else
{
Texture2D texture2D = null;
texture2D = handlerTexture.texture;
if (callBack != null)
{
callBack(texture2D);
}
}
webRequest.Dispose();
}
private IEnumerator DownloadLocalAudioClip(string url, System.Action callBack = null)
{
string readLocalPath = GetReadLocalPathPre() + url;
UnityWebRequest webRequest = UnityWebRequestMultimedia.GetAudioClip(readLocalPath, AudioType.MPEG);
webRequest.timeout = 20;
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError || !string.IsNullOrEmpty(webRequest.error))
{
Debug.LogError("DownloadLocalAudioClip Error : " + webRequest.error + " url = " + readLocalPath);
}
else
{
AudioClip audioClip = DownloadHandlerAudioClip.GetContent(webRequest);
if (callBack != null)
{
callBack(audioClip);
}
}
webRequest.Dispose();
}
private string GetSaveLocalPathPre()
{
return Application.persistentDataPath + "/";
}
private string GetReadLocalPathPre()
{
string path =
#if UNITY_EDITOR
"file:///" + Application.persistentDataPath + "/";
#elif UNITY_ANDROID
"file://" + Application.persistentDataPath + "/";
#else
"file:///" + Application.persistentDataPath + "/";
#endif
return path;
}
#endregion
#region public methods
///
/// 下载阿里云资源或从本地沙盒
///
///
/// 路径加文件名
/// 下载完回调
public IEnumerator LoadResByUrl(string url, System.Action callBack = null) where T : UnityEngine.Object
{
yield return DownloadByUrl(url, callBack);
}
public IEnumerator DownloadFormServer(string url, System.Action callBack = null)
{
url = url.Replace("\\", "/");
string localPath = GetSaveLocalPathPre() + url;
if (File.Exists(localPath))
{
if (callBack != null)
{
callBack(true);
}
yield break;
}
string serverPath = serverUrl + url;
UnityWebRequest webRequest = UnityWebRequest.Get(serverPath);
webRequest.timeout = 20;
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError || !string.IsNullOrEmpty(webRequest.error))
{
Debug.LogError("DownloadFormServer NetworkError : " + webRequest.error + " url = " + serverPath);
if (callBack != null)
{
callBack(false);
}
}
else
{
var file = webRequest.downloadHandler.data;
CheckAndCreateDirectory(localPath);
//try
//{
// FileStream fileStream = new FileStream(localPath, FileMode.Create);
// fileStream.Write(file, 0, file.Length);
// fileStream.Flush();
// fileStream.Close();
//}
//catch (System.Exception e)
//{
// Debug.Log(e.ToString());
//}
File.WriteAllBytes(localPath, file);
if (callBack != null)
{
callBack(true);
}
}
webRequest.Dispose();
}
public IEnumerator CacheAudioClip(string url)
{
url = url.Replace("\\", "/");
yield return DownloadLocalAudioClip(url, (clip) =>
{
cacheAudioClips[url] = clip;
});
}
public AudioClip LoadAudioClip(string url)
{
url = url.Replace("\\", "/");
AudioClip audioClip;
if (cacheAudioClips.TryGetValue(url, out audioClip))
{
return audioClip;
}
return null;
}
public void Destroy()
{
cacheAudioClips.Clear();
_Instance = null;
}
#endregion
}
}