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,它们给出的回答里面,也会提到这个优化点,可惜了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值