Интернет магазин шабонов
Форма входа

Бесплатный раздел

Уважаемые пользователи!
Доводим до вашего сведения, что мы не занимаемся обучениями по системе uCoz и настройками Ваших сайтов.
Подобные просьбы и вопросы - будут игнорироваться!

Как сделать видео-плеер на HTML5 Video

Дата добавления: 26.12.2013 - 06:40
Добавил: Buger
Количество просмотров: 1139
Количество комментариев: 0
Рейтинг материала: 5.0 / 1
Как сделать видео-плеер на HTML5 Video
БЕСПЛАТНО
Для скачивания файлов, необходима авторизация или регистрация на нашем ресурсе.
рейтинг 5.0
/
голосов 1
Сегодня мы рассмотрим задачу создания собственного видео-плеера на HTML5 Video.
Напомню, что video-элемент сам по себе уже обеспечивает необходимый набор контролов для управления проигрыванием. Чтобы была видна панель управления воспроизведением, достаточно указать атрибут controls.
Код
<video src="trailer_480p.mp4" width="480" height="270" poster="poster.gif" controls />

Однако, как я отмечал в вводной статье, со стандартными контролами есть проблема, которая заключается как раз в том, что выглядят они нестандартно. Другими словами, в каждом браузере они выглядят по-своему (проверить, как выглядят контролы в разных браузерах, можно на примере Video Format Support на ietestdrive.com — просто откройте его в двух-трех различных браузерах).

API для управления воспроизведением

Стандарт HTML5 для работы с видео вводит в DOM новый интерфейс — HTMLVideoElement, наследующий в свою очередь интерфейс HTMLMediaElement.

Интерфейс HTMLMediaElement

Это общий интерфейс для обоих медиа-элементов (аудио и видео), описывающий доступ к базовым возможностями работы с медиа-контентом: контроль источника контента, управление воспроизведением, изменение уровня звука и обработка ошибок. Основные свойства и методы, которые нам понадобятся:

Состояние сети и готовность к работе
src — ссылка (url) на воспроизводимый контент
buffered — буферизованные куски видео

Воспроизведение и контролы
currentTime — текущий момент проигрывания (с.)
duration — длительность медиа-контента (с.)
paused — находится ли воспроизведение на паузе
ended — закончилось ли проигрывание
muted — включение/выключение звука
volume — уровень звука [0, 1]
play() — начать проигрывание
pause() — поставить на паузу

События
oncanplay — можно начать проигрывание
ontimeupdate — изменена позиция проигрывания
onplay — запущено проигрыв
onpause — нажата пауза
onended — воспроизведение закончилось

Важно: это далеко не все методы и свойства, выставляемые через интерфейс HTMLMediaElement.

Интерфейс HTMLVideoElement

Видео отличается от аудио несколькими дополнительными свойствами:
width и height — ширина и высота контейнера для проигрывания видео;
videoWidth и videoHeight — внутреннее значение ширины и высоты видео, если размеры не известны, равны 0;
poster — ссылка на картинку, которую можно показывать, пока видео недоступно (обычно это один
из первых непустых кадров).

Разница между width/height и videoWidth/videoHeight в том, что последние — это собственные характеристики видео, в частности, с учетом соотношения сторон и других характеристик, в то время как контейнер для видео может быть любых размеров (больше, меньше, с другой пропорцией).

Play & Pause

Создание нашего собственного видео-плеера мы начнем с простой задачи: научимся запускать видео на проигрывание и останавливать воспроизведение. Для этого нам понадобятся методы play() и pause() и несколько свойств, описывающих текущее состояние видео-потока (мы также будем использовать библиотеку jQuery, не забудьте ее подключить).

Первым делом нам необходим video-элемент, которым мы хотим управлять, и элемент на который можно нажимать для управления текущим состоянием:
Код
<div>
    <video id="myvideo" width="480" height="270" poster="poster.gif" >
        <source src="trailer_480p.mp4" type='video/mp4;codecs="avc1.42E01E, mp4a.40.2"' />
        <source src="trailer_480p.webm" type='video/webm; codecs="vorbis,vp8"'/>
    </video>
</div>
<div id="controls">
    <span id="playpause" class="paused" >Play</span>
</div>

Код
#controls span {
    display:inline-block;
}
        
#playpause {
    background:#eee;
    color:#333;
    padding:0 5px;
    font-size:12pt;
    text-transform:uppercase;
    width:50px;
}

Обратите внимание на инвертирование состояния кнопки (paused) и действия (play).

Теперь надо добавить немного js-кода, чтобы нажатие на кнопку play переключало ее состояние и соответственно запускало видео-ролик или ставило его на паузу:
Код
$(document).ready(function(){
    var controls = {
        video: $("#myvideo"),
        playpause: $("#playpause")                 
    };
                
    var video = controls.video[0];
               
    controls.playpause.click(function(){
        if (video.paused) {
            video.play();
            $(this).text("Pause");    
        } else {
            video.pause();
            $(this).text("Play");
        }
                
        $(this).toggleClass("paused");
    });
});

