То, что недавно казалось фантастикой, сегодня уже реальность. Начиная с версии 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;
Ну и как обычно, простейший пример всего вышеописанного:
Ссылки по теме:
Восхитительно, как всегда! Спасибо за подробное описание. Его бы еще на английском и в кукбук.
ОтветитьУдалитьError: No audio data = audio data
ОтветитьУдалитьat MainTest/Wav_public_and_Setting()
at MainTest/stopRec()
Круто, как раз стал вопрос об обработке аудио и видео потока.
ОтветитьУдалитьА есть возможность что-то подобное сделать с видео? Все ресурсы в основе своей, описывают отправку видео потока на сервер, а для меня это лишнее.
Да. у меня та же ошибка, что и у alexa. как при извлечении данных из загруженной во флэш музыки, так и с микрофона. Подскажите, в чем может быть проблема?
ОтветитьУдалитьв статье 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.
_sample_arr.position = 0 перед записью во wav_writer
ОтветитьУдалитьа исходники к примеру можно?
ОтветитьУдалитьПодскажите пожалуйста как отправить несоразмерный файл на сервер.
ОтветитьУдалитьУ меня есть скрипт, который записывает с микрофона и сохраняет в файл
fileReference.save(recorder.output, "recording.wav");
Как заставить моментально отправлять файл на сервер?
Я прочитал про
fileReference.upload()
но я так понимаю, он требует сначала показывать диалоговое окно выбора фала через
fileReference.browse()
Вы писали "Если же есть необходимость отправить полученный .mp3-файл на сервер, мы можем сделать это самостоятельно..."
Я не могу понять, чем мне нужно пользоваться, чтобы отправить recorder.output
Спасибо
Почему все пишут как создать, я вот ничего не понимаю в AS, а нужно написать то, что тут описано. Копирую вставляю во Adobe Flash, сохраняю, жму ctrl+enter и получаю набор ошибок... можете в конце статья прикрепить архив с исходниками и в какой программе все делали...
ОтветитьУдалить