Ion.Sound — плагин для воспроизведения звуков. Создание и особенности

  • Tutorial


Привет, последнее время мне частенько приходится обрабатывать всякие события на сайтах, будь то сообщения в чатах, оповещения, напоминания, входящая почта и т.д. Этих событий становится все больше и больше и все они хотят как то привлечь внимание пользователя к себе. Я изощряюсь в разных видах анимации, элементы прыгают, мигают, крутятся и т.д. и т.п. В какой-то момент я понял, что все эти приемы бесполезны, если пользователь, например, отвернулся от экрана или вовсе перешел на соседнюю вкладку в браузере. Решение пришло быстро — звуки. Но как это сделать? Немножко погуглив я не нашел каких либо простых и удобных решений этой задачи. Зато нашел кучи аудио/видео плееров всевозможных видов. Вот я и решил написать собственный плагин для воспроизведения звуков у событий.

Как оказалось в html5 уже есть подходящий API, и это элемент audio. Его кроссбраузерная поддержка оказалась очень даже неплохой. В JavaScript этот элемент доступен через конструктор Audio и обладает множеством настроек. В общем вооружимся описанием и начнем.

Описывать тонкости создания jQuery-плагина я не буду, на Хабре есть полно статей на эту тему, опишу сразу нужные части:

Создание звуков


Несмотря на то что элемент аудио поддерживает очень много браузеров, с поддержкой кодеков все обстоит не так уж радужно. Mp3 понимают не все, по этому каждый звук, что мы захотим использовать нужно будет дополнительно конвертировать в Ogg. Это можно сделать очень просто прямо онлайн. Например тут или тут.

Подключение звуков к нашему сценарию:


Вначале объявим нужные нам переменные:
var settings = {},
    soundsNum,
    canMp3,
    url,
    i,

    sounds = {},
    playing = false;


Создадим функцию, принимающую аргументом имя звукового файла
var createSound = function(name){
    // В объект sounds записываем создаваемые экземпляры Audio
    sounds[name] = new Audio();
    
    // Переменная canMp3 - определяет может ли браузер проигрывать mp3,
    // для этой проверки есть специальный метод canPlayType *.
    // Метод при желании может провести проверку поддержки любого формата,
    // ну а мы проверим поддержку mp3
    canMp3 = sounds[name].canPlayType("audio/mp3");

    // У метода canPlayType есть интересная особенность, он не определяет наличие кодека
    // со стопроцентной точностью, вместо этого он возвращает строку "probably", "maybe" или "".
    // В общем верим ему на слово и выбираем mp3 или ogg
    if(canMp3 === "probably" || canMp3 === "maybe") {
        url = settings.path + name + ".mp3";
    } else {
        url = settings.path + name + ".ogg";
    }

    $(sounds[name]).prop("src", url);          // устанавливаем ссылку на звуковой файл
    sounds[name].load();                       // для старых браузеров потребуется теперь загрузить этот звук
    sounds[name].volume = settings.volume;     // устанавливаем громкость
};

* Подробнее о методе canPlayType

Проигрывание звуков:


Создаем еще одну функцию, принимающую аргументом имя звукового файла
var playSound = function(name){
    var $sound = sounds[name],
        playingInt;

    // проверяем есть ли у нас что проигрывать
    if(typeof $sound === "object" && $sound !== null) {

        // Вначале о переменной settings.multiPlay. Эта переменная была задумана чтобы ограничить возможность
        // бесконтрольного воспроизведения звуков. Если установить ей значение false, то плагин будет
        // проигрывать звуки строго по одному за раз, иначе в некоторых ситуациях можно получить жуткую какофонию

        // Проверяем играет ли звук
        if(!settings.multiPlay && !playing) {
            // Запускаем воспроизведение методом play
            $sound.play();
            playing = true;

            // И запускаем интервал, ждущий окончания воспроизведения
            playingInt = setInterval(function(){
                // Чтобы понять, когда кончилось воспроизведение, существует специальная переменная ended,
                // принимает значение true, если воспроизведение файла закончилось
                if($sound.ended) {
                    clearInterval(playingInt);
                    playing = false;
                }
            }, 250);
        } else if(settings.multiPlay) {
            // Если же multiPlay включен то просто играем звук
            if($sound.ended) {
                $sound.play();
            } else {
                // Если звук еще проигрывается, пытаемся отмотать его назад, устанавливая значение 0
                // переменной currentTime, но как выяснилось, это переменная не всегда доступна,
                // например в iOS браузерах, так что нужно проверить возможность
                try {
                    $sound.currentTime = 0;
                } catch (e) {}
                $sound.play();
            }
        }

    }
};


Инициализация плагина и запуск воспроизведения:


