Sunday, April 21, 2013

Задача 6: Загрузка MP3 аудио через класс WWW

Практическое использование движка Unity3d.


Задача 6: Загрузка MP3 аудио через класс WWW


  В этой статье рассмотрим следующую задачу: необходимо реализовать загрузку mp3 аудио через класс WWW в Unity3d. К сожалению Unity3d не поддерживает загрузку mp3 аудио через WWW для Windows. Для того чтоб реализовать загрузку mp3 аудио будем использовать бесплатную библиотеку NAudio (подробнее здесь: http://naudio.codeplex.com/).
  Первым делом скачаем библиотеку NAudio, и скопируем файлы NAudio.dll и NAudio.WindowsMediaFormat.dll в папку Assets. 
  После этого необходимо включить поддержку полной версии .NET Framework в Unity3d. Для этого нужно установить в «File/Build Settings/Player Settings/Other Settings/Optimization/Api Compatibility Level» параметр «.NET 2.0». На рис. 1 показан процесс установки полной версии .NET Framework.
Рисунок 1. – Установка полной версии .NET Framework 
  Теперь перейдем к скриптам. Во-первых убедимся что библиотека уже подключена к проекту. Для этого раскрываем «References» в проекте, и проверяем наличие библиотек NAudio. В случае если они не подключены – подключаем их. Структура «References» показана на рис. 2.

 
Рисунок 2. – Секция «References» 


Теперь подключим необходимые сборки в секции «using». 
using NAudio; 
using NAudio.Wave;
Теперь создадим переменные - член класса, с помощью которой мы будем проигрывать звук. 
private IWavePlayer mWaveOutDevice;
private WaveStream mMainOutputStream;
private WaveChannel32 mVolumeStream;
Создадим функцию, которая из массива байт загружает аудио.
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;
}
Алгоритм функции следующий:
  • Создаем объект класса «MemoryStream»; 
  • Т.к. мы будем загружать звук в формате mp3, создадим объект класса «Mp3FileReader»; 
  • Из объекта класса «Mp3FileReader» создадим объект класса «WaveChannel32»; 
  • Наконец, для того чтоб получить возможность воспроизводить звук, создадим объект класса «WaveOut», и инициализируем его; 

Теперь создадим функцию для загрузки звука «LoadAudio». 
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();
    }
}
Алгоритм функции следующий:
  • Показать пользователю «OpenFileDialog». Фильтры диалогу поставим такие, чтоб диалог показывал только mp3 файлы; 
  • С помощью объекта класса WWW загружаем данные mp3 файла; 
  • Передаём загруженные данные в функцию «LoadAudioFromData». В случае если функция не вернула никаких ошибок – проигрываем звук;

Для выгрузки звука из памяти, напишем функцию «UnloadAudio». 
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;
    }
}
Алгоритм выгрузки звука очень простой:
  • Останавливаем проигрывание звука; 
  • Закрываем «WaveChannel32» и «WaveStream»; 
  • Освобождаем память для объекта класса «IWavePlayer»; 

 Вот и все. Также, для библиотеки NAudio, есть хороший пример для проигрывания mp3 звука, который можно посмотреть здесь: http://naudio.codeplex.com/wikipage?title=MP3

  Если Вам нужно более детальное описание работы, пожалуйста, пишите в комментариях. 


Демонстрацию работы можно скачать здесь: 

Исходные коды работы, как всегда бесплатно, можно скачать здесь: 

No comments:

Post a Comment