2017-08-09 58 views
1

我正在创建一个播放大型30分钟视频的Gear VR android应用。我已经读过,我不应该使用StreamingAssets文件夹,但我没有看到有关我应该使用的信息。如果我把视频放在Assets/videos中,它不包含在android build中。我应该使用资源文件夹还是有另一种方式来包含视频? (我的项目也在iOS上,但我目前在该平台上没有任何问题。)在Unity项目的Gear VR中播放大型视频文件

我读过PersistentDataPath文件夹可以使用,但我不知道如何让我的视频进入文件夹从统一时。我不想在那里复制视频,只有一个使用时有两个600MB文件。

+0

*“我读过,我不应该使用StreamingAssets文件夹”*您在哪里读过这些内容? – Programmer

+0

https://forum.unity3d.com/threads/large-videos-not-playing-on-gear-vr-but-do-play-on-google-cardboard-any-ideas.395779/ –

+0

我使用AVPro和它们的文档中说明了这一点。 “机器人 - ?为什么从StreamingAssets文件夹不是我的巨大的视频文件播放 –

回答

0

太大的文件可能需要很长的时间来提取和复制,有时他们 甚至可能导致用完存储空间或内存

这是真实的设备,但是你必须知道你是做。您不能仅将该文件与WWW API或File.Copy/File.WriteAllBytes函数复制。

。复制视频块,然后播放它。这消除了内存不足的问题。

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的文件时使用 只有一个。

这里有你有其他的选择:

Resources文件夹。 (不推荐),因为这会减慢你的游戏加载时间。值得一提。随着新的统一VideoPlayer,您可以加载视频是这样的:不需要这个

VideoClip video = Resources.Load("videoFile", typeof(VideoClip)) as VideoClip; 

AVPro插件,并且不再需要统一。


如果这是你想要的,你也可以在AVPro插件中使用Resources文件夹。

只需将视频扩展名更改为.bytes,然后将其加载为字节。如果AVPro插件可以按字节播放视频,那么你去!

TextAsset txtAsset = (TextAsset)Resources.Load("videoFile", typeof(TextAsset)); 
byte[] videoFile = txtAsset.bytes; 

。用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; 
} 

。最后,使用StreamingAssets文件夹,但不是抄袭的视频,创建本地服务器HttpListener并将其指向的StreamingAssets路径。

现在,连接到与新VideoPlayer和播放视频。你可以在stackoverflow上找到很多HttpListener服务器的例子。 我已经完成了这个过去,它的工作。

+0

经过深入研究,我认为真正的解决方案将是在应用程序开始时托管文件并将其下载到设备。您知道管理下载大文件的最佳方式以及它应该存储的位置吗?谢谢。 –

+0

它应该存储到'Application.persistentDataPath/videofolder /'。 – Programmer

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); 
}