在Unity项目中的Gear VR中播放大型视频文件

时间:2017-08-09 02:26:35

标签: c# file unity3d unity5 gear-vr

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

我已经读过可以使用PersistentDataPath文件夹了,但是我不知道如何在统一时将我的视频放到该文件夹​​中。我不想在那里复制视频,只使用一个时有两个600mb的文件。

3 个答案:

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