Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Unity项目的Gear VR中播放大型视频文件_C#_File_Unity3d_Unity5_Gear Vr - Fatal编程技术网

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

C# 在Unity项目的Gear VR中播放大型视频文件,c#,file,unity3d,unity5,gear-vr,C#,File,Unity3d,Unity5,Gear Vr,我正在创建一个Gear VR android应用程序,可以播放30分钟的大视频。我已经读到我不应该使用StreamingAssets文件夹,但是我没有看到任何关于我应该使用什么的信息。如果我把视频放在资产/视频中,它不会包含在android构建中。我应该使用resources文件夹还是有其他方法包含视频?(我的项目也在iOS上,但我目前在该平台上没有任何问题。) 我已经读到可以使用PersistentDataPath文件夹,但我不知道如何将我的视频从unity放入该文件夹。我不想复制那里的视频,

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

我已经读到可以使用PersistentDataPath文件夹,但我不知道如何将我的视频从unity放入该文件夹。我不想复制那里的视频,当只有一个使用时,我有两个600mb的文件

提取和复制大型文件可能需要很长时间,有时它们会 甚至可能导致设备耗尽存储空间或内存

这是真的,但你必须知道你在做什么。您不能仅使用
WWW
API或仅使用
file.copy
/
file.writealBytes
函数复制文件

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。文件夹。(不推荐)因为这会减慢游戏加载时间。值得一提。使用新的Unity,您可以像这样加载视频:

VideoClip video = Resources.Load("videoFile", typeof(VideoClip)) as VideoClip;
AVPro插件是不需要的,在Unity中不再需要


如果您需要的话,您也可以使用带有AVPro插件的Resources文件夹

只需将视频扩展名更改为
.bytes
,然后将其作为字节加载即可。如果AVPro插件可以以字节的形式播放视频,那就好了

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

3。使用AssetBundle加载视频。这在过去新的视频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;
}
IEnumerable加载对象(字符串路径)
{
AssetBundleCreateRequestBundle=AssetBundle.LoadFromFileAsync(路径);
收益-收益捆绑;
AssetBundle myLoadedAssetBundle=bundle.AssetBundle;
if(myLoadedAssetBundle==null)
{
Log(“加载资产绑定失败!”);
屈服断裂;
}
AssetBundlerRequest请求=myLoadedAssetBundle.LoadAssetAsync(“视频文件”);
退换货请求;
VideoClip clip=请求.asset作为VideoClip;
}

4。最后,使用
StreamingAssets
文件夹,但不要复制视频,而是使用
HttpListener
创建一个本地服务器,并将其指向
StreamingAssets
路径

现在,连接新功能并播放视频。您可以在stackoverflow上找到许多
HttpListener
服务器的示例。我过去也做过这件事,而且效果很好

提取和复制大型文件可能需要很长时间,有时它们会 甚至可能导致设备耗尽存储空间或内存

这是真的,但你必须知道你在做什么。您不能仅使用
WWW
API或仅使用
file.copy
/
file.writealBytes
函数复制文件

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。文件夹。(不推荐)因为这会减慢游戏加载时间。值得一提。使用新的Unity,您可以像这样加载视频:

VideoClip video = Resources.Load("videoFile", typeof(VideoClip)) as VideoClip;
AVPro插件是不需要的,在Unity中不再需要


如果您需要的话,您也可以使用带有AVPro插件的Resources文件夹

只需将视频扩展名更改为
.bytes
,然后将其作为字节加载即可。如果AVPro插件可以以字节的形式播放视频,那就好了

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

3。使用AssetBundle加载视频。这在过去新的视频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;
}
IEnumerable加载对象(字符串路径)
{
AssetBundleCreateRequestBundle=AssetBundle.LoadFromFileAsync(路径);
收益-收益捆绑;
AssetBundle myLoadedAssetBundle=bundle.AssetBundle;
if(myLoadedAssetBundle==null)
{
Log(“加载资产绑定失败!”);
屈服断裂;
}
AssetBundlerRequest请求=myLoadedAssetBundle.LoadAssetAsync(“视频文件”);
退换货请求;
VideoClip clip=请求.asset作为VideoClip;
}

4。最后,使用
StreamingAssets
文件夹,但不要复制视频,而是使用
HttpListener
创建一个本地服务器,并将其指向
StreamingAssets
路径


现在,连接新功能并播放视频。您可以在stackoverflow上找到许多
HttpListener
服务器的示例。我以前也这样做过,而且很有效。

我发现这是一种下载文件并将其保存到PersistantDataPath的方法。


我看到的一个问题是,如果应用程序暂停。(例如,取下耳机)下载失败。对于650MB的文件,基本上所有用户都会这样。你知道我如何在unity暂停时继续下载吗?我还将对此发表一篇新文章。

我发现这是一种下载文件并将其保存到PersistantDataPath的方法。


我看到的一个问题是,如果应用程序暂停。(例如,取下耳机)下载失败。对于650MB的文件,基本上所有用户都会这样。你知道我如何在unity暂停时继续下载吗?我还将就此发表一篇新文章。

这是我现在要用的代码

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

这是我现在要用的代码

 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);
}
“我已经读到我不应该使用流媒体