воскресенье, 10 октября 2010 г.

Видео-доклад с презентацией: FLVScrubber, Flex-Ajax Bridge и SWFObject

Очень часто бывает необходимо выложить видео-доклад в интернете. Однако, доклад чаще всего делают со слайдами, а нередко - даже с онлайн-написанием кода, и если использовать только одну камеру - и для докладчика, и для изображения с проектора, получается, что изображение с проектора видно плохо.

Если же выводить только изображение с проектора, и фоном аудиозапись доклада - опять же, получается неполная картина, поскольку докладчик может шутить, улыбаться, жестикулировать... К примеру, я для себя заметил, что большую часть времени я смотрю именно на докладчика, а не на слайды. Конечно, всё зависит от конкретного доклада, но всё-таки, смотреть на человека бывает весьма интересно.

Итак, идеальный вариант - совмещать на одном видео и изображение докладчика, и изображение с проектора. Чтобы это проделать, используются различные методы.

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

 

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

И вот совершенно недавно, я увидел очень простой вариант, который используется на сайте InfoQ. Вообще, на этот сайт я попал случайно, смотрел Эрика Эванса (кто не знает, это основоположник понятия DDD), поскольку готовил доклад про анемичную модель, и интересно было послушать, какие конкретно плюсы видят Эванс и Фаулер в rich-модели. Но Эванс парень, как выяснилось, довольно нудный, а потому если уж соберетесь что-то посмотреть на InfoQ, рекомендую доклад Udi Dahan'а про CQRS. Правда, собственно про CQRS там было немного (т.е. желательно ознакомиться с паттерном заранее), зато много было про аналитику и про usability, в разрезе Distributed-систем, в общем мне понравилось. Да и докладчик очень даже ничего.


Дак вот, о самом способе. Смысл такой: на страницу встроено два Flash-объекта. Основной объект представляет собой обычное flash-видео докладчика, демонстрируемое с помощью плеера FLVScrubber, второй объект предназначен для слайдов, которые хранятся в виде отдельных файлов в swf-формате. Эти объекты имеют идентификаторы, соответственно, "FLVScrubber" и "slideArea" (понадобится дальше). Причем, второй объект сбинден с первым с помощью JavaScript. В итоге, для демонстрации достаточно объявить два массива - slides и TIMES, с помощью которых будет определяться, в какое время на какой слайд требуется переключиться. Например, это может выглядеть так:

var slides = new Array('1.swf','2.swf','3.swf','4.swf','5.swf','6.swf','7.swf');
var TIMES = new Array(0,66,121,219,225,261,278);

Как видите, если придерживаться правил именования файлов со слайдами, то от массива slides можно даже избавиться.

Для того, чтобы всё это заработало, ребята из InfoQ используют SWFObject и Adobe Flex-Ajax Bridge. При инициализации, они создают мост к объекту FLVScrubber с помощью FABridge.

// Entry method (triggered after load)
function init() {
    // register callback for FABridge initialization
    FABridge.addInitializationCallback("FLVScrubber", initBridge);
    // sort TIMES array from small to high numbers
    TIMES.sort(sortNumber);
    // render first slide
    var so = new SWFObject(getPathForSlide(0), "slides", "100%", "100%", "8");
    so.addParam("wmode", "transparent");
    so.write("slideArea");
}

, где:
  • initBridge - это функция, которая будет выполнена при инициализации моста.
  • getPathForSlide - это крохотная функция, которая получает путь к слайду с соответствующим порядковым номером
Наиболее интересен именно initBridge, который, собственно, с помощью моста подписывается на событие FLVStatusEvent:

// Init Flex-AJAX-Bridge and subscribe to FLVStatusEvent
function initBridge() {
    flexApp = FABridge.FLVScrubber.root();
    flexApp.getVideoDisplay().addEventListener("FLVStatusEvent", scrubberEventHandler);
    flexApp.getVideoDisplay().setFile(Base64.decode(jsclassref));
}
 
где:
  • jsclassref - это просто путь к flv-файлу с видео докладчика, закодированный в base64.
  • scrubberEventHandler - это хендлер для событие FLVStatusEvent, которому на вход передается время, и в зависимости от этого времени меняется слайд.

// Handler for scrubber events (gets triggered three times a second)
var scrubberEventHandler = function(event) {
    // get index of slide for the current playing position ...
    var cand = getIndexOfProjectedSlide(event.getTime());
    // and switch to it if it isn't already shown
    if (cand != currentSlide) {
        var so = new SWFObject(getPathForSlide(cand), "slides", "100%", "100%", "7");
        so.addParam("wmode", "transparent");
        so.write("slideArea");
        if(document.EXPRESSINSTALL_SWF) {
           so.useExpressInstall(EXPRESSINSTALL_SWF);
        }
        currentSlide = cand;
    }
}

Не буду разъяснять все внутренние переменные, т.к. их значение довольно очевидно.

Полный код Js-файла, реализующего весь функционал презентаций, можно скачать с InfoQ. Не рекомендую использовать его без изменений (поскольку есть такая штука, как авторские права), однако сам подход мне очень понравился, постараюсь его воплотить, когда буду выкладывать собственные доклады.

Update: еще один неплохой фриварный вариант для видео-докладов - это использование SlideSync-плагина для JW Player.

Комментариев нет:

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

Внимание! Реклама и прочий спам будут беспощадно удаляться.