c# - 在 Unity 中通过音频源播放 NAudio .mp3

标签 c# audio unity-game-engine mp3 naudio

我正在使用一个名为 Visualizer Studio ( http://www.alteredr.com/visualizer-studio/ ) 的软件包来制作一个游戏,其中对象对音乐使用react。我的目标是让用户能够在游戏过程中随时加载歌曲。它将是独立/PC 版,而不是 WebPlayer。

我的问题是 Visualizer Studio 从场景中的音频源获取音频数据。因此,当我使用 NAudio 加载和流式传输 MP3 时,可视化工作室听不到它们,并且我的对象不会对音乐使用react。

我现在正在代码中使用 IWavePlayer。我尝试添加audio.clip = www.GetAudioClip和类似的函数来让音频剪辑加载正在播放的音乐,但无济于事。

我从这篇博客文章中获得了用于选择和流式传输 .mp3 的代码(源代码位于底部):( http://denis-potapenko.blogspot.com/2013/04/task-6-loading-mp3-audio-via-www-class.html )。目前它没有改变,因为我所做的一切都不起作用。

需要明确的是,当我从文件浏览器中选择 .mp3 时,它们会播放。我只需要它们在我的场景中通过音频源播放。拜托,一定有办法做到这一点。我已经联系了可视化工作室支持人员并在统一论坛上进行了询问,但到目前为止没有人可以提供帮助。

请记住,我并不是一个出色的程序员,因此您可能不得不为我简化答案。感谢您提前的耐心等待。无论如何,

这是我用来打开文件浏览器和流音频的代码:

using UnityEngine;
using System.Collections;
using System.IO;

using System.Runtime;
using System.Runtime.InteropServices;

using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

using NAudio;
using NAudio.Wave;

public class AppRoot : MonoBehaviour
{
    ///////////////////////////////////////////////////////////////////////////
    #region Variables

    private static AppRoot mInstance = null;

    private const string cLocalPath = "file://localhost/";

    private IWavePlayer mWaveOutDevice;
    private WaveStream mMainOutputStream;
    private WaveChannel32 mVolumeStream;

    #endregion
    ///////////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////////
    #region Interface

    public AppRoot()
    {
        mInstance = this;
    }

    public void Start()
    {

    }

    public void Update()
    {
        if(Input.GetKeyDown(KeyCode.F))
        {
            UnloadAudio();
            LoadAudio();
        }



    }

    public void OnGUI()
    {
        if (GUI.Button(new Rect(100, Screen.height - 200 + 100, Screen.width - 200, 35), "Load audio"))
        {
            UnloadAudio();
            LoadAudio();
        }
    }

    public void OnApplicationQuit()
    {
        UnloadAudio();
    }

    #endregion
    ///////////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////////
    #region Implementation

    private void LoadAudio()
    {
        System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
        ofd.Title = "Open audio file";
        ofd.Filter = "MP3 audio (*.mp3) | *.mp3";
        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            WWW www = new WWW(cLocalPath + ofd.FileName);


            Debug.Log("path = " + cLocalPath + ofd.FileName);
            while (!www.isDone) { };
            if (!string.IsNullOrEmpty(www.error))
            {
                System.Windows.Forms.MessageBox.Show("Error! Cannot open file: " + ofd.FileName + "; " + www.error);
                return;
            }

            byte[] imageData = www.bytes;

            if (!LoadAudioFromData(imageData))
            {
                System.Windows.Forms.MessageBox.Show("Cannot open mp3 file!");
                return;
            }



           mWaveOutDevice.Play();



            Resources.UnloadUnusedAssets();
        }

    }

    private bool LoadAudioFromData(byte[] data)
    {
        try
        {
            MemoryStream tmpStr = new MemoryStream(data);
            mMainOutputStream = new Mp3FileReader(tmpStr);
            mVolumeStream = new WaveChannel32(mMainOutputStream);

            mWaveOutDevice = new WaveOut();
            mWaveOutDevice.Init(mVolumeStream);

            return true;
        }
        catch (System.Exception ex)
        {
            Debug.LogWarning("Error! " + ex.Message);
        }

        return false;
    }

    private void UnloadAudio()
    {
        if (mWaveOutDevice != null)
        {
            mWaveOutDevice.Stop();
        }
        if (mMainOutputStream != null)
        {
            // this one really closes the file and ACM conversion
            mVolumeStream.Close();
            mVolumeStream = null;

            // this one does the metering stream
            mMainOutputStream.Close();
            mMainOutputStream = null;
        }
        if (mWaveOutDevice != null)
        {
            mWaveOutDevice.Dispose();
            mWaveOutDevice = null;
        }

    }

    #endregion
    ///////////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////////
    #region Properties

    private static AppRoot Instance
    {
        get
        {
            return mInstance;
        }
    }

    #endregion
    ///////////////////////////////////////////////////////////////////////////
}

真诚的, 乔纳森

最佳答案

http://answers.unity3d.com/answers/1128204/view.html

将“最新”版本的 NAudio.dll 和 NAudio.WindowsMediaFormat.dll 插入您的 Resources 文件夹后,利用此代码执行您所描述的操作:

var musicInput : GameObject;
 private var aud : AudioFileReader;
 private var craftClip : AudioClip;
 private var AudioData : float[];
 private var readBuffer : float[];
 private var soundSystem : AudioSource;
 private var musicPath : String[];

 //Check if there's a pref set for the music path. Use it AND add all the files from it
 function CheckMusic()
 {
     var pathname = musicInput.GetComponent.<InputField>();
         if(PlayerPrefs.HasKey("musicpath") == false)
             {
                 PlayerPrefs.SetString("musicpath", "Enter Music Directory");
             }
             else
                 {
                     pathname.text = PlayerPrefs.GetString("musicpath");
                     musicPath = Directory.GetFiles(PlayerPrefs.GetString("musicpath"),"*.mp3");
                 }

 }

 function LoadSong(songToPlay : int)
 {
 //Download the song via WWW
 var currentSong : WWW = new WWW(musicPath[songToPlay]);

 //Wait for the song to download
 if(currentSong.error == null)
     {
         //Set the title of the song
         playingSong.text = Path.GetFileNameWithoutExtension(musicPath[songToPlay]);
         //Parse the file with NAudio
         aud = new AudioFileReader(musicPath[songToPlay]);

         //Create an empty float to fill with song data
         AudioData = new float[aud.Length];
         //Read the file and fill the float
         aud.Read(AudioData, 0, aud.Length);

         //Create a clip file the size needed to collect the sound data
         craftClip = AudioClip.Create(Path.GetFileNameWithoutExtension(musicPath[songToPlay]),aud.Length,aud.WaveFormat.Channels,aud.WaveFormat.SampleRate, false);
         //Fill the file with the sound data
         craftClip.SetData(AudioData,0);
         //Set the file as the current active sound clip
         soundSystem.clip = craftClip;
     }
 }

我引用

The "songToPlay" variable that is passed to the function is a simple int that is acquired from the array created under the CheckMusic function. I search a chosen directory entered from a GUI Inputfield for a specific file type (MP3) which can be changed to WAV or OGG and then input those files to an array. Other code chooses the number of the song on the array to play and you can change that to anything you like. The important part is that the NAudio,dll does all the heavy lifting. All you need to do is use the aud.Read(float[] to send data to, song starting point(usually 0),length of song data (aud.length). The Float[] here is the same length as aud.length so create the float of the same length, read the file, fill the float, create the clip, then dump the float data in with AudioClip.SetData()

Right now this code works and it does the job. Downside is it takes 2-3 seconds to fill the float in this way and is a noticeable drag. It also tends to chew up memory pretty fast, but it gets the job done. Hope it helps as a starting point for those who are looking to do this. I know I needed it.

关于c# - 在 Unity 中通过音频源播放 NAudio .mp3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19349643/

相关文章:

c# - 如何在C Sharp中使用unity3d从url下载文件并保存在位置?

c# - 从 Web API 提供文件和路由

c# - 获取成员拦截的属性值

python-2.7 - 在 MAC 上使用 Kivy 和 python 播放 wav 文件时没有声音

javascript - 使用jQuery和JavaScript在按钮上添加开关行为

HTML 滚动声音 - 仅暂停

ios - Xcode 和 Unity 缺少库 'lGoogleUtilities'

java - 在java中检索cookieContainer内的数据

c# - 如何在 Unity 5 中使用 .NET Framework 4.5

c# - 变量初始化 : Directly or in the constructor?