Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как загрузить аудио файл пользователя в audio bufer (https://javascript.ru/forum/misc/65135-kak-zagruzit-audio-fajjl-polzovatelya-v-audio-bufer.html)

lucky89 29.09.2016 09:03

Как загрузить аудио файл пользователя в audio bufer
 
Здравствуйте!
Подскажите, можно ли как-то загрузить аудио файл пользователя в audio bufer для дальнейшей работы с ним средствами Web Audio API ?
То есть хочу, чтобы пользователь нажимал в браузере кнопку "Выбрать песню на диске", ему открывался Проводник, юзер выбирает трек и тот грузится в audio bufer.
По url аудиофайлы знаю как получать, но нужно, чтобы юзер мог в любой момент подгружать свои звуки. Именно сразу в audio bufer, на сервере его mp3 хранить не нужно.

Aetae 29.09.2016 10:48

Если нужно работать "с ним средствами Web Audio API", то буффер тут не нужен.)
<audio controls="true"></audio><br>
<input type="file" accept="audio/*" />
<script>
var files = document.querySelector('input'),
	audio = document.querySelector('audio');

files.addEventListener('change', function(){
	audio.src = URL.createObjectURL(this.files[0]);  
});
audio.addEventListener('canplay', function(){
	this.play();

	var context = new AudioContext();
	var input = context.createMediaElementSource(this);
	//... здесь творим что нам надо
	input.connect(context.destination);
});
</script>

А если нужен именно буффер то вам потребуется FileReader.readAsArrayBuffer() и AudioContext.decodeAudioData().

Опан 29.09.2016 21:46

Декодированные аудиоданные могут потребоваться, если нужно просмотреть их в каком-то другом представлении, скажем, в виде текста или в шестнадтцатеричном виде, или чтобы построить диаграмму. А для воспроизведения они по-любому должны находится в каком-то из стандартных аудиоформатов. и не зависимо, где - на сервере или локалке, в файле или оперативной памяти.
Не знаю, какие негаразды могуд вызвать необходимость делить на части процесс воспроизведения музыки - сначала в буфер, а потом всё остальне? Обычно применение <audio src="..."> или флешплееров решает все задачи надёжности и быстродействия. К тому же я не допонял, о каких своих звуках пользователя идёт речь.

lucky89 30.09.2016 10:54

Цитата:

Сообщение от Опан (Сообщение 430258)
Декодированные аудиоданные могут потребоваться, если нужно просмотреть их в каком-то другом представлении

Нужны. Это игра типа Audiosurf, на основе трека строится карта и юзер ее проходит под свою же музыку.
Уже смог загрузить и в audio и в буфер.
Aetae, спасибо!
При загрузке в audio страница есть 40 Мб оперативной памяти, а если в буфер, то 150Мб. Вот и думаю может и без буфера обойтись получится.
---
Писал другую игрушку, вот она: http://printmusic.ru/ (нужна клавиатура и колонки, с мобильных устройств не загрузится, если только клаву через OTG не подключите). Так вот в ней я звуки нот все 128 штук каждую грузил в буфер, от туда уже по нажатиям кнопок они играют. Игра тоже многовато памяти ест... Может есть более правильный способ для загрузки звуков в игры?

Опан 30.09.2016 12:18

Цитата:

Сообщение от lucky89 (Сообщение 430300)
Так вот в ней я звуки нот все 128 штук каждую грузил в буфер, от туда уже по нажатиям кнопок они играют.

Лишние хлопоты. Можете записать один МП3-файл общей длительностью с одну песню, в котором бы по очереди проигрывались все звуки для игры (или ноты), и элементом аудио в нужный момент воспроизводить нужный участок этого файла, содержащий соответствующий звук. И будете использовать только 5-7 мб оперативки вместо 150. Хотя может построение карты стоит таких затрат.
Я тут попытался разработать алгоритм, синтезирующий музыкальные звуки вообще без сохранения в файл. В моём примере суть в том, что в результате действия случайных настроек после каждого обновления страницы они звучат уже по-другому и никогда не повторяются. Вот ссылка. Страница ест до 200 мб памяти и грузится от трёх секунд. Но если вместо целого рингтона генерировать одну ноту, то затраты будут меньшими. Не знаю, на сколько правильно всё это решение, но что, если его использовать для игры?

lucky89 30.09.2016 12:56

Цитата:

Сообщение от Опан (Сообщение 430337)
и элементом аудио в нужный момент воспроизводить нужный участок этого файла, содержащий соответствующий звук.

А элемент audio многопоточность поддерживает? Там же и по 10 звуков одновременно бывает надо запускать. То есть 1 элемент audio должен одновременно начать воспроизводить несколько своих кусков, при чем надо иметь возможность каждым, уже звучащим куском управлять по отдельности: какой приглушить, какой ускорить, какой выключить и забыть...
Строить карту - это разовая процедура, это до начала игры происходит (создается большой массив в переменной, но он почти ничего не весит в плане памяти), так что по ходу игры оно не влияет на потребляемую память.
--
В твоем сайте прямо средствами web audio api из "цифр и знаков" синтезируются звуки? Ты можешь любую ноту любого инструмента закодить?

рони 30.09.2016 13:10

lucky89,
https://github.com/stewdio/beep.js
https://github.com/miroshko/Synzer

Опан 30.09.2016 13:48

Элемент аудио многопоточность и ускорение не поддерживают (обещают в будущем.) Можно использовать много элементов на странице.
Цитата:

Сообщение от lucky89
В твоем сайте прямо средствами web audio api из "цифр и знаков" синтезируются звуки? Ты можешь любую ноту любого инструмента закодить?

web audio api я не использую. Только заливаю данными массив типа blob, его можно использовать, как медиаисточник для элемента аудио.
Да, могу любую ноту и последовательность, но не традиционними инструменами, а звуком синтезатора (типа, как когда-то были аналоговые) с разными настройками.

lucky89 30.09.2016 15:32

Цитата:

Сообщение от Опан (Сообщение 430350)
заливаю данными массив типа blob, его можно использовать, как медиаисточник для элемента аудио.

Можешь в двух словах рассказать, как звук в blob превратить? Или показать, как будет звучать в твоем исполнении например эта нота: http://printmusic.ru/game/midi/66.mp3 ?
---
Забыл уточнить, это ты чисто программно делаешь или реальный инструмент синтезатор используешь?

Опан 30.09.2016 22:03

Допустим, ты загнал звук пианино из МП3-файла в ArrayBuffer() и декодировал данные, как предложил Aetae. Потом нужно создать объект DataView() (это такой массив, в который можно записывать разнотипную информацию) и отформатировать его содержимое, как в файле формата WAV и в качестве аудиоданных загнать содержимое ArrayBuffer(). Получится то же файл в формате WAV, только в оперативке:
var buffer = new ArrayBuffer();
// тут загоняем аудиоданные
var view = new DataView(buffer);
// тут загоняем всё, что нужно
var audioBlob = new Blob([view], { type: 'audio/wav' });
var url = URL.createObjectURL(audioBlob);
var audio= new Audio(url);
audio.play();

Примерно так (хотя я чуть было не запутался)
Я всё сделал чисто программно, и для заполнения ArrayBuffer использовал математический алгоритм, а не внешний источник (файл). Если интересует сам алгоритм, могу кратко описать в личке.


Часовой пояс GMT +3, время: 19:01.