我正在创建一个可以播放30分钟视频的Gear VR安卓应用。我已经读过我不应该使用StreamingAssets文件夹,但是我没有看到任何有关我应该使用的信息。如果我把视频放在资产/视频中,它不包含在android版本中。我应该使用资源文件夹还是有其他方式来包含视频? (我的项目也在iOS上,但我目前在该平台上没有任何问题。)
我已经读过可以使用PersistentDataPath文件夹了,但是我不知道如何在统一时将我的视频放到该文件夹中。我不想在那里复制视频,只使用一个时有两个600mb的文件。
答案 0 :(得分:0)
巨大的文件可能需要很长时间才能提取和复制,有时甚至是它们 甚至可能导致设备耗尽存储空间或内存
这是事实但你必须知道你在做什么。您不能仅使用WWW
API或只使用File.Copy
/ File.WriteAllBytes
功能复制文件。
1 。以块的形式复制视频然后播放。这消除了内存不足的问题。
bool copyLargeVideoToPersistentDataPath(string videoNameWithExtensionName)
{
string path = Path.Combine(Application.streamingAssetsPath, videoNameWithExtensionName);
string persistentPath = Path.Combine(Application.persistentDataPath, "Videos");
persistentPath = Path.Combine(persistentPath, videoNameWithExtensionName);
bool success = true;
try
{
using (FileStream fromFile = new FileStream(path, FileMode.Open, FileAccess.Read))
{
using (FileStream toFile = new FileStream(persistentPath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
byte[] buffer = new byte[32 * 1024];
int bytesRead;
while ((bytesRead = fromFile.Read(buffer, 0, buffer.Length)) != 0)
{
toFile.Write(buffer, 0, bytesRead);
}
Debug.Log("Done! Saved to Dir: " + persistentPath);
Debug.Log(videoNameWithExtensionName + " Successfully Copied Video to " + persistentPath);
text.text = videoNameWithExtensionName + " Successfully Copied Video to " + persistentPath;
}
}
}
catch (Exception e)
{
Debug.Log(videoNameWithExtensionName + " Failed To Copy Video. Reason: " + e.Message);
text.text = videoNameWithExtensionName + " Failed To Copy Video. Reason: " + e.Message;
success = false;
}
return success;
}
我不想在那里复制视频,并且有两个600mb文件 只使用了一个。
您还有其他选择:
<强> 2 即可。 Resources文件夹。 (不推荐)因为这会减慢你的游戏加载时间。值得一提。使用新的Unity VideoPlayer
,您可以加载以下视频:
VideoClip video = Resources.Load("videoFile", typeof(VideoClip)) as VideoClip;
这不需要AVPro插件,Unity中不再需要它。
如果您想要的话,也可以将Resources文件夹与AVPro插件一起使用。
只需将视频扩展名更改为.bytes
,然后将其加载为字节。如果AVPro插件可以播放视频作为字节,那么你去吧!
TextAsset txtAsset = (TextAsset)Resources.Load("videoFile", typeof(TextAsset));
byte[] videoFile = txtAsset.bytes;
3 。使用AssetBundle加载视频。新的Video API问世以来,现在不支持这种做法,但现在应该得到支持了。
IEnumerable LoadObject(string path)
{
AssetBundleCreateRequest bundle = AssetBundle.LoadFromFileAsync(path);
yield return bundle;
AssetBundle myLoadedAssetBundle = bundle.assetBundle;
if (myLoadedAssetBundle == null)
{
Debug.Log("Failed to load AssetBundle!");
yield break;
}
AssetBundleRequest request = myLoadedAssetBundle.LoadAssetAsync<GameObject>("VideoFile");
yield return request;
VideoClip clip = request.asset as VideoClip;
}
4 。最后,使用StreamingAssets
文件夹但不是复制视频,而是使用HttpListener
创建本地服务器并将其指向StreamingAssets
路径。
现在,使用新的VideoPlayer
与之关联并播放视频。您可以在stackoverflow上找到许多HttpListener
服务器的示例。 我在过去做过这件事并且有效。
答案 1 :(得分:0)
我发现这是一种下载文件并将其保存到PersistantDataPath的方法。 http://answers.unity3d.com/questions/322526/downloading-big-files-on-ios-www-will-give-out-of.html
我看到的一个问题是,如果应用程序暂停了。 (以关闭耳机为例。)下载失败。使用650MB文件时,基本上所有用户都可能会这样做。你知道如何在统一暂停时保持下载速度吗?我还要发一篇关于此事的新帖子。
答案 2 :(得分:0)
以下是我现在要使用的代码。
void DownloadFile()
{
loadingBar.gameObject.SetActive(true);
downloadButton.SetActive(false);
downloadingFile = true;
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(DownloadFileCompleted);
client.DownloadFileAsync(new Uri(url), Application.persistentDataPath + "/" + fileName);
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
downloadProgressText = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive;
downloadProgress = int.Parse(Math.Truncate(percentage).ToString());
totalBytes = e.TotalBytesToReceive;
bytesDownloaded = e.BytesReceived;
}
void DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
if (e.Error == null)
{
AllDone();
}
}
void AllDone()
{
Debug.Log("File Downloaded");
FileExists = 1;
}
public void DeleteVideo()
{
print("Delete File");
PlayerPrefs.DeleteKey("videoDownloaded");
FileExists = 0;
enterButton.SetActive(false);
downloadButton.SetActive(true);
File.Delete(Application.persistentDataPath + "/" + fileName);
}