Создание аудиоплеера при помощи HTML5. Часть 2: прототипирование
Перевод статьи Making An Audio Player With HTML5, Part 2: Prototyping с сайта demosthenes.info, c разрешения автора — Дадли Стори.
Существует два подхода для создания почти чего угодно. Первый – это взяться за дело с наскока, разрабатывая от целого к частному, набивая шишки о проблемы по мере их появления и надеясь, что вы во всём разберётесь. Второй – это создать ряд простых тестов: разрабатывая от частного к целому, проверяя каждый шаг, прежде чем использовать плоды своих трудов для создания окончательного, законченного произведения.
У каждого из этих двух методов есть свои преимущества, но второй, как правило, приводит к лучшему результату. Здесь я продемонстрирую второй подход, в разработке изначального прототипа веб-аудиоплеера, с которым я познакомил вас в первой части этого цикла статей.
Одно из преимуществ размещения своего контента на собственном сервере – это возможность настраивать всё, с ним связанное: вместо того, чтобы вынужденно обходиться UI для аудиофайлов из SoundCloud или встроенными элементами управления браузера, мы можем создать наш собственный плеер, используя специализированные HTML5-элементы, зная лишь немного JavaScript.
Исходные элементы
Первым делом давайте убедимся, что мы в принципе можем проиграть аудиофайл на странице. Здесь я использую Трек 24 из альбома Ghosts III группы NIN под лицензией Creative Commons:
<figure id="audioplayer"> <audio controls src="24-ghosts-III.mp3"id="audiotrack"></audio> </figure>
Поскольку последние версии Firefox наряду с другими современными браузерами теперь поддерживают.mp3, здесь я использую только этот кодек. Я разместил элемент <audio> внутри <figure>, т.к. мы будем добавлять в него элементы управления вместе с текстовой расшифровкой.
Как только вы убедитесь, что аудио работает, следующей задачей будет создание собственного UI для плеера.
Работа над постепенным улучшением
Если у пользователя не запущен JavaScript, или скрипт, который мы собираемся добавить, не будет работать, то нам всё равно нужно, чтобы у пользователя был доступ к базовым элементам управления аудио. Поэтому мы удалим UI по умолчанию только в контексте нашего скрипта:
var audioPlayer = document.getElementById("audioplayer"), audioTrack = document.getElementById("audiotrack"), playButton = document.createElement("button"); playButton.type = "button"; audioPlayer.appendChild(playButton); audioTrack.removeAttribute("controls");
Добавленный внизу HTML-страницы, этот скрипт фактически сокращает наш аудиоплеер до простого элемента <button>. Прямо сейчас кнопка проигрывания не содержит никакого текста внутри себя. Но мы планируем часто менять текст в элементах «button», поэтому будет правильно поместить этот скрипт в функцию:
function setText(el,text) { el.innerHTML = text; }
Теперь мы легко можем установить текст для любого HTML-элемента.
setText(playButton,"Play");
Далее нам нужно заставить кнопку реально что-то делать:
playButton.addEventListener("click", player); function player() { if (audioTrack.paused) { setText(playButton,"Pause"); audioTrack.play(); } else { setText(playButton,"Play"); audioTrack.pause(); } }
Заметьте, что мы не пытаемся сделать отдельные функции для «play» и «stop», а мыслим в категориях действия кнопки.
Создание кнопки «Mute»
Также нам необходимо создать элементы управления для громкости звука. Самое простое – это сделать кнопку «Mute», которая использует шаблон, очень похожий на шаблон кнопки Play/Pause:
var muteButton = document.createElement("button"); setText(muteButton,"Mute"); muteButton.type = "button"; audioPlayer.appendChild(muteButton); muteButton.addEventListener("click", muter); function muter() { if (audioTrack.volume == 0) { setText(this,"Mute"); audioTrack.volume = 1; } else { setText(this,"Unmute"); audioTrack.volume = 0; } }
Эта функция немного сырая: когда звук включен, она устанавливает уровень громкости для аудио в его абсолютный максимум (насколько позволяет система), но на данный момент это допустимо.
Создание регулятора громкости
Далее нам нужен более точный регулятор громкости. Очевидный кандидат для этого элемента управления UI – элемент «range
».
volumeSlider = document.createElement("input"); volumeSlider.type = "range";
Элементу «range
» через JavaScript нужно установить множество атрибутов, что мы могли бы сделать тем же способом, которым я только что установил тип для нового поля… то, что мы делаем прототип, еще не значит, что нам нужно идти длинным путем. В идеале, как минимум часть нашего кода будет перенесена в финальную версию медиаплеера, так что мы должны искать эффективные способы написания нашего кода прямо сейчас.
К сожалению, не существует метода setAttributes
, который позволял бы устанавливать значения нескольких атрибутов одновременно. Тем не менее, для этого мы можем сделать довольно простую функцию:
function setAttributes(el, attrs) { for(var key in attrs){ el.setAttribute(key, attrs[key]); } }
Теперь можно устанавливать атрибуты для регулятора диапазона громкости при помощи одной строки кода:
setAttributes(volumeSlider, { "type": "range", "min": "0", "max": "1", "step": "any", "value": "1" });
Заметьте, что минимальное и максимальное значение регулятора соответствуют значениям функции muter
()
.
Далее мы добавим обработчик событий к полю регулятора, установив громкость аудиотрека в значение регулятора внутри анонимной функции:
volumeSlider.addEventListener("input", function(){ audioTrack.volume = volumeSlider.value; });
Здесь мы сталкиваемся с первой серьёзной проблемой: с функциональной точки зрения, снижение громкости регулятора до 0 и нажатие на «Mute» – это одно и тоже, так что изменение состояния должно отображаться в кнопке. Как нам это сделать?
Синхронизация элементов управления
Моим решением будет абстрагироваться от кнопок и смотреть на любые изменения в громкости самого элемента <audio> :
audioTrack.addEventListener('volumechange', volumizer); function volumizer() { if (audioTrack.volume == 0) setText(muteButton,"Unmute"); } else { setText(muteButton,"Mute"); } }
Осталась ещё одна вещь, которую нужно исправить. Когда музыкальный трек заканчивается, музыка должна возвращаться к началу, а кнопка воспроизведения должна отображать «Play» вместо «Pause» или «Stop»:
audioTrack.addEventListener('ended', finish); function finish() { audioTrack.currentTime = 0; setText(playButton,"Play"); }
Вот и всё! Весь код, с незначительным улучшением в функции muter
()
, представлен ниже; я также предоставил ссылку с более усовершенствованной версией плеера на Codepen. Я покажу как добиться улучшения в этой версии плеера в следующих двух статьях этого цикла.
function player() { if (audioTrack.paused) { setText(this, "Stop"); audioTrack.play(); } else { setText(this,"Play"); audioTrack.pause(); } } function setText(el,text) { el.innerHTML = text; } function finish() { audioTrack.currentTime = 0; setText(playButton,"Play"); } function volumizer() { if (audioTrack.volume == 0) { setText(muteButton,"Unmute"); } else { setText(muteButton,"Mute"); } } function muter() { if (audioTrack.volume == 0) { audioTrack.volume = restoreValue; volumeSlider.value = restoreValue; } else { audioTrack.volume = 0; restoreValue = volumeSlider.value; volumeSlider.value = 0; } } function setAttributes(el, attrs) { for(var key in attrs){ el.setAttribute(key, attrs[key]); } } var audioPlayer = document.getElementById("audioplayer"), audioTrack = document.getElementById("audiotrack"), playButton = document.createElement("button"), muteButton = document.createElement("button"), volumeSlider = document.createElement("input"); setText(playButton, "Play"); setText(muteButton, "Mute"); setAttributes(playButton, { "type": "button" }); setAttributes(muteButton, { "type": "button" }); setAttributes(volumeSlider, { "type": "range", "min": "0", "max": "1", "step": "any", "value": "1" }); audioPlayer.appendChild(volumeSlider); audioPlayer.appendChild(muteButton); audioPlayer.appendChild(playButton); audioTrack.removeAttribute("controls"); playButton.addEventListener("click", player, false); muteButton.addEventListener("click", muter, false); volumeSlider.addEventListener("input", function(){ audioTrack.volume = volumeSlider.value; }, false); audioTrack.addEventListener('volumechange', volumizer, false); audioTrack.addEventListener('ended', finish, false);
Примечание
Этот код предполагает, что, как только скрипт загрузился, все условия окажутся идеальными: что браузер поддерживает HTML5 и все функции API, которые мы использовали, и что аудиотрек загрузился тотчас же.. Но это не всегда так: например, Android 2 и ниже не поддерживает event
.ended
для аудио. Существуют способы обойти это и множество фолбеков, которые мы могли бы добавить, но я не буду уделять им внимание сегодня.
P.S. Это тоже может быть интересно:
None Found
спс очен помог, а продолженя будет? там загрузчик не хватает только
Да, есть третья часть.