2017-08-09 55 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); 
}