// Создаем функцию, запускающую наш плагин
$.pluginName = function(options){

    // загружаем и запоминаем настройки
    settings = $.extend({
        // массив имен звуковых фалов
        sounds: [
            "sound_name_1",
            "sound_name_2"
        ],

        // путь до папки со звуками
        path: "sounds/",

        // возможность воспроизведения нескольких звуков за раз
        multiPlay: true,

        // громкость в формате 0.0 - 1.0
        volume: "0.5"
    }, options);

    // определяем сколько всего звуков нужно загрузить
    soundsNum = settings.sounds.length;

    // узнаем поддерживается ли вообще конструктор Audio
    if(typeof Audio === "function" || typeof Audio === "object") {

        // и подключаем наши звуки
        for(i = 0; i < soundsNum; i += 1){
            createSound(settings.sounds[i]);
        }
    }

    // создаем метод воспроизводящий звуки по их именам
    $.pluginName.play = function(name) {
        playSound(name);
    };
};


Вот собственно и все. Конечно этот плагин можно расширять и дальше, например предусмотреть возможность задавать индивидуальную громкость для каждого из звуков и т.д. Но в целом он отвечает своему назначению — воспроизведению коротких звуков для иллюстрации всяческих событий.

Послесловие


Звуки — это очень мощный инструмент привлечения внимания пользователя. Но этот инструмент так же очень опасен, так как люди не любят лишние звуки или слишком громкие звуки. И я советую вам очень осторожно подходить к подключению звуковых эффектов для ваших веб-сайтов. Не нужно привязывать звуки к каждому клику, это лишнее. Желательно только к очень важным и нужным событиям. И старайтесь делать громкость поменьше, вы ведь не хотите чтобы пользователь подскочил в кресле и расплескал на себя чай? :-)

Информация о плагине


Полностью готовый плагин можно посмотреть здесь:
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 13
  • 0
    А на JQuery младше чем 1.9 пробовали? Там вроде бы ничего такого не используется
    • +1
      Да это я по инерции написал, чуть чуть допилить напильником и jQuery для этого плагина вообще не понадобиться.
      • 0
        Я тоже про это подумал, но раз уж используется, то почему бы и нет )) jQuery сейчас повсюду.
        Только версию там можно чуть ли не 1.6 ставить, судя по исходникам. На счет $.prop() не уверен с какой заработает, а больше там ничего практически и нет.
        • 0
          Ну да, prop в 1.6 появился, а для более древних по идее можно и attr написать.
          • +1
            Я до сих пор $.attr() использую, по инерции. И никаких проблем небыло ни разу. Правда у вас элемент не помещается в DOM. Хотя думаю, что заработает.

            Как вариант — просто через if($.fn.prop !=== undefined) решить проблему, и заявить версию гораздо ниже, т.к. я, например, использую 1.7 — 1.8 версию, ибо некоторые плагины отваливаются на 1.9 и, посмотрев на ваш, не стал бы использовать.
            • 0
              Ок, спасибо за мнение, обязательно допишу как будет время.
    • +4
      Рискну быть непонятым: но каждый раз попадая на сайт, который внезапно начинает генерировать какие-то звуки без моего участия, я мысленно отправляю создателей этого сайта в АДЪ, быстро-быстро закрываю вкладку и больше никогда не возвращаюсь к этом сайту. Считаю, что любые звуки сайт должен воспроизводить только по указанию пользователя и никак иначе.
      • 0
        Ну я и написал в послесловии то, чем может грозить бесконтрольное проигрывание звуков. Но согласитесь, в каком нибудь почтовом клиенте, например, негромкий короткий звук сообщающий о приходе нового письма будет вполне уместен.
      • 0
        Извиняюсь, но спешу напомнить про push notifications, спрашивающие разрешение пользователя на отображение и предоставляющие бОльшую информативность. Они как нельзя лучше подойдут для упомянутых чатиков. А звуки…… пусть они останутся для системных уведомлений.
        • +1
          В отличие от звуков, HTML5 Notifications API пока не так распространен, чтобы можно было его смело использовать в своих проектах.
          В тоже время, если какой-то инструмент для привлечения внимания пользователя есть, то он вполне может занять свою нишу, если приготовить его правильно. Чрезмерное использование звуков может легко все испортить, но в малых дозах, почему нет?
          • 0
            На socket io делал простенький чат, и там как раз использовать notification api браузера. Звук воспроизводился не во всех браузерах, да и сами окна нотификации достаточно разные были. В итоге отказался от нотификаций и через Ion.Sound сделал одинаковое звуковое оповещение.
        • 0
          Этих событий становится все больше и больше и все они хотят как то привлечь внимание пользователя к себе.

          Равно как и открытых вкладок в пользовательском браузере. И если все они начнут кричать «выбери карту», то привлекут внимание пользователя не хуже Центра американского английского.
          • 0
            Правила хорошего тона никто не отменял, а веб тем хорош, что почти любому сервису можно найти менее раздражающий аналог.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.