При желании можно сразу добавить несколько css-стилей для кнопок управления и их различных состояний и...

… казалось бы, все уже замечательно работает, но не тут-то было! Есть несколько мелочей, которые нам также нужно учесть.

Проигрывание сначала

Во-первых, нам нужно правильно обработать окончание проигрывания видео-ролика (если, конечно, оно не зациклено), и в этот момент нужно переключить кнопки управления так, чтобы вместо состояния «pause» было состояние «play»:
Код
video.addEventListener("ended", function() {
    video.pause();
    controls.playpause.text("Play");
    controls.playpause.toggleClass("paused");
});

Контекстное меню

Во-вторых, браузеры обычно добавляют возможность управлять воспроизведением через контекстное меню. Это означает, что пользователь, вообще говоря, может что-то изменить в обход наших элементов управления. Этот момент нужно также отловить и внести необходимые изменения во внешний вид контролов. Для этого достаточно подписаться на события onplay и onpause.
Код
video.addEventListener("play", function() {
    controls.playpause.text("Pause");
    controls.playpause.toggleClass("paused");
});
                
video.addEventListener("pause", function() {
    controls.playpause.text("Play");
    controls.playpause.toggleClass("paused");
});

Так как у нас становится многовато мест, где меняется внешний вид, самое время попутно произвести небольшой рефакторинг, убрав из изначального переключения режимов теперь уже дублирующую смену внешнего состояния:
Код
var controls = {
    ...  
    togglePlayback: function() {
        (video.paused) ? video.play() : video.pause();
    }
    ...
};
                
controls.playpause.click(function(){
    controls.togglePlayback();
});

Кликабельное видео

Наконец, наверняка, нам захочется, чтобы проигрывание и пауза переключались по нажатию на само видео, поэтому нужно добавить еще несколько строчек:
Код
controls.video.click(function() {
    controls.togglePlayback();
});

Текущий результат:



Прогресс

Теперь давайте перейдем к отображению прогресса проигрывания. Для начала необходимо добавить несколько элементов, которые будут использоваться для отображения текущего состояния и управления текущей позицией:
Код
<span id="progress">
    <span id="total">
        <span id="buffered"><span id="current">​</span></span>
    </span>
</span>
<span id="time">
    <span id="currenttime">00:00</span> /
    <span id="duration">00:00</span>
</span>

И соответствующие стили:
Код
#progress {
    width:290px;
}
            
#total {
    width:100%;                
    background:#999;
}
            
#buffered {
    background:#ccc;
}
            
#current {
    background:#eee;
    line-height:0;
    height:10px;
}
            
#time {
    color:#999;
    font-size:12pt;
}

И несколько ссылок на соответствующие элементы для быстрого доступа в объект controls:
Код
var controls = {
    ...
    total: $("#total"),
    buffered: $("#buffered"),
    progress: $("#current"),
    duration: $("#duration"),
    currentTime: $("#currenttime"),
    hasHours: false,
    ...
};

Первым делом, нам нужно понять, какова длительность ролика — для этого у video-элемента есть свойство duration. Отследить это значение можно, например, в момент готовности ролика к проигрыванию — по событию oncanplay:
Код
video.addEventListener("canplay", function() {
    controls.hasHours = (video.duration / 3600) >= 1.0;                    
    controls.duration.text(formatTime(video.duration, controls.hasHours));
    controls.currentTime.text(formatTime(0),controls.hasHours);
}, false);

В данном случае, мы попутно определяем, нужно ли отображать количество часов в видео-плеере (кстати, вообще говоря, спецификация предполагает, что длительность ролика может изменяться — в этот момент срабатывает событие ondurationchange, и к тому же быть бесконечной — например, при стриминге радио).

Также мы используем специальную функцию formatTime для перевода секунд в формат HH:mm:ss или mm:ss:
Код
function formatTime(time, hours) {
    if (hours) {
        var h = Math.floor(time / 3600);
        time = time - h * 3600;
                    
        var m = Math.floor(time / 60);
        var s = Math.floor(time % 60);
                    
        return h.lead0(2)  + ":" + m.lead0(2) + ":" + s.lead0(2);
    } else {
        var m = Math.floor(time / 60);
        var s = Math.floor(time % 60);
                    
        return m.lead0(2) + ":" + s.lead0(2);
    }
}
            
Number.prototype.lead0 = function(n) {
    var nz = "" + this;
    while (nz.length < n) {
        nz = "0" + nz;
    }
    return nz;
};

Для отображения процесса проигрывания нам понадобится событие ontimeupdate, срабатывающее при изменении текущего момента:

Код
video.addEventListener("timeupdate", function() {
    controls.currentTime.text(formatTime(video.currentTime, controls.hasHours));
                    
    var progress = Math.floor(video.currentTime) / Math.floor(video.duration);
    controls.progress[0].style.width = Math.floor(progress * controls.total.width()) + "px";
}, false);

Свойство currentTime выдает в секундах текущее время. Его же можно использовать, чтобы изменить время проигрывания:
Код
controls.total.click(function(e) {
    var x = (e.pageX - this.offsetLeft)/$(this).width();
    video.currentTime = x * video.duration;
});

Также будет полезным показывать буферизацию видео, для этого можно отталкиваться от события onprogress, срабатывающего при загрузке новых порций видео:
Код
video.addEventListener("progress", function() {
    var buffered = Math.floor(video.buffered.end(0)) / Math.floor(video.duration);
    controls.buffered[0].style.width =  Math.floor(buffered * controls.total.width()) + "px";
}, false);

Важный нюанс относительно свойства buffered, который нужно иметь в виду, заключается в том, что он предоставляет не просто время в секундах, а промежутки времени в виде объекта TimaRanges. В большинстве случаев это будет только один промежуток с индексом 0, и начинающийся с отметки 0c. Однако, если браузер использует HTTP range запросы к серверу, например, в ответ на попытки перейти к другим фрагментам видео-потока, промежутков может быть несколько. Также надо учитывать, что в зависимости от реализации браузер может удалять из буфера памяти уже проигранные куски видео.

Промежуточный результат:

Звук

Наконец, давайте добавим еще небольшой штрих к нашем видео-плееру — возможность включать и выключать звук. Для этого добавим небольшой контрол с динамиком
Код
<span id="volume">
    <svg id="dynamic" version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="16px" height="16px" viewBox="0 0 95.465 95.465">
        <g >
            <polygon points="39.323,20.517 22.705,37.134 0,37.134 0,62.865 22.705,62.865 39.323,79.486 "/>
            <path d="M52.287,77.218c14.751-15.316,14.751-39.116,0-54.436c-2.909-3.02-7.493,1.577-4.59,4.59
                        c12.285,12.757,12.285,32.498,0,45.254C44.794,75.645,49.378,80.241,52.287,77.218L52.287,77.218z"/>
            <path d="M62.619,89.682c21.551-22.103,21.551-57.258,0-79.36c-2.927-3.001-7.515,1.592-4.592,4.59
                        c19.08,19.57,19.08,50.608,0,70.179C55.104,88.089,59.692,92.683,62.619,89.682L62.619,89.682z"/>
            <path d="M75.48,99.025c26.646-27.192,26.646-70.855,0-98.051c-2.936-2.996-7.524,1.601-4.592,4.59
                        c24.174,24.674,24.174,64.2,0,88.871C67.956,97.428,72.545,102.021,75.48,99.025L75.48,99.025z"/>
        </g>
        </svg>
</span>

С соответствующими стилями для включенного и выключенного состояний:
Код
#dynamic {
    fill:#333;
    padding:0 5px;
}
            
#dynamic.off {
    fill:#ccc;
}

Для переключения состояния динамика нам понадобится свойство mute:
Код
controls.dynamic.click(function() {
    var classes = this.getAttribute("class");

    if (new RegExp('\\boff\\b').test(classes)) {
        classes = classes.replace(" off", "");
    } else {
        classes = classes + " off";
    }

    this.setAttribute("class", classes);
                    
    video.muted = !video.muted;
});

(Стандартные методы jQuery для переключения css-классов не работают с SVG-элементами.)
Если вы хотите также менять уровень громкости, то вам поможет свойство volume, принимающее значения в диапазоне [0, 1].

Финальный результат:



Что еще...

Помимо того, что вы легко можете настроить стили элементов управления по своему усмотрению, есть еще несколько важных моментов, которые остаются за пределами этой статьи, но о которых полезно помнить в реальном проекте:
  • проверка поддержки браузером HMTL5 Video,
  • программное определение и переключение поддерживаемых кодеков,
  • поддержка субтитров, в том числе для обеспечния accessibility
Также не забудьте, что привязку событий к элементам управления нужно делать после того, как стало понятно, что видео доступно для проигрывания (oncanplay):
Код
video.addEventListener("canplay", function() {
    ...
}, false);

Либо нужно делать соответствующие проверки или отлавливать возможные исключения. Исключения вообще надо отлавливать, например, событие onerror, возникающее при ошибке загрузки видео-потока :)

Из дополнительных опций, которые могут вам понадобиться: изменение скорости проигрывания. Для этого есть свойство playbackRate и соответствующее событие onratechange.



Источник: http://habrahabr.ru
Добавлять комментарии могут только зарегистрированные пользователи.