3

Unity之动态加载播放外部mp3音频

 2 years ago
source link: https://fredlyu.github.io/Unity%E4%B9%8B%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD%E6%92%AD%E6%94%BE%E5%A4%96%E9%83%A8mp3%E9%9F%B3%E9%A2%91.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Unity之动态加载播放外部mp3音频

发表于

2020-05-16 分类于 Unity NAudio

阅读次数: 646 评论次数: 0 本文字数: 2k 阅读时长 ≈ 2 分钟

Unity动态加载并播放mp3音频

  由于Unity支持的外部加载的音频格式有限(wav、ogg等),因此本文使用支持.Net的NAudio库来完成MP3音频的加载与播放。
  NAudio
  下载NAudio动态库,然后放在Unity中的Plugins文件夹下。在Unity使用NAudio播放MP3音频有两种方式,使用声卡直接播放和使用Unity的AudioSource播放。接下来我们一一了解。

  在Unity中直接播放,需要先申请实例化一个WaveOutEvent对象,用于将音频直接发送到声卡输出;然后需要一个AudioFileReader加载外部的MP3音频,再将音频绑定到WaveOutEvent输出设备。在音频播放完毕之后,同时也要释放资源,避免内存的泄露与浪费,这时我们可以使用WaveOutEvent对象的PlaybackStopped事件来完成这个操作。具体代码实现如下:


void Start()
{
    if(string.IsNullOrEmpty(audioUrl))
    {
        audioUrl = System.Environment.CurrentDirectory + "/Audios/test.mp3";
    }

    //使用声卡直接播放
    if(outputDevice == null)
    {
        //初始化播放设备
        outputDevice = new WaveOutEvent();
        //绑定播放结束事件
        outputDevice.PlaybackStopped += OutputDevice_PlaybackStopped;
    }
    if(audioFileReader == null)
    {
        //加载音乐
        audioFileReader = new AudioFileReader(@audioUrl);

        outputDevice.Init(audioFileReader);
    }

    outputDevice.Play();
}

private void OutputDevice_PlaybackStopped(object sender, StoppedEventArgs e)
{
    //释放资源
    outputDevice.Dispose();
    outputDevice = null;
    audioFileReader.Dispose();
    audioFileReader = null;
}

  其他具体操作可以参考NAudio的说明手册

使用Unity播放

  使用Unity的AudioSource播放,需要先将MP3转换成Unity支持的外部加载音频格式,这里我们使用wav格式。转换MP3需要用到NAudio中的WaveFileWriter中的CreateWaveFile静态方法,并且在此需要使用Mp3FileReader先将MP3音频加载到内存。接着就可以使用UnityWebRequestMultimedia加载转换完成的mav文件到Unity了。具体代码如下:


void PlayAudio(string url)
{
    //获取音频名称
    FileInfo fileInfo = new FileInfo(@url);
    //wav保存地址
    cacheUrl = Path.Combine(System.Environment.CurrentDirectory + "/Cache", fileInfo.Name.Replace(".mp3", ".wav"));
    //判断是否已经转换过
    if (!File.Exists(@cacheUrl))
    {
        //将MP3转换成WAV
        using (var audioStrem = new Mp3FileReader(@url))
        {
            WaveFileWriter.CreateWaveFile(@cacheUrl, audioStrem);
        }
    }

    //使用Unity加载wav音频并播放
    StartCoroutine(LoadAndPlay(@cacheUrl));
}

  这里Unity加载外部音频的代码就不给出了,大家自行查阅资料学习。补充一点就是对于转换完成后的WAV音频是保存到本地的,因此我们在转换一个MP3音频前可以先检查本地是否存在已经转换好wav音频,因此就有了if (!File.Exists(@cacheUrl))这段代码。
  具体其他注意点,可以查考ConvertMp3ToWav

  对于这两种方式,哪种较好,我个人推荐使用Unity中的AudioSource去播放,虽然会耗时稍微长一点。但做好预加载应该是没啥问题的。至于为什么不推荐使用声卡直接播放,因为如果处理不好容易导致内存泄露,程序闪退。

如有侵权,请联系删除!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK