当前位置: 首页 > news >正文

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

相关文章:

  • jmeter吞吐量控制器-Throughput Controller
  • 计算机四级 - 数据库原理 - 第9章「数据库应用及安全性」
  • WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)深度解析与实战复现
  • C/C++蓝桥杯算法真题打卡(Day6)
  • 在群晖DS923+手动安装我Wordpress最新版
  • 小科普《php、jsp、asp和aspx的区别》
  • 使用JSON存储数据的场景
  • 第七章:SELinux
  • DeepSeek R1在医院后勤故障报修工单自动化处理中的路径设计
  • API调用大模型推理与第三方API实现业务整合
  • leetcode974. 和可被 K 整除的子数组
  • 现代操作系统阅读笔记(一)
  • C#语言的事务管理
  • GESP2023年12月认证C++三级( 第三部分编程题(1)小猫分鱼)
  • 时间序列建模 | 时间序列预测【项目复现】数据挖掘实战③:基于Matplotlib对空气质量监测数据进行可视化分析(附带实例代码)
  • 算法刷题记录——LeetCode篇(8) [第701~800题](持续更新)
  • 关于Redis的集群(上)
  • java构建树形结构的方式、如何组装树状结构数据
  • ModBus TCP/RTU互转(主)(从)|| Modbus主动轮询下发的工业应用 || 基于智能网关的串口服务器进行Modbus数据收发的工业应用
  • 课程4. 图像处理算法与卷积神经网络
  • 欧盟和英国对俄新一轮制裁将中国公司也列入名单,外交部回应
  • 为配合铁路建设,上海地铁3号线将在这两个周末局部缩时运营
  • 国家发改委:进一步完善促进民营经济发展的制度机制
  • 安徽凤阳通报鼓楼瓦片脱落:去年3月维修竣工,已成立调查组
  • 甘肃省白银市一煤矿发生透水事故,3人失联
  • 媒体:多家国有大行存款利率即将迎来新一轮下调