Страницы

Поиск по вопросам

Показаны сообщения с ярлыком web-audio. Показать все сообщения
Показаны сообщения с ярлыком web-audio. Показать все сообщения

суббота, 11 января 2020 г.

Последовательное непрерывное воспроизведение аудио на странице с несколькими плеерами

#javascript #html5 #web_audio


Есть страница, на ней плееры (Flash) из сервиса Uppod, но не во всех браузерах они
проявляются, а главное их не видно в мобильных устройствах.
Решил заменить их на HTML5 audio, но не могу найти решение непрерывного, последовательного
воспроизведения, когда после завершения проигрывания одного плеера начинает звучать
следующий, к примеру, или тут.
Есть варианты плееров с плейлистами, но мне хотелось бы несколько плееров на странице,
между которыми будет текст. 



var audio = document.getElementsByTagName("audio");
for (let i = 0; i < audio.length; i++) {
  audio[i].addEventListener('ended', function() {
    if (audio[i].duration === audio[i].currentTime) {
      audio[i + 1].play();
    }
  });
}


Ответы

Ответ 1



Чтобы проигрывались несколько плееров подряд, за это отвечает событие ended. Надо его отследить и все. Мне кажется данная конструкция на столько проста, что и пояснять тут нечего var audio = document.getElementsByTagName("audio"); for (let i = 0; i < audio.length; i++) { audio[i].addEventListener('ended', function() { if (audio[i].duration === audio[i].currentTime) { audio[i + 1].play(); } }); }

Ответ 2



Думаю нужно поработать с events. То есть запустить проигрывание на первом плеере, затем когда произойдет событие 'ended' запускай второй плеер , и так далее. Например: document.addEventListener("DOMContentLoaded", () => { let allAudio = Array.from(document.getElementsByTagName('audio')); allAudio[0].play(); allAudio.forEach((item, index) => { item.addEventListener('ended', (ev) => { if (index === allAudio.length - 1) { index = 0 } else { index++; } allAudio[index].play(); }) }); }); Пускай не самый лучший код, но думаю концепция понятна. Для первоначального запуска первого плеера можно использовать уже, что душе угодно. Ниже ссылка на видео , аудио события: https://developer.mozilla.org/ru/docs/Web/Guide/Events/Media_events

вторник, 10 декабря 2019 г.

С помощью каких технологий рисуется звуковая волна?

#javascript #canvas #аудио #mac #web_audio


Пример.



Вообще, интересует, как из аудиофайла получить рисунок волноформы, желательно нужного
размера, в графическом формате (png, jpg).

В аудиоредакторах, например Logic pro x волноформа отображается, но нет возможности
сохранить ее, как рисунок.
Скриншот не лучший вариант, т.к. при уменьшении/увеличении изображения, теряем в
качестве.


    


Ответы

Ответ 1



Технологии рисования звуковой волны делятся на два этапа - сначала из аудиофайла получают данные для рисования. На JS это делают с помощью WebAudio Api - функции decodeAudioData(). Второй этап - вывод рисунка можно сделать очень по-разному. Пожалуй с помощью тега canvas будет попроще, но если требуется сохранить изображение в определённом формате, то есть другой способ - записать данные изображения в требуемом графическом формате в массив типа blob. Из него их потом можно будет задать, как атрибут src для элемента img, как буд-то из файла. А если это же самое задать, как атрибут href для ссылки, то потом кликом по этой ссылке можно будет скачать изображение в папку для загрузок, указанную в настройках браузера. Так же можно будет сохранить изображение, кликнув правой клавишей по рисунку и выбрав сохранить изображение. В этой теме: Получение сырых данных Audio в js во втором ответе есть пример кода рисования звуковой волны с последующей возможностью сохранения рисунка пока что в формате BMP.

Ответ 2



Аудиоволна в цифровом виде это массив значений (целых, или с плавающей запятой), отображающих силу сигнала в конкретный момент времени. Что бы нарисовать ее, мы делим все сэмплы (длину массива) на количество пикселей, для которого будем рисовать картинку. Совмещая участок массива с каждым пикселем, ищем максимальный и минимальный уровень сигнала на данном участке времени, и рисуем соответствующую вертикальную линию. По ссылке описано, как рисуется waveform в Audacity: https://manual.audacityteam.org/man/audacity_waveform.html Они еще рисуют среднее квадратичное на каждом участке, что соответствует тому, как громко в целом слышен данный участок. Ниже примерный код на джаваскрипте, можно запустить прям отсюда, подсунув ему mp3 файл, и скачав картинку в png. function processFile() { var reader = new FileReader(); reader.onload = function (e) { let buffer = e.target.result; let ctx = new AudioContext(); ctx.decodeAudioData(buffer).then(function (audioBuffer) { // здесь массив Float32 // для примера рисуем только первый канал let channel = audioBuffer.getChannelData(0); var allMin = 0; var allMax = 0; for (var i = 0; i < channel.length; i++) { allMin = channel[i] < allMin ? channel[i] : allMin; allMax = channel[i] > allMax ? channel[i] : allMax; } let allAvg = (allMin + allMax) / 2; let width = parseInt(document.querySelector('#width').value); let height = parseInt(document.querySelector('#height').value); let canvas = document.querySelector('#canvas'); canvas.width = width; canvas.height = height; let ctx = canvas.getContext('2d'); ctx.fillStyle = '#CCCCCC'; ctx.fillRect(0, 0, width, height); for (var i = 0; i < width; i++) { var min = 0; var max = 0; let sampleFrom = Math.floor(channel.length * i / width); let sampleTo = Math.floor(channel.length * (i + 1) / width); var rms = 0; // считаем минимум и максимум на участке + среднее квадратичное for (var j = sampleFrom; j < sampleTo; j++) { min = channel[j] < min ? channel[j] : min; max = channel[j] > max ? channel[j] : max; rms += channel[j] * channel[j] / (sampleTo - sampleFrom); } var fromY = Math.floor(height * (allMax - min) / (allMax - allMin)); var toY = Math.floor(height * (allMax - max) / (allMax - allMin)); ctx.fillStyle = '#414BD3'; ctx.fillRect(i, fromY, 1, toY - fromY); rms = Math.sqrt(rms); var fromY = Math.floor(height / 2 + height * (allAvg - rms) / (allMax - allMin)); var toY = Math.floor(height / 2 + height * (allAvg + rms) / (allMax - allMin)); ctx.fillStyle = '#777CE3'; ctx.fillRect(i, fromY, 1, toY - fromY); } }); }; reader.readAsArrayBuffer(document.querySelector('#file').files[0]); } function downloadImage() { let image = document.querySelector('#canvas').toDataURL('image/png').replace('image/png', 'image/octet-stream'); let a = document.querySelector('a'); a.setAttribute('download', 'image.png'); a.setAttribute('href', image); }
Width: Height:
Download Image

