Веб-программирование

Создаем пользовательский HTML5 видео плеер при помощи CSS3 и jQuery

Создаем пользовательский HTML5 видео плеер при помощи CSS3 и jQuery
Поделиться в соцсетях:

Элемент HTML5 <video> уже поддерживается большинством современных браузеров, и даже IE поддерживает начиная с версии 9. Есть много преимуществ в том, что видео проигрывается в самом браузере без использования плееров сторонних производителей (см. статью Введение в HTML5 video Брюса Лоусона), поэтому многие разработчики пытаются начать использовать эту возможность как можно скорее. Но есть несколько препятствий к этому,  в первую очередь, это проблемы с поддержкой  кодеков в каждом браузере, тут разногласия между Opera / Firefox и IE / Safari. Но это не может быть серьезной проблемой в течение длительного времени, Google не так давно выпустил кодек VP8, и Opera, Firefox, Chrome и IE9 уже имеют поддержку этого формата, да и Flash также может проигрывать VP8. Это означает, что в скором времени мы сможем создать единую версию видео, которое будет проигрываться при помощи тега <video> в большинстве браузеров и Flash Player.

Другим серьезным препятствием для использования является создание пользовательского HTML5 <video> плеера - это то, где flash на данный момент единственное решение и в настоящее время имеет преимущество, с мощным IDE, Flash обеспечивает простой интерфейс для создания пользовательского компонента видеоплеера. Если мы хотим создать собственный плеер для элемента HTML5 <video>, то мы должны писать все это на HTML5, CSS3, JavaScript и т.д.

И это то, о чем будет статья. Мы рассмотрим как создать легкий пользовательский HTML5 <video> плеер, включая создание для этого простого плагина jQuery, выбор элементов управления и настройка внешнего вида при помощи CSS.

В этой статье мы рассмотрим:

  1. Элементы управления видео
  2. Основы разметки элементов управления
  3. Создание плагина JQuery
  4. Внешний вид плеера
  5. Создание тем для плеера

Мы будем использовать jQuery для упрощения манипуляций DOM, и jQuery UI для создания ползунков управления, которые мы будем использовать для перемотки видео и изменения уровня громкости.

Элементы управления видео

Как профессиональные веб-дизайнеры, мы хотим создать видеоплеер, который будет выглядеть одинаково во всех браузерах. Однако, каждый браузер предоставляет свой собственный, по разному выглядящий, видео плеер, от минималистичного в Firefox и Chrome, до более навороченного в Opera и Safari (см. рисунок 1). Если мы хотим, чтобы наши элементы управления выглядели одинаково во всех браузерах, а также соответствовали нашему дизайну, мы должны создать наши собственные элементы управления с нуля. Это не так сложно, как кажется.

Рисунок 1. Встроенные элементы управления видео в различных браузерах

Все медиа-элементы в HTML5 имеют поддержку API медиа-элементов , к которому мы можем получить доступ при помощи  JavaScript и использовать для создания таких функций, как воспроизведение, пауза и т.д.  Элементы управления мы можем создать с помощью HTML, CSS, SVG.
Основная разметка элементов управления

Во-первых, нам нужно создать собственно саму разметку для элементов управления. Нам нужна кнопка Play/Pause, панель поиска, таймер и регулятор громкости. Мы вставим разметку для элементов управления после элемента <video>, и обернем их в блок с классом ghinda-video-controls.

<div class="ghinda-video-controls">
    <a class="ghinda-video-play" title="Play/Pause"></a>
    <div class="ghinda-video-seek"></div>
    <div class="ghinda-video-timer">00:00</div>
    <div class="ghinda-volume-box">
        <div class="ghinda-volume-slider"></div>
        <a class="ghinda-volume-button" title="Mute/Unmute"></a>
    </div>
</div>

Мы использовали классы вместо ID для всех элементов, чтобы иметь возможность использовать этот же код для нескольких видео-плееров на одной странице.
Создание плагина jQuery для плеера

После создания разметки, мы будет связывать наши элементы с API медиа-элементами, для того, чтобы управлять нашим видео. Как было отмечено выше, для этого мы напишем плагин jQuery.

Примечание автора: Я надеюсь, что вы знакомы с основами JQuery и JavaScript, поэтому я лишь вкратце объясню сценарий. Если вам нужна дополнительная информация по этим вопросам, см. Craig Buckler How to develop a jQuery plugin, и раздел  JavaScript section of the Opera web standards curriculum.

