Блог от AS3Coder'a о JavaScript, HTML, CSS... и немного о Flash.

пятница, 2 декабря 2011 г.

Сохранение звука с микрофона на ActionScript 3.0

То, что недавно казалось фантастикой, сегодня уже реальность. Начиная с версии FlashPlayer'a 10.1 у класса Microphone появилось событие sampleData.

SampleDataEvent

Это событие отправляется когда в буфере микрофона появляются аудио-данные. Событие имеет свойство data, которое содержит образцы записанных с микрофона данных. Естественно данные приходят в сыром формате. И проиграть их вне FlashPlayer'a не получиться. Поэтому их необходимо декодировать, предварительно собрав необходимое количество в бинарный массив ByteArray.

//
// Объявляем бинарный массив для хранения полученных с микрофона аудио-данных
var _samples_arr:ByteArray = new ByteArray();;
//
// Получаем экзмпляр микрофона
var _microphone:Microphone = Microphone.getMicrophone(-1);
//
// Вешаем обработчик события 
_microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, onMicrophoneSampleData, false, 0, true);
//
// Обработчик обновления данных в микрофоне
function onMicrophoneSampleData (e:SampleDataEvent):void
{
  //
  // Добавляем полученные данные в биннарный массив
  _samples_arr.writeBytes(e.data);
}

Для начала выполним преобразование в .wav-формат.

WAVWriter

Специально для этого в Adobe написали класс WAVWriter.as. Останавливаться на нём не будем, потому что он довольно простой в использовании:
//
// Объявляем бинарный массив для данных .wav-файла
var wav_file:ByteArray = new ByteArray();
//
// Объявляем и настроиваем энкондер
var writer:WAVWriter = new WAVWriter();
writer.numOfChannels = 1;
writer.sampleBitRate = 16;
writer.samplingRate = 44100;
//
// Декодируем данные с микрофона в wav-формат
writer.processSamples(wav_file, _samples_arr, 44100, 1);

Теперь, фактически получив бинарные данные аудио-файла в .wav-формате, казалось бы мы выполнили задачу и остается только сохранить их в файл. 

Но мы пойдем дальше. И рассмотрим преобразование наших данных в .mp3-формат. Да, такое уже возможно и реализовано. Говорим спасибо Cyril Diagn за его работу в этом направлении, а именно проект Shine MP3 Encoder on Alchemy.

Shine MP3 Encoder on Alchemy

Это .swc-библиотека с классом ShineMP3Encoder для преобразования данных из .wav-формата в .mp3. Код портирован с помощью Alchemy из энкодера написанного на С, автором которого является Gabriel Bouvigne.

Пример использования:
//
// Обнуляем позицию в массиве .wav-файла
wav_file.position = 0;
//
// Объявляем mp3-энкодер
var _mp3_encoder:ShineMP3Encoder = new ShineMP3Encoder(wav_file);
//
// Вешаем обработчики событий
_mp3_encoder.addEventListener(Event.COMPLETE, onMP3EncoderComplete, false, 0, true);
_mp3_encoder.addEventListener(ProgressEvent.PROGRESS, onMP3EncoderProcess, false, 0, true);
//
// Начинаем кодирование
_mp3_encoder.start();
//
// Обработчик процесса кодирования
function onMP3EncoderProcess (e:ProgressEvent):void
{
  trace("Encoding to mp3 ... " + Math.ceil(e.bytesLoaded * 100 / e.bytesTotal) + "%");
}
//
// Обработчик завершения кодирования
function onMP3EncoderComplete (e:Event):void
{
  trace("Encoding to mp3 complete!")
}

Теперь, после преобразования мы можем сохранить .mp3-файл штатными средствами энкодера. Для этого имеется метод saveAs()
_mp3_encoder.saveAs('record.mp3');

Если же есть необходимость отправить полученный .mp3-файл на сервер, мы можем сделать это самостоятельно, получив его данные во свойстве mp3Data.
var mp3_file:ByteArray = _mp3_encoder.mp3Data;

Ну и как обычно, простейший пример всего вышеописанного:


Ссылки по теме:
       

9 комментариев:

  1. Восхитительно, как всегда! Спасибо за подробное описание. Его бы еще на английском и в кукбук.

    ОтветитьУдалить
  2. Error: No audio data = audio data
    at MainTest/Wav_public_and_Setting()
    at MainTest/stopRec()

    ОтветитьУдалить
  3. Круто, как раз стал вопрос об обработке аудио и видео потока.
    А есть возможность что-то подобное сделать с видео? Все ресурсы в основе своей, описывают отправку видео потока на сервер, а для меня это лишнее.

    ОтветитьУдалить
  4. Да. у меня та же ошибка, что и у alexa. как при извлечении данных из загруженной во флэш музыки, так и с микрофона. Подскажите, в чем может быть проблема?

    ОтветитьУдалить
  5. в статье http://demiart.ru/forum/lofi/index.php/t164450
    описан класс MicRecorder,
    первую часть по преобразованию байтарея в wav можно сделать по примеру,
    а уже готовый wav, которым будет "recorder.output", преобразовать в mp3, как показано у автора статьи : _mp3_encoder = new ShineMP3Encoder(recorder.output);

    по классу ShineMP3Encoder и не хватающему в нём класса cmodule.shine.CLibInit – он лежит в swc.

    ОтветитьУдалить
  6. _sample_arr.position = 0 перед записью во wav_writer

    ОтветитьУдалить
  7. а исходники к примеру можно?

    ОтветитьУдалить
  8. Подскажите пожалуйста как отправить несоразмерный файл на сервер.
    У меня есть скрипт, который записывает с микрофона и сохраняет в файл

    fileReference.save(recorder.output, "recording.wav");

    Как заставить моментально отправлять файл на сервер?
    Я прочитал про
    fileReference.upload()
    но я так понимаю, он требует сначала показывать диалоговое окно выбора фала через
    fileReference.browse()

    Вы писали "Если же есть необходимость отправить полученный .mp3-файл на сервер, мы можем сделать это самостоятельно..."
    Я не могу понять, чем мне нужно пользоваться, чтобы отправить recorder.output

    Спасибо

    ОтветитьУдалить
  9. Почему все пишут как создать, я вот ничего не понимаю в AS, а нужно написать то, что тут описано. Копирую вставляю во Adobe Flash, сохраняю, жму ctrl+enter и получаю набор ошибок... можете в конце статья прикрепить архив с исходниками и в какой программе все делали...

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например <b>, <i>, <a>

Поиск по блогу

Обо мне



Farid Shamsutdinov (AS3Coder)
Russia, Tatarstan, Kazan
as3coder@gmail.com

Подробнее...

Постоянные читатели

© 2014 Farid Shamsutdinov. При копировании материалов, ссылка на источник обязательна. Технологии Blogger.