Unity音乐内存优化
文章目录
- 音乐
- 下载远程音乐
音乐
音乐文件如果只从工程目录里面读取,那有很多种方法可以优化,比如设置
Load Type
直接采用流式加载方式,内存直接降最小(但是记住,每种优化都是有对应的代价的,优化是一种平衡的艺术)。但是如果我是从url
加载进来的音乐呢 是不是就无能为力了
下载远程音乐
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using UnityEngine;
using UnityEngine.Networking;
public class MusicTest : MonoBehaviour
{
public AudioSource audioSource;
public string audioUrl = "http://music.163.com/song/media/outer/url?id=447925558.mp3";
private void Start()
{
GetAudio(audioUrl, (result, clip, tips) =>
{
audioSource.clip = clip;
audioSource.loop = true;
audioSource.Play();
});
}
public bool GetAudio(string url, Action<bool, AudioClip, string> callback)
{
if (string.IsNullOrEmpty(url))
{
callback?.Invoke(false, null, "URL is empty");
return false;
}
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
callback?.Invoke(false, null, "Invalid URL format");
return false;
}
StartCoroutine(DownloadAudioCoroutine(url, callback));
return true;
}
private IEnumerator DownloadAudioCoroutine(string url, Action<bool, AudioClip, string> callback)
{
using (var request = UnityWebRequestMultimedia.GetAudioClip(url, DetectAudioType(url)))
{
request.disposeDownloadHandlerOnDispose = true;
request.timeout = 30;
var operation = request.SendWebRequest();
while (!operation.isDone)
{
// float progress = request.downloadProgress;
yield return null;
}
if (request.result == UnityWebRequest.Result.Success)
{
AudioClip clip = DownloadHandlerAudioClip.GetContent(request);
if (clip != null)
{
clip.name = Path.GetFileNameWithoutExtension(url);
callback?.Invoke(true, clip, null);
}
else
{
callback?.Invoke(false, null, "Audio decoding failed");
}
}
else
{
string errorMsg = $"Download failed: {request.error} (HTTP {request.responseCode})";
Debug.LogError(errorMsg);
callback?.Invoke(false, null, errorMsg);
}
}
}
private AudioType DetectAudioType(string url)
{
string ext = Path.GetExtension(url).ToLower();
return ext switch
{
".mp3" => AudioType.MPEG,
".wav" => AudioType.WAV,
".ogg" => AudioType.OGGVORBIS,
".aiff" => AudioType.AIFF,
_ => AudioType.UNKNOWN
};
}
}
这是一份很正常的代码,使用UnityWebRequest
下载一首音乐资源,随便从开源的歌曲直链里面就能拿到,比如我代码上的这首资源,时长3分50,大小3.5MB,然后我加载进来,用Memory Profile
跑一下,
这么大,手算大小44100 × 2 × 2 × 230 ≈ 40,548,000 字节 ≈ 38.7MB,还真差不多。完了,动态加载进来的,clip
不能在后面设置压缩比和加载方式。
我当初在找资料的时候,一大片都没说明优化方案,大多都在强调如何从工程中导入的时候做优化,其实就加一行代码就能解决内存爆表的问题,
request.downloadHandler = new DownloadHandlerAudioClip(url,AudioType.MPEG){ streamAudio = true };
streamAudio
这个参数还是我翻源码翻出来的。比较可惜的是,现在问一些稍微深入的一点AI
,它们给出的回答里面,也会提到这个优化点,可惜了。