文章目录
- 音乐
- 下载远程音乐
音乐
音乐文件如果只从工程目录里面读取,那有很多种方法可以优化,比如设置
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
,它们给出的回答里面,也会提到这个优化点,可惜了。