$.fn.gVideo = function(options) {
    // build main options before element iteration
    var defaults = {
        theme: 'simpledark',
        childtheme: ''
    };
    var options = $.extend(defaults, options);
    // iterate and reformat each matched element
    return this.each(function() {
        var $gVideo = $(this);

    //create html structure
    //main wrapper
    var $video_wrap = $('<div></div>').addClass('ghinda-video-player').addClass(options.theme).addClass(options.childtheme);
    //controls wraper
    var $video_controls = $('<div class="ghinda-video-controls"><a class="ghinda-video-play" title="Play/Pause"></a><div class="ghinda-video-seek"></div><div class="ghinda-video-timer">00:00</div><div class="ghinda-volume-box"><div class="ghinda-volume-slider"></div><a class="ghinda-volume-button" title="Mute/Unmute"></a></div></div>');                       
    $gVideo.wrap($video_wrap);
    $gVideo.after($video_controls);

Здесь мы используем jQuery для создания динамически разметки видеоплеера (но не сам проигрыватель), а также удаляем атрибут controls как только скрипт загружается. Это для того, что в случае, если пользователь отключил JavaScript, эти элементы управления будут бесполезны, и он/она не сможет воспользоваться нативными элементами управления браузера для элемента видео. Плеер будет использовать наши пользовательские элементы управления только после того,  как скрипт успешно загрузился.

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

//get newly created elements
var $video_container = $gVideo.parent('.ghinda-video-player');
var $video_controls = $('.ghinda-video-controls', $video_container);
var $ghinda_play_btn = $('.ghinda-video-play', $video_container);
var $ghinda_video_seek = $('.ghinda-video-seek', $video_container);
var $ghinda_video_timer = $('.ghinda-video-timer', $video_container);
var $ghinda_volume = $('.ghinda-volume-slider', $video_container);
var $ghinda_volume_btn = $('.ghinda-volume-button', $video_container);

$video_controls.hide(); // keep the controls hidden

Мы получаем каждый элемент управления по его классу, а затем их скрываем пока все не будет готово.

Теперь для управления Play/Pause:

var gPlay = function() {
    if ($gVideo.attr('paused') == false) {
        $gVideo[0].pause();                   
    } else {                   
        $gVideo[0].play();               
    }
};

$ghinda_play_btn.click(gPlay);
$gVideo.click(gPlay);

$gVideo.bind('play', function() {
 $ghinda_play_btn.addClass('ghinda-paused-button');
});

$gVideo.bind('pause', function() {
 $ghinda_play_btn.removeClass('ghinda-paused-button');
});

$gVideo.bind('ended', function() {
    $ghinda_play_btn.removeClass('ghinda-paused-button');
});

Мы также добавляем и удаляем классы из наших кнопкок, чтобы изменить внешний вид, в зависимости от состояния видео (воспроизведение или пауза).

Для создания ползунка поиска мы будем использовать jQuery UI Slider component.

var createSeek = function() {
    if ($gVideo.attr('readyState')) {
        var video_duration = $gVideo.attr('duration');
        $ghinda_video_seek.slider({
            value: 0,
            step: 0.01,
            orientation: "horizontal",
            range: "min",
            max: video_duration,
            animate: true,                   
            slide: function(){                        
                seeksliding = true;
            },
            stop:function(e,ui){
                seeksliding = false;                       
                $gVideo.attr("currentTime",ui.value);
            }
        });
        $video_controls.show();                   
    } else {
        setTimeout(createSeek, 150);
    }
};

createSeek();

Как видите, мы используем рекурсивную функцию, при чтении ReadyState видео. Мы должны продолжать запрашивать видео, пока оно не готово, иначе мы не сможем определить продолжительность, и не сможем создать ползунок. Как только видео будет готово, мы инициализируем ползунок, а также отображаем элементы управления.

Далее мы создадим таймер.

var gTimeFormat=function(seconds) {
    var m=Math.floor(seconds/60)<10?"0"+Math.floor(seconds/60):Math.floor(seconds/60);
    var s=Math.floor(seconds-(m*60))<10?"0"+Math.floor(seconds-(m*60)):Math.floor(seconds-(m*60));
    return m+":"+s;
};

var seekUpdate = function() {
    var currenttime = $gVideo.attr('currentTime');
    if(!seeksliding) $ghinda_video_seek.slider('value', currenttime);
    $ghinda_video_timer.text(gTimeFormat(currenttime));                           
};

$gVideo.bind('timeupdate', seekUpdate);

Здесь мы используем функцию seekUpdate, чтобы получить атрибут CurrentTime видео и функцию gTimeFormat для форматирования полученного текущего значения.

Для регулировки громкости, мы будем также использовать jQuery UI slider и пользовательскую функцию для кнопки регулировки громкости видео.

$ghinda_volume.slider({
    value: 1,
    orientation: "vertical",
    range: "min",
    max: 1,
    step: 0.05,
    animate: true,
    slide:function(e,ui) {
        $gVideo.attr('muted',false);
        video_volume = ui.value;
        $gVideo.attr('volume',ui.value);
    }
});

var muteVolume = function() {
    if ($gVideo.attr('muted')==true) {
        $gVideo.attr('muted', false);
        $ghinda_volume.slider('value', video_volume);
        $ghinda_volume_btn.removeClass('ghinda-volume-mute');                   
    } else {
        $gVideo.attr('muted', true);
        $ghinda_volume.slider('value', '0');
        $ghinda_volume_btn.addClass('ghinda-volume-mute');
    };
};

$ghinda_volume_btn.click(muteVolume);

Наконец, мы собираемся удалить атрибут controls из <video>, потому что к этому моменту наши собственные пользовательские элементы управления настроены и мы хотим использовать их вместо используемых в браузере по умолчанию.

$gVideo.removeAttr('controls');

Теперь, когда наш плагин готов, мы можем вызвать его для элемента video.

$('video').gVideo();

Этот код вызовет плагин для всех видео-элементов на странице.

Внешний вид

А теперь самое интересное, внешний вид видео плеера. Как только плагин будет готов, настройка элементов управления очень проста при помощи CSS. Как вы уже заметили, мы еще не добавили стили для элементов управления и для этого мы будем использовать CSS3.

Во-первых, мы добавим несколько стилей для основного контейнера видеоплеера.

.ghinda-video-player {
    float: left;
    padding: 10px;
    border: 5px solid #61625d;

    -moz-border-radius: 5px; /* FF1+ */
    -ms-border-radius: 5px; /* IE future proofing */
    -webkit-border-radius: 5px; /* Saf3+, Chrome */
    border-radius: 5px; /* Opera 10.5, IE 9 */

    background: #000000;
    background-image: -moz-linear-gradient(top, #313131, #000000); /* FF3.6 */
    background-image: -o-linear-gradient(top, #313131, #000000); /* Opera 10.60 */
    background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #313131),color-stop(1, #000000)); /* Saf4+, Chrome */

    box-shadow: inset 0 15px 35px #535353;
}

Мы указали float:left, чтобы не допустить его растягивания на всю ширину плеера, и чтобы ширина его была равна фактической ширине элемента видео.

Далее мы выстроим все элементы управления влево. Мы будем использовать opacity и transitions для Play/Pause и кнопки регулировки звука, чтобы создать симпатичный эффект при наведении курсора.

.ghinda-video-play {
    display: block;
    width: 22px;
    height: 22px;
    margin-right: 15px;
    background: url(../images/play-icon.png) no-repeat;   

    opacity: 0.7;

    -moz-transition: all 0.2s ease-in-out; /* Firefox */
    -ms-transition: all 0.2s ease-in-out; /* IE future proofing */
    -o-transition: all 0.2s ease-in-out;  /* Opera */
    -webkit-transition: all 0.2s ease-in-out; /* Safari and Chrome */
    transition: all 0.2s ease-in-out;
}

.ghinda-paused-button {
    background: url(../images/pause-icon.png) no-repeat;
}

.ghinda-video-play:hover {   
    opacity: 1;
}

Я уверен, что вы внимательно прочитали первую часть статьи о JavaScript, и помните, что мы добавляли и удаляли классы для кнопки Play/Pause в зависимости от состояния видео (воспроизведение или пауза). Вот почему класс ghida-paused-button переопределяет свойство background класса ghinda-video-play.

Теперь бегунки. Как мы говорили раньше, мы используем jQuery UI slider для перемотки видео и регулировки уровня громкости. Этот компонент имеет свои собственные стили, определенные в jQuery UI stylesheet, но мы будем полностью переопределять их, для того, чтобы он соответствовал дизайну плеера.

.ghinda-video-seek .ui-slider-handle {
    width: 15px;
    height: 15px;
    border: 1px solid #333;
    top: -4px;

    -moz-border-radius:10px;
    -ms-border-radius:10px;
    -webkit-border-radius:10px;
    -o-border-radius:10px;
    border-radius:10px;   

    background: #e6e6e6;
    background-image: -moz-linear-gradient(top, #e6e6e6, #d5d5d5);
    background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #e6e6e6),color-stop(1, #d5d5d5));

    box-shadow: inset 0 -3px 3px #d5d5d5;   
}

.ghinda-video-seek .ui-slider-handle.ui-state-hover {
    background: #fff;
}

.ghinda-video-seek .ui-slider-range {
    -moz-border-radius:15px;
    -ms-border-radius:15px;
    -webkit-border-radius:15px;
    -o-border-radius:10px;
    border-radius:15px;

    background: #4cbae8;
    background-image: -moz-linear-gradient(top, #4cbae8, #39a2ce);
    background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #4cbae8),color-stop(1, #39a2ce));

    box-shadow: inset 0 -3px 3px #39a2ce;
}

В настоящее время регулятор громкости виден всё время. Мы изменим это, сделаем его скрытым по-умолчанию, и проявляется он будет только тогда, когда мы наведем мышь на кнопку регулировки звука, чтобы он выглядел немного более динамичным и аккуратным.

.ghinda-volume-box {   
    height: 30px;

    -moz-transition: all 0.1s ease-in-out; /* Firefox */
    -ms-transition: all 0.1s ease-in-out; /* IE future proofing */
    -o-transition: all 0.2s ease-in-out;  /* Opera */
    -webkit-transition: all 0.1s ease-in-out; /* Safari and Chrome */
    transition: all 0.1s ease-in-out;
}

.ghinda-volume-box:hover {   
    height: 135px;
    padding-top: 5px;
}

.ghinda-volume-slider {   
    visibility: hidden;
    opacity: 0;

    -moz-transition: all 0.1s ease-in-out; /* Firefox */
    -ms-transition: all 0.1s ease-in-out;  /* IE future proofing */
    -o-transition: all 0.1s ease-in-out;  /* Opera */
    -webkit-transition: all 0.1s ease-in-out; /* Safari and Chrome */
    transition: all 0.1s ease-in-out;
}

.ghinda-volume-box:hover .ghinda-volume-slider {
    position: relative;
    visibility: visible;
    opacity: 1;
}

Когда курсор мыши наводится на кнопку регулировки громкости, её высота увеличивается при помощи transitions.

С базовыми знаниями CSS и некоторыми новыми свойствами CSS3, мы уже создали удобный интерфейс для нашего плеера, внешний вид его можно увидеть на рисунке 2:

Рисунок 2: Наш готовый видеоплеер.

Создание тем для плеера

Как вы могли заметить, при создании плагина jQuery, мы определили набор опций по умолчанию. Эти опции theme и childtheme, они могут быть изменены при вызове плагина, что позволяет нам с легкостью применять пользовательские темы.

Тема представляет собой совершенно новый свод правил CSS для каждого плеера. childtheme представляет собой набор правил CSS, который опирается на правила существующей темы, и добавляет или перезаписывает стили "родительской" темы.

Мы можем указать оба варианта или только один, при вызове jQuery плагина.

$('video').gVideo({
    childtheme:'smalldark'
});

В приведенном выше примере мы вызываем плагин с темой smalldark. Сначала будет применяться родительская дефолтовая тема, а затем применится дочерняя тема поверх её, переопределив некоторую часть правил, установленных в родительской теме. См. рисунок 3 для темы Smalldark.

Рисунок 3: Тема Smalldark в действии.

Вы можете проверить то что у нас получилось в действии, или скачать исходный код (8.5MB, ZIP-файл) и экспериментировать с ним дальше.

Заключение

Создание собственного видеоплеера с HTML5, JavaScript и CSS 3 довольно легко. JavaScript используется только для создания функциональности элементов управления, а CSS3 за все, что включает в себя внешний вид плеера. В результате мы получаем мощное, легко настраиваемое, решение.

Новый комментарий

Имя:
Для редактирования комментария осталось 10 минут
Комментарии отсутствуют