Lecaw

Учимся создавать Web-сайты

Как сделать CSS видео фильтры на HTML5 video

August 28, 2012
CSS
458hits

Как нам известно – в специфике языка программирования HTML, появился новый элемент – HTML5 video. Обычно люди используют этот элемент для встраивания видео в веб-страницы. Это очень удобно. Потому что HTML5 video предназначен для вставки видеороликов без добавления скриптов. Вы можете просто выбрать несколько видео файлов для браузеров которые поддерживают HTML5 video. Теперь, давайте представим, что мы можем использовать элемент video - для доступа к камере и микрофону. Я собираюсь показать вам, как снимать видео с веб-камеры при помощи HTML5, а также как передать это видео в объект canvas. Для видео, мы будем использовать фильтры CSS.

 Исходные файлыДЕМО

 

Сегодня мы создадим скрипт, который будет снимать видео с веб-камеры (в элементе video), в правую часть элемента video, я помещу элемент canvas, и мы будем передавать видео в объект HTML5 Canvas. Я собираюсь использовать новую функцию HTML5 - navigator.getUserMedia (). Эта функция предоставит доступ к камере и микрофону пользователя. Кроме того, прежде чем начать я хотел бы сообщить вам, что наш результат будет работать не во всех браузерах. Проверено на Chrome (я рекомендую использовать последнюю версию) и Opera (версии 12 и выше), а также в будущем должно работать и на Firefox.

Шаг 1. HTML

Наша основная HTML-разметка не содержит много кода:

index.html
<div class="warning"><h2>Native web camera streaming  (getUserMedia) is not supported in this browser.</h2></div>
  <div class="container">
<h3>Current filter is: None</h3>
<button>Click here to change video filter</button>
<div style="clear:both"></div>
<div class="col">
<h2>HTML5 <video> object</h2>
<video></video>
</div>
<div class="col">
<h2>HTML5 <canvas> object</h2>
<canvas width="600" height="450"></canvas>
</div>
</div>

Здесь я добавил предупреждающие сообщения для браузеров, которые не поддерживают HTML5 video и HTML5 Canvas.

Шаг 2. CSS фильтры

Как я уже говорил в начале нашего урока - мы будем использовать CSS фильтры:

style.css
.grayscale{
    -webkit-filter:grayscale(1);
    -moz-filter:grayscale(1);
    -o-filter:grayscale(1);
    -ms-filter:grayscale(1);
    filter:grayscale(1);
}
.sepia{
    -webkit-filter:sepia(0.8);
    -moz-filter:sepia(0.8);
    -o-filter:sepia(0.8);
    -ms-filter:sepia(0.8);
    filter:sepia(0.8);
}
.blur{
    -webkit-filter:blur(3px);
    -moz-filter:blur(3px);
    -o-filter:blur(3px);
    -ms-filter:blur(3px);
    filter:blur(3px);
}
.brightness{
    -webkit-filter:brightness(0.3);
    -moz-filter:brightness(0.3);
    -o-filter:brightness(0.3);
    -ms-filter:brightness(0.3);
    filter:brightness(0.3);
}
.contrast{
    -webkit-filter:contrast(0.5);
    -moz-filter:contrast(0.5);
    -o-filter:contrast(0.5);
    -ms-filter:contrast(0.5);
    filter:contrast(0.5);
}
.hue-rotate{
    -webkit-filter:hue-rotate(90deg);
    -moz-filter:hue-rotate(90deg);
    -o-filter:hue-rotate(90deg);
    -ms-filter:hue-rotate(90deg);
    filter:hue-rotate(90deg);
}
.hue-rotate2{
    -webkit-filter:hue-rotate(180deg);
    -moz-filter:hue-rotate(180deg);
    -o-filter:hue-rotate(180deg);
    -ms-filter:hue-rotate(180deg);
    filter:hue-rotate(180deg);
}
.hue-rotate3{
    -webkit-filter:hue-rotate(270deg);
    -moz-filter:hue-rotate(270deg);
    -o-filter:hue-rotate(270deg);
    -ms-filter:hue-rotate(270deg);
    filter:hue-rotate(270deg);
}
.saturate{
    -webkit-filter:saturate(10);
    -moz-filter:saturate(10);
    -o-filter:saturate(10);
    -ms-filter:saturate(10);
    filter:saturate(10);
}
.invert{
    -webkit-filter:invert(1);
    -moz-filter:invert(1);
    -o-filter: invert(1);
    -ms-filter: invert(1);
    filter: invert(1);
}

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

