Ion.Sound is a plugin for playing sounds. Creation and features

  • Tutorial


Hi, lately I often have to handle all sorts of events on websites, whether it's chat messages, notifications, reminders, incoming mail, etc. These events are becoming more and more and they all want to somehow attract the user's attention to themselves. I am sophisticated in different types of animation, elements jump, blink, spin, etc. etc. At some point, I realized that all these tricks are useless if the user, for example, turned away from the screen or even switched to the next tab in the browser. The solution came quickly - sounds. But how to do that? A little googling, I did not find any simple and convenient solutions to this problem. But he found heaps of audio / video players of all kinds. So I decided to write my own plugin for playing sounds from events.

As it turned out, html5 already has a suitable API, and this is an audio element. His cross-browser support turned out to be very good . In JavaScript, this element is accessible through the Audio constructor and has many settings. In general, we arm ourselves with a description and begin.

I will not describe the intricacies of creating a jQuery plugin, there are a lot of articles on this topic on Habré, I will describe the necessary parts right away:

Making sounds


Despite the fact that the audio element supports a lot of browsers, everything is not so rosy with the support of codecs. Mp3 is not understood by everyone; therefore, every sound that we want to use will need to be additionally converted to Ogg. This can be done very simply right online. For example here or here .

Connect sounds to our script:


First, declare the variables we need:
var settings = {},
    soundsNum,
    canMp3,
    url,
    i,

    sounds = {},
    playing = false;


Let's create a function that takes the sound file name argument
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;     // устанавливаем громкость
};

* More about canPlayType method

Playing sounds:


Create another function that takes the sound file name argument
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();
            }
        }

    }
};


Initializing the plugin and starting playback:


// Создаем функцию, запускающую наш плагин
$.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);
    };
};


That's all. Of course, this plugin can be expanded further, for example, provide the ability to set an individual volume for each of the sounds, etc. But in general, he meets his purpose - to reproduce short sounds to illustrate all sorts of events.

Afterword


Sounds are a very powerful tool to attract user attention. But this instrument is also very dangerous, since people do not like extra sounds or sounds too loud. And I advise you to be very careful in connecting sound effects to your websites. No need to attach sounds to every click, this is superfluous. It is desirable only to very important and necessary events. And try to make the volume lower, you don’t want the user to jump in the chair and spill tea on himself? :-)

Plugin info


A fully finished plugin can be viewed here: