是否可以从 API 链接到 get/download 文件,而这些链接在 Unity3D 中没有真实的文件路径?

is possible to get/download file from API links that don't have real file path in Unity3D?

我尝试从 api 获取一些没有 return 真实文件路径的可下载文件,例如 www.domain.com/api/get-audio?name=foo.mp3,当在浏览器中打开时,文件将自动下载,但似乎在Unity 必须有一些功能才能下载文件,例如:

IEnumerator GetTheFoo(string path)
{
    using (UnityWebRequest www = UnityWebRequest.Get(path))
    {
        www.SendWebRequest();
        while (www.downloadProgress < 0.01)
        {
            Debug.Log(www.downloadProgress);
            yield return new WaitForSeconds(.1f);
        }
        if (www.isNetworkError)
        {
            Debug.Log("error");
        }
        else
        {  
            Debug.Log(Application.persistentDataPath);
            string savePath = string.Format("{0}/{1}.mp3", Application.persistentDataPath, "foo");        
            System.IO.File.WriteAllText(savePath, www.downloadHandler.text);
        }
    }
}

我得到了文件,但在我查看文件后 return 大小不对,可能不是声音文件,因为我无法播放它,我在 google 上深入搜索寻找最佳下载方式文件,我看到给出的所有示例和解决方案都是 link 和真实路径文件,如 file/audio/foo.mp4,因此是否可能从 API 或 link 获取可下载文件不包含真实路径?

[更新]

100%是我自己的错,见识不足请见谅 我不知道 while 是否会改变结果,所以只要用一些正确的逻辑改变 yield return 或者只用 only

替换它们

yield return www.SendWebRequest();

你会

while (www.downloadProgress < 0.01)
{
    Debug.Log(www.downloadProgress);
    yield return new WaitForSeconds(.1f);
}

因此,您等到 1% 下载完毕,然后尝试保存文件。您应该等到所有内容都下载完毕,例如

while (www.downloadProgress < 1f)
{
    Debug.Log(www.downloadProgress);
    yield return new WaitForSeconds(.1f);
}

或者如果你不需要进度更新,你也可以直接使用

yield return www.SendWebRequest();

那么 afaik MP3 文件不是 UTF8 编码的,所以你应该使用 binary DownloadHandler.data!

对于系统文件路径也可以使用 Path.Combine 而不是字符串连接 (+ "/")

var savePath = Path.Combine(Application.persistentDataPath, "foo" + ".mp3");  
File.WriteAllBytes(savePath, www.downloadHandler.data);

总的来说喜欢

IEnumerator GetTheFoo(string path)
{
    using (UnityWebRequest www = UnityWebRequest.Get(path))
    {
        www.SendWebRequest();
        while (www.downloadProgress < 1)
        {
            Debug.Log(www.downloadProgress);
            yield return new WaitForSeconds(.1f);
        }

        if (www.isNetworkError)
        {
            Debug.Log("error");
        }
        else
        {  
            var savePath = Path.Combine(Application.persistentDataPath, "foo.mp3");        
            System.IO.File.WriteAllBytes(savePath, www.downloadHandler.data);

            Debug.Log($"File saved to {savePath}", this);
        }
    }
}

这对我来说非常好,例如路过

https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_5MG.mp3

作为参数;)