Хотелось бы рассказать вам историю создания одного простенького развлекательного сервиса по записи gif’ок с веб-камеры при помощи HTML5 и JS. О том как решение на коленке на базе опенсорсных решений в одночасье произвело пусть хоть и маленький, но всплеск популярности волны от которого уже на протяжении полугода приносят небольшое количество посетителей которым полезен этот сервис.
А началось все просто
В конце лета обычным рабочим днем бороздя просторы GitHub я наткнулся на довольно интересный скрипт (facetogif) на нативном JS и HTML5 позволяющий записывать ролики с веб-камеры в gif-анимацию. Была приложена даже рабочая демка заливающая готовые ролики на сервис imgur или позволяющая сохранить их сразу на жестком диске.
Эта идея показалась мне очень интересной и я решил с небольшими переделками реализовать ее в виде самостоятельного сервиса.
Сказано — сделано. В тот же вечер я форкнул репозиторий, зарегистрировал домен «вгиф.рф», поднял VPS (самый дешевый тариф за 5$) на DigitalOcean и написал простейший скрипт на php складирующий ролики прямо там на сервере.
Для экономии ресурсов на сервер установил только Nginx и PHP-FPM.
первая версия сайта
На следующее утро я поделился ссылкой на новоявленный сервис друзьям на одном закрытом сообществе. И сервис встретили хорошо =) Постепенно в перерывах между работой я занялся небольшими доделками — добавил кнопки шаринга в VK и Twitter, а также подредактировал js чтобы можно было делать ролики только одного размера (для унификации). Ночью того же дня понял что домен в зоне рф это довольно плохая идея и зарегистрировал более красивый и интересный домен togif.me, на котором сервис и по сей день.
Наступила долгожданная суббота и я с самого утра решил заняться сайтом. Для начала сделал большой и красивый мануал с картинками и собой в главной роли, а затем выложил ее на развлекательном сайте Pikabu и стал ждать минусов (там рейтинговая система схожая с Reddit и Хабром). И тут стали появляться один за одним комментарии, с минусами вместе пошли и плюсы, а затем уже я заметил что свободное место на VPS стало постепенно уменьшаться. Поздно спохватился с прикручиванием Яндекс.Метрики. Прикрученная поздно вечером она показала около 700 уникальных посетителей. В то время к посту на Пикабу было уже около 500 комментариев. Ну а затем кто-то добрый выложил ссылку на сервис в посте на Joyreactor и посещаемость увеличилась вновь! В воскресенье счетчик метрики застыл на отметке в 8 с лишним тысяч посетителей и 12 тысяч просмотров!
Технические подробности
И тут я понял что допустил одну досадную ошибку. Ролик можно было скачать или загрузить, но при загрузке пользователю выдавалась только скучная прямая ссылка на gif-файл. Не хватало каталога загруженных роликов чтобы можно было не только записать свой, но и посмотреть на других посетителей сайта!
Настала пора переписывать “сервис” который состоял из 1 статичной html-страницы, 1 опенсорсного js и скрипта upload.php.
Вариант 1
Так как поток посетителей не прерывался, а каталог хотелось здесь и сейчас то я накидал простенькую схему БД MySQL, подключил Idiorm для запросов к БД в стиле ООП, написал простенькие роутинги для отображения страниц каталога и самих картинок и еще добавил Disqus для возможности комментирования каждого ролика.
Где то в тот же период я стал эксперементировать со сжатием роликов и оказалось что imagemagick сжимает каждый из них минимум на 30%, а то и на все 70% =)
Связано это с тем что ролики генерируютя посредством js в браузере когда каждый фрейм снимается отдельно и затем они складываются в ролик. При этом подходе одинаковые части кадров повторяются в каждом фрейме.
За это время количество посетителей плавно таяло (с 1000 уников до 300 в течение сентября), но меня это не сильно беспокоило т.к. сервис сделан чисто себе в удовольствие и я радовался каждому новому записанному ролику. Очень приятно осознавать что сделал пусть что-то очень простое и не совсем свое, но полезное.
Далее я решил переписать все на Yii Framework и получился:
Вариант 2
Новшества:
- галочка для “непубличных” роликов (не отображаются в каталоге)- хранение новых загруженных роликов в Selectel storage
- генерация превьюшек при помощи imagemagick
- нанесение на ролики ватермарки со ссылкой на сайт (прямо во время записи)
- отдельная страничка с FAQ
- подсчет количества просмотров каждого ролика
- генерация более безопасных ссылок с рандомным количеством символов и добавлением даты (вместо /image/4r32njfi3.gif стало /2014/04/5e7eaed8bd.gif)
- возможность «отзеркаливания» записи
Хранение роликов я перенес в selectel storage т.к. захотелось более быстрой отдачи файлов для конечных посетителей. Готовый php-класс я позаимствовал у Eugene Smith на GitHub.
Для узнаваемости сайта было решено добавлять к каждому записанному ролику ватермарку. Причем хотелось чтобы даже просто сохраненный с браузера ролик уже ее имел. Для этой задачи я решил нагрузить пользовательские ресурсы и вот что получилось:
function recorder_fn(ctx, gif, frames) { var coords = facetogif.recorderFrame(), drawW = facetogif.gifSettings.w, drawH = facetogif.gifSettings.h; if(facetogif.p_flag==0 && facetogif.scale==1) { ctx.translate(coords.w, 0); ctx.scale(-1, 1); } return function () { if (facetogif.video.src) { ctx.drawImage(facetogif.video, coords.x,coords.y, coords.w,coords.h); if (facetogif.scale==1) { //Грязный хак с переворотами =) ctx.translate(coords.w, 0); ctx.scale(-1, 1); ctx.fillStyle = "white"; ctx.font = "normal 20px Arial"; ctx.textBaseline = 'top'; ctx.fillText("ToGIF.me", 220, 220); ctx.translate(coords.w, 0); ctx.scale(-1, 1); } else { //наложение ватермарки begin ctx.fillStyle = "white"; ctx.font = "normal 20px Arial"; ctx.textBaseline = 'top'; ctx.fillText("ToGIF.me", 220, 220); //наложение ватермарки end } var frame = ctx.getImageData(0,0, drawW,drawH); frames.push(frame); gif.addFrame(frame, {delay: facetogif.gifSettings.ms}); } else { clearInterval(recorder.interval); facetogif.recIndicator.classList.remove('on'); recorder.state = recorder.states.IDLE; } } }
Ну и отзеркаливание роликов я добавил по той причине что если записывать ролик в обычном режиме то на ролике ваша правая рука станет левой и наоброт. Поэтому для перфекционистов я добавил подобный режим.
Более безопасные ссылки я начал генерировать для защиты пользователей от полного скачивания архивов тупым перебором ссылок т.к. те кто доверился мне и загрузил на сервер приватные ролики должны заслуживать защиты. Алгоритм по понятным причинам раскрывать не буду.
За это время основной сайт успел переехать с VPS на DigitalOcean на облачную виртуалку в Selectel, а старые ролики остались на месте и для ссылок вида togif.me/image/xxx.gif стали работать автоматические редиректы на old.togif.me/image/xxx.gif
Затем при отсутствии существенных плюсов и более высокой стоимости решения (5$ + 300 руб. + 150 руб. каждый месяц) для сайта по фану было решено начать экономить.
Новая конфигурация включает в себя — мощный шаред-хостинг на сервере вскладчину и selectel storage для новых роликов. Для каждой порции в 10Gb гифок я решил создавать отдельный поддомен и по набору этого объема я стал их переносить на шаред-хостинг т.к. места там много, траффик не лимитируется и скорость отдачи не так важна ибо ролики уже не новые.
Облачное же хранилище с высокими скоростями остается только для новых роликов которые отдаются и сохраняются с высокими скоростями. Теперь затраты на сайт около 200 руб. в месяц что в принципе терпимо.
Текущий стек технологий:
Nginx, Imagemagick, HTML5, JS, PHP, Yii, MySQL
Нерешенные проблемы:
- не работает запись роликов в Safari
- не работает запись роликов в Iphone,Ipad
Немного статистики:
- Запуск сервиса — 22.08.13
- Трафик за данный период — ~1Tb
- Загружено роликов — ~15000
- Уникальных посетителей — ~80 000
Выводы:
- Для каких то тяжелых операций иногда можно нагружать клиентские компьютеры и клиентский JS в этом случае является спасительным кругом
- Для тяжелых операций на сервере целесообразно применять что-то более производительное чем php. Картинки например оптимизируются утилитой convert
- Yii показывает довольно выскокую скорость работы даже без встроенного кеширования, но нужно обязательно включать настройки для production mode
- Flash постепенно уходит, но есть еще куча устройств и программ которые не поддерживают новомодные фичи HTML5
Вот так используя опенсорс-решения можно сделать довольно интересный и полезный людям проект который пусть и без прибыли, но и без особых затрат продолжает кого-то радовать.
ссылка на оригинал статьи http://habrahabr.ru/post/218113/
Добавить комментарий