среда, 17 октября 2018 г.

Звук при входящем сообщении на сайте

Здравствуйте. Нужно, чтобы при входящем сообщении на сайте проигрывался звук, по типу, как у контакта! Как это реализовать? Скрипт проверки на наличие сообщений имеется, как в него вставить воспроизведение звукового файла? Решил проблему так: function soundClick() { var audio = new Audio(); // Создаём новый элемент Audio audio.src = 'n.mp3'; // Указываем путь к звуку "клика" audio.autoplay = true; // Автоматически запускаем }


Ответ

Предлагаю не создавать объект Audio каждый раз, ведь вы можете создать его однажды и использовать повторно
Ниже накиданный на скорую руку симулятор чата
function MessageClass(userName, text, avatarSrc, sendTime){ var self = this; this.UserName = userName; this.Text = text; this.SendTime = sendTime.toLocaleTimeString(); this.AvatarSrc = avatarSrc; } var chat = new function (){ var audio = document.createElement('audio'), source = document.createElement('source'), tid = 0; source.type = 'audio/mpeg'; source.src = 'http://dl.dropbox.com/u/1538714/article_resources/song.m4a'; audio.appendChild(source); this.Messages = ko.observableArray([]); this.Messages.subscribe(function (){ clearInterval(tid); audio.pause(); audio.currentTime = 0; audio.play(); // только потому что трек длинный tid = setTimeout(function(){ audio.pause(); }, 400); }); } ko.applyBindings(chat, document.getElementById("chat")); (function onMessage(){ chat.Messages.push( new MessageClass( faker.name.firstName() + ' ' + faker.name.lastName(), faker.hacker.phrase(), faker.image.avatar(), new Date() ) ); scrollTo(0, document.body.offsetHeight); setTimeout(onMessage, faker.random.number(1500) + 500); })(chat, faker); fieldset{ position: relative; } fieldset:nth-child(2n){ margin-left:24px; } legend{ color:#0a0; } time{ position:absolute; right:12px; top:0px; background:#FFF; color: #a00; display:inline-block; padding: 0px 6px; font-size: 12px; } img{ float:left; width: 60px; margin-right: 12px; border-radius:30px; height:60px; }


А вот здесь вы и сами можете писать сообщения:
function MessageClass(userName, text, avatarSrc, sendTime){ var self = this; this.UserName = userName; this.Text = text; this.SendTime = sendTime.toLocaleTimeString(); this.AvatarSrc = avatarSrc; } var chat = new function (){ var self = this, tid = 0, audio = document.createElement('audio'), source = document.createElement('source'), generateFakeMessage = function (){ self.Messages.push( new MessageClass( faker.name.firstName() + ' ' + faker.name.lastName(), faker.hacker.phrase(), faker.image.avatar(), new Date() ) ); scrollTo(0, document.body.offsetHeight); }; source.type = 'audio/mpeg'; source.src = 'http://dl.dropbox.com/u/1538714/article_resources/song.m4a'; audio.appendChild(source); self.Messages = ko.observableArray([]); self.UserMessage = ko.observable(''); self.sendMessage = function(){ if (self.UserMessage()){ chat.Messages.push(new MessageClass( 'My account', self.UserMessage(), '//s3.amazonaws.com/uifaces/faces/twitter/psdesignuk/128.jpg', new Date() )); self.UserMessage(''); } setTimeout(generateFakeMessage, 1000); return false; }; self.Messages.subscribe(function (){ clearInterval(tid); audio.pause(); audio.currentTime = 1; audio.play(); // только потому что трек длинный tid = setTimeout(function(){ audio.pause(); }, 400); }); generateFakeMessage(); } ko.applyBindings(chat, document.getElementById("chat")); fieldset{ position: relative; } fieldset:nth-child(2n){ margin-left:24px; } legend{ color:#0a0; } time{ position:absolute; right:12px; top:0px; background:#FFF; color: #a00; display:inline-block; padding: 0px 6px; font-size: 12px; } img{ float:left; width: 60px; margin-right: 12px; border-radius:30px; height:60px; } input, button{ margin-top:6px; width:100%; }