Шаг 3. HTML5 JavaScript

Теперь самый важный шаг - HTML5. Cоздайте пустой файл script.js со следующим содержанием:

script.js
// основная инициализация
document.addEventListener('DOMContentLoaded', function() {
    // глобальные переменные
    var video = document.querySelector('video');
    var audio, audioType;
    var canvas = document.querySelector('canvas');
    var context = canvas.getContext('2d');
    // видео фильтры
    var iFilter = 0;
    var filters = [
        'grayscale',
        'sepia',
        'blur',
        'brightness',
        'contrast',
        'hue-rotate',
        'hue-rotate2',
        'hue-rotate3',
        'saturate',
        'invert',
        'none'
    ];
    // получите видеопотока с камеры
	    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia || navigator.msGetUserMedia;
    window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
    if (navigator.getUserMedia) {
        // вызов функции getUserMedia
        navigator.getUserMedia({video: true, audio: true}, onSuccessCallback, onErrorCallback);
        function onSuccessCallback(stream) {
            // использование видеопотока как элемент видео
            video.src = window.URL.createObjectURL(stream) || stream;
            // автозапуск
            video.play();
            // HTML5 Audio
            audio = new Audio();
            audioType = getAudioType(audio);
            if (audioType) {
                audio.src = 'polaroid.' + audioType;
                audio.play();
            }
        }
        // отображение ошибок
        function onErrorCallback(e) {
            var expl = 'An error occurred: [Reason: ' + e.code + ']';
            console.error(expl);
            alert(expl);
            return;
        }
    } else {
        document.querySelector('.container').style.visibility = 'hidden';
        document.querySelector('.warning').style.visibility = 'visible';
        return;
    }
    function drawVideoAtCanvas(obj, context) {
        window.setInterval(function() {
            context.drawImage(obj, 0, 0);
        }, 60);
    }
    // функция canPlayType() не возвращает истину или ложь. С учетом того
    // насколько сложный формат, функция возвращает значение: 'вероятно', 'возможно' или пустую строку.
    function getAudioType(element) {
        if (element.canPlayType) {
            if (element.canPlayType('audio/mp4; codecs="mp4a.40.5"') !== '') {
                return('aac');
            } else if (element.canPlayType('audio/ogg; codecs="vorbis"') !== '') {
                return("ogg");
            }
        }
        return false;
    }
    
    video.addEventListener('play', function() {
        drawVideoAtCanvas(this, context);
    }, false);
    // кнопка для переключения фильтров
    document.querySelector('button').addEventListener('click', function() {
        video.className = '';
        canvas.className = '';
        var effect = filters[iFilter++ % filters.length]; // цикл фильтров
        if (effect) {
            video.classList.add(effect);
            canvas.classList.add(effect);
            document.querySelector('.container h3').innerHTML = 'Current filter is: ' + effect;
        }
    }, false);
}, false);

Давайте рассмотрим наш код. Чтобы взаимодействовать с веб-камерой (или микрофоном), мы используем новую функцию navigator.getUserMedia. В качестве её параметров, мы используем {video: true, audio: true}. В этом случае, когда мы открываем страницу, в браузере Chrome, появится информационная панель с запросом - разрешить или отклонить использование веб-камеры и микрофона. Это просто система обеспечения безопасности браузера. Основные параметры мы можем разделить на две функции обратного вызова для navigator.getUserMedia: onSuccessCallback и onErrorCallback. В случае ошибки – мы скроем объекты video и canvas, и добавим сообщение: 'Используемая веб-камера, не поддерживается в этом браузере'. Вы должны были заметить, что здесь также присутствует элементы HTML5 audio. Затем, чтобы произвести видеопоток для объекта canvas – я использую основную функцию 'drawImage'. И наконец, когда мы хотим использовать фильтр CSS, просто меняем имена классов для video и canvas.

 Исходные файлыДЕМО

 

Дополнительная информация

Влерий Аликин - веб-разработчик & дизайнер. Соучредитель и член команды Lecaw.

Эл. почта
RATTING:
(0 голосов)

Оставить комментарий