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

Итак, начнем, пожалуй, с мира материального.

Для работы нам потребуется как минимум один сервер (для размещения контента) и одна рабочая станция (для перекодирования видео). При этом сервер для вещания может быть не самый производительный на данный момент — основная его деятельность будет заключаться в том, чтобы быстро отдать видео большому числу пользователей. Замечу, что в данном случае видеофрагменты достаточно большие и кешировать их целиком в оперативной памяти, как бы последняя не была дешева, смысла не имеет. Рабочая станция, наоборот, должна быть максимально производительна (процессоры с количеством ядер меньше четырех рассматривать вряд ли стоит), поскольку при перекодировке процессорные ресурсы очень востребованы.

Примерная конфигурация сервера
Intel 1U SR1530HSH (LGA775, i3200, SVGA, SATA RAID, 3xHotSwap SATA, 2xGbLAN, 4DDR-II, 350W)
CPU Intel Core 2 Duo E8500 3.16 ГГц/ 6Мб/ 1333МГц LGA775
Kingston ValueRAM KVR800D2N5/2G DDR-II DIMM 2Gb PC2-6400 CL5
HDD 160 Gb SATA-II 300 Seagate/Maxtor Barracuda 7200.11/DiamondMax 22 3160813AS 7200rpm 8Mb
2 х HDD 1.5 Tb SATA-II 300 Seagate Barracuda 7200.11 ST31500341AS 7200rpm 32Mb

Стоимость такого набора может составлять примерно 40 000 рублей из расчета розничных цен. Основную погоду делают, конечно же, жесткие диски, места на которых постоянно будет не хватать.
В данной конфигурации предполагалось, что 1.5Тб-е диски будут включены в зеркало посредством software-RAID, а на 160Гб будет располагаться система.

Примерная конфигурация рабочей станции
HDD 1.5 Tb SATA-II 300 Seagate Barracuda 7200.11 ST31500341AS 7200rpm 32Mb
CPU Intel Core i7-920 2.66 ГГц/1+8Мб/4.8 ГТ/с LGA1366
ASUS P6T SE (RTL) LGA1366 X58 3xPCI-E+GbLAN+1394 SATA RAID ATX 6DDR-III
Kingston ValueRAM KVR1066D3N7/2G DDR-III DIMM 2Gb PC3-8500 CL7
1Gb PCI-E DDR-3 ASUS EN9800GT /DI/1GD3 (RTL) +DVI+HDMI+SLI GeForce 9800GT
Miditower ASUS TA9L1-SBB 90-PL9L1AV7T6-53CZ Silver&Black ATX 450W(24+4+6пин)
20″ MONITOR ASUS VH203D BK (LCD, Wide, 1600×900)

Стоимость рабочей станции колеблется так же в районе 40 000 рублей, при этом надо понимать, что приведенные выше конфигурации по большей части условность — можно воспользоваться и более дешевыми вариантами, и продукцией других вендоров и т.п.

Итак, железо есть. Что дальше? Дальше — операционные системы и ПО. В силу множества исторических факторов и наработанного опыта лично я склоняюсь к использованию Debian Linux на сервере и Ubuntu Linux или OpenSUSE на рабочей станции. Разумеется, это ограничение весьма условное и дело личных предпочтений, производственной религиозности и т.п. При этом если планируется использовать сервер для еще каких-либо функций помимо собственно ресурса, рекомендую сразу установить ядро с поддержкой контейнеров OpenVZ. Впрочем, это факультативный аспект, который оставим на самостоятельное изучение.

Теперь смело можно устанавливать сервер в стойку и подключать к магистрали. Все остальные операции на нем можно будет сделать удаленно.

Сразу отмечу следующие нюансы: поток в 2Мбит/с (на который ориентировались при создании HDin.TV) предполагает, что первой точкой потенциальных проблем станет пропускная способность канала, затем — свободное место на жестком диске. Поэтому надо предполагать, что если провайдер предоставляет вам канал на 100 Мбит/с, нормально смотреть видео смогут одновременно не более 40-50 человек, при этом с большой вероятностью пик будет приходится на 18:00-02:00, т.е. вечернее время. Это очень важно сразу обсудить с хостинг-провадером во избежание дальнейших претензий.

Сервер в стойке, на рабочей станции все установлено и настроено. Хорошо, теперь произведем разделение ролей. Сервер будет транслировать видео в сеть. Рабочая станция — перекодировать видео.

Начнем с рабочей станции. Для начала соберем и установим программу для видеоперекодировки ffmpeg и любимый торрент-клиент. С клиентом предлагаю разобраться самостоятельно, а вот про ffmpeg расскажу попробнее. Мое личное убеждение, что и ffmpeg, и x264 (библиотека для сжатия с применением кодека H.264) следует брать из систем контроля версий, собирать вручную и использовать. Причина тому проста — оба проекта весьма динамично развиваются, оперативно добавляются новые функции и устраняются ошибки, поэтому дистрибутивные пакеты, как правило, не успевают за этой динамикой. Впрочем, отрицать правильность пути с установкой пакетов из стандартной поставки так же не буду — как минимум не придется отслеживать зависимости и проверять обновления.

Устанавливаем x264

1
2
3
4
5
git clone git://git.videolan.org/x264.git
cd x264
./configure
make
make install

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

1
2
3
4
5
svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
cd ffmpeg
./configure --enable-gpl --enable-nonfree --enable-postproc --enable-pthreads --enable-libdc1394 --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libvorbis --enable-libx264 --enable-libxvid
make
make install

Хорошо, ПО собрали и установили, торрент-клиент есть — можно качать любимые сериалы, перекодировать и выкладывать на сервер? Не все так просто. Во-первых, необходимо понимать, что сериалов много и уследить за выходом серий в каждом из них — сложно. Во-вторых, перекодировать целый сезон, набирая команды руками — непрактично. В-третьих, мы все еще не настроили сервер.

Начнем с отвлеченного. Как следить за выходом серий? Тут есть два очевидных варианта: а) воспользоваться сервисом для отслеживания сериалов; б) написать небольшого робота, который будет самостоятельно отслеживать изменения на страницах трекера и присылать вам уведомление об изменении (можно, конечно, заставить торрент-клиента скачивать по RSS, но мы же настоящие комсомольцы, правда?). Для себя я сделал такого робота на базе Jabber-клиента, уже упоминавшегося в данном блоге.

Скачать робота можно тут — bot.zip.

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

Второй аспект — перекодирование сезонов. Не секрет, что многие сериалы уже идут не один год и по каждому из них набралось порядочное количество серий. Так же очевидно, что все это надо перекодировать — Adobe Flash понимает достаточно небольшое число видео и аудио-кодеков. Помимо всего есть еще один параметр, который надо подкорректировать — верхняя граничная величина скорости кодирования, которой определяется будет ли наш пользователь смотреть видео без проблем или ждать каждые пять секунд дозагрузки нового фрагмента. В случае 720p мы можем использовать значение максимальной скорости потока видео 1664 Кбит/с, для аудио — 192 Кбит/с (на канал, каналов обычно 2 штуки), что в сумме даст потребную пропускную способность в 2 Мбит/с (т.е. пользователи с тарифным планом, подразумевающим меньшие скорости, будет, вероятно, испытывать неудобства). Это обычно ниже того потока, на который рассчитаны размещаемые на трекерах файлы, и, разумеется, ведет к определенной потере качества, порой заметную на глаз, но, в тоже время, позволяет экономить место на диске — 40 минут серии будут занимать уже не 1.4 Гбайт в среднем, а 500 Мбайт. То есть выбор параметров сжатия в большей степени продиктован балансом между качеством и доступностью для пользователей / занимаемым пространством.

Другой аспект данного вопроса — формат контейнера. Можно использовать flv («родной» для Flash Player формат), но я предпочитаю mp4 — это продиктовано потенциальными сложностями, которые могут возникнуть в проигрывании flv у сетевых плееров и медиа-центров. Хотя, возможно, эти сложности и надуманные, и можно использовать любой контейнер, который поддерживает разворачиваемая на сервере система вещания.

Итак, вернемся к тому факту, что серий много. Соответственно, возникают следующие задачи: а) как перекодировать большое число серий пачкой (привести к нужному формату и скорости потока), б) как оформить большое количество серий для разового импорта в систему публикации.

Первая подзадача решается просто. По-хорошему, следовало бы создать систему, которая в пакетном режиме обрабатывала задачи на перекодирование, обходила каталоги, преобразовывала бы видео-контент и выкладывала результат деятельности на сервер. Наверное, так было бы правильно и хорошо. Если бы не единственный нюанс — порой исходный материал содержит несколько дорожек, дорожки могут быть перепутаны, в результате чего на выходе получается серия, где все герои говорят не на том языке, который хотел бы слышать посетитель (а в отдельно преобразованной звуковой дорожке, которую мы тоже будем выдирать для наших целей — как раз тот самый перевод). Поэтому контент после преобразования необходимо выверять. Что, впрочем, не оправдывает тот полурукопашный подход, который я применил для hdin.tv. Поскольку серии часто имеют в названии структуры типа s(номер сезона)e(номер эпизода), достаточно легко и просто написать простенький PHP-сценарий, который пробежится по файлам текущего каталога и при помощи ffmpeg сделает файлы требуемого формата, выдернет дополнительную дорожку с языком оригинала и сформирует стоп-кадр (на 10-й секунде видео), причем сделает это, давая результатам имена формата (номер сезона)-(номер серии).

Сценарий можно скачать здесь, он достаточно простой, чтобы не писать его самостоятельно.

Вторая подзадача решается тоже весьма просто, хотя автоматизировать ее я бы не рискнул. Допустим, в нашей системе управления сайтом есть база с сериалами и эпизодами, на основе которой будут формироваться страницы для доступа к контенту. Поэтому для массового импорта всего перекодированного достаточно написать сценарий, который, допустим, получит на вход csv-файл со списком номеров сезонов, номеров серий и названий, после чего благополучно загонит их в SQL-таблицу, по которой (в нашем случае) будет формироваться представление для посетителя. А сам файл легко создать при помощи OpenOffice Calc или еще каких альтернативных пакетов ПО на основе данных из о сериях из Wikipedia или IMDB. Данное техническое решение достаточно тривиальное, чтобы его публиковать, поэтому оставим это на самостоятельное обучение.

Итого, на данном этапе мы умеем получать контент и его описание в нужном формате, что позволяет нам перейти к самому интересному — настройке сервера вещания и разработки собственно ресурса, где будем этот самый контент публиковать. Сразу уточню, что в рассмотрении этого вопроса я не буду касаться двух аспектов — подсистемы авторизации пользователей и регистрации по приглашениям (поскольку это достаточно просто даже не для самого опытного вэб-разработчика) и способа доставки контента с рабочей станции на сервер (потому как это просто сделать множеством возможных методов, например, при помощи Samba, WebDAV, rsync или DRDB, и так же вполне тривиально).

Итак, доставлять видео на браузер посетителю мы може как минимум двумя основными способами — посредством RTMP или банально поверх HTTP. Для первого потребуется поднимать дополнительный сервис типа ErlyVideo или Wowza Media Server, за последний придется еще и заплатить. Но в определенной степени этот метод не самый удобный — а) в этом случае мы ограничиваем количество клиентов, позволяющих просматривать видео, браузером и AIR-приложением (медиа-центры, не поддерживающие интеграцию Flash Player-а, так же останутся за бортом), б) в некоторых случаях RTMP может быть просто банально заблокирован не в меру ретивым системным администратором. Поэтому в угоду универсальности и простоте будем отдавать контент посредством псевдо-потокового HTTP-вешания, для чего вполне сгодится вэб-сервер nginx, дополненный модулем h264-streaming.

Собираем на сервере nginx (можно в пакет, можно напрямую), с подключением дополнительного модуля, устанавливаем и конфигурируем согласно инструкции (nginx можно взять посвежее).

Следующий этап — создание сайта. На эту тему тоже можно долго рассуждать, спорить, какая система управления лучше и правильнее, поэтому углубляться в это, наверное, смысла особо не имеет. На hdin.tv применена моя старая наработка — самописная система управления, позволяющая конструировать структуру БД из-под себя на основе хранения метаинформации, а пользовательский интерфейс обеспечивался сгенерированными по запросу администратора статическими HTML-файлами. В этом случае для взаимодействия с пользователем достаточно nginx-а, который будет отдавать по сути дела статический контент (немного потеряли в динамике, но для сайтов подобного плана оно, наверное, не сильно критично).

Единственный нюанс в создании сайта — использование готового или самописного плеера (тут надо отметить небольшую путаницу в терминах — под плеером в данном случае подразумевают не Adobe Flash Player, являющийся плагином к браузеру, а некий созданный для него swf-файл, который может управлять параметрами вывода видео). Я для ресурса использовал JW Player, позволяющий нарастить функционал проигрывания (добавить субтитры и дополнительные дорожки, задействовать горячие клавиши), который достаточно просто конфигурируется через flashvars или вспомогательной JS-библиотеки типа SWFObject. Опять же, наличие у плеера JavaScript API позволило реализовать такую приятную мелочь, как затенение экрана в момент проигрывания:

1
2
3
4
5
6
7
8
9
10
11
var player = $("#mpi")[0];     
player.addModelListener('STATE', 'stateChanged');

function stateChanged(obj)
{
    if(obj.newstate == "PLAYING") {
        $("#overlay").fadeIn();
    } else {
        $("#overlay").fadeOut();           
    };
}

В общем, хорошая штука, всячески рекомендую. Особо приятно то, что он поддерживает http-streaming «из коробки», впрочем, за остальные плееры не берусь утверждать, может быть они умеют это делать еще лучше.

Отдельно замечу на предмет двух вещей — Smooth streaming (возможность подстраивать поток видео под пропускную способность канала до пользователя) и HTML5 (который имеет встроенную в обход достаточно прожорливого до ресурсов на не-Windows платформах Flash Player-а подсистему для проигрывания видео). Первая штука чрезвычайно полезна, но в случае если вы захотите увеличить доступность ресурса для большего числа пользователей, в том числе и с низкоскоростными каналами. Но, увы, она требует как поддержки со стороны пользователя (что не страшно, поскольку версия 5.1 JW Player-а, по анонсам разработчиков, поддерживает эту опцию, сам я еще не проверял), так и предполагает наличие на сервере исходного контента, перекодированного как минимум под две скорости (бОльшую и меньшую), т.е. место на жестком диске будет расходоваться очень быстро. Впрочем, ничто не мешает сделать подобное в случае создания версии ресурса для iPhone, iPad и прочих мобильных устройств.
HTML5-браузеров c поддержкой h.264 не так много, поэтому я сделал такую простую проверку на JavaScript, позволяющую показать дополнительную кнопку переключения в этот режим на панель над проигрывателем:

1
2
3
4
5
6
7
8
9
10
if (supportH264()) {
    $("#h5v").show();
}

function supportH264() {
    var v = document.createElement("video");
   
    if (!v || !document.createElement('video').canPlayType) { return false; }
    return v.canPlayType('video/mp4');
}

К сожалению, встроенные в браузер видеопроигрыватели, как правило, достаточно бедны по функционалу, поэтому перед масштабной поддержкой HTML 5 лучше дождаться выхода какого-либо открытого плеера для данной технологии (например, openplayer).

После того, как все поставлено, настроено и оттестировано, и первые пользователи атакуют ваш сервис с целью посмотреть видео, поэтому осталось несколько моментов:

  • создать средства, позволяющие отслеживать добавления новых серий. для начала достаточно RSS, который затем можно перенаправить в Twitter и социальные сети;
  • создать XML или JSON-выгрузку данных для ресурса. Это очень полезно, если в дальнейшем вы или ваши колеги захотят написать специализированное AIR-приложение или плагин для медиацентра;
  • подключить систему сбора статистики (рекомендую Google Analytics) и систему мониторинга (рекомендую Cacti) для последующего упрощения поддержки ресурса;
  • протестировать взаимодействие с различными плеерами типа VLC или WMC — порой смотреть через них удобнее, нежели через браузер.

Если все прошло успешно — мои поздравления, теперь вам предстоит долгая и кропотливая работа по подбору сериалов, их перекодированию, описанию и оформлению. Если нет — напишите комментарий к данной заметке, попробуем разобраться.

44 ком.
  1. Игорь:

    Все отлично, один вопрос, а сами почему не хотите такой сделать?

    Максим Крентовский

    А уже сделал. Прошло испытание боем, т.с.

    Игорь

    покажите?

    Максим Крентовский

    Ну, собственно hdin.tv. Только там по приглашениям. Если очень интересно — напишите на mkrentovskiy@gmail.com, я скажу код.

    IceMan76

    А можно мне у вас просить волшебное слово на http://www.tulavideo.net ???

    Максим Крентовский

    Увы, там канал совсем кончился. Так что волшебные слова никому не раздаются.

  2. Братец, у тебя эта статья в жж криво экспортнулась, просто JFI

    http://syndicated.livejournal.com/relabs_ru/18176.html

    Максим Крентовский

    Ага, вижу. Спасибо.

  3. Владимир:

    А почему сайт закрывается?

    Максим Крентовский

    Там много мотивов, в основном — личные.

    Игорь

    а передавать его не планируете?

    Максим Крентовский

    Не-а, да и кому?

  4. gigimon:

    Хотелось бы больше узнать о создаваемых нагрузках на сервер, сколько потоков он может отдавать и были ли какие-то специфичные настройки nginx?

    Максим Крентовский

    Ну смотрите, примерная полезная пропускная способность 100Mbts Ethernet-интерфейса где-то 80Mbts (остальное служебные данные, паразитный трафик). Т.е. в теории один сервер без проблем может держать 80/2 = 40 одновременных подключений. Конечно, в серверах сейчас интерфейсы гигабитные, но под них еще и провайдера надо найти.

    Специфичных настроек почти нет, за исключением зажатия соединения на максимум эти самые 2Мбит/с. Но это в документации очень хорошо описано.

  5. Павел:

    За очень корткое время hdin стал очень популярным и желанным сайтом !

    Максим Крентовский

    Свято место пусто не бывает.

  6. Daniel:

    А можно узнать какие именно параметры при конвертировании в косоле нада задавать?

    Максим Крентовский

    А посмотрите на внутренности скрипта для перекодировки, там они в виде массива перечислены.

  7. Вроде как что-то с ссылкой http://erlyvideo.org/ ? Почему то у меня не работает. Пишет 404 — в чем может быть дело?

    Максим Крентовский

    Вроде работает. Может обновлялось.

  8. [...] • Как сделать свой онлайн-кинотеатр с пользователями и приглашениями? Информация из первых рук. [...]

  9. Александр:

    Хорошая статья. Только не понял для чего это все нужно. Чтобы на мобильники видео запускать? Тогда это интересно. Но а для полноценного сервиса VoD, это просто смешно. Я сначала думал что случайно наткнулся на старые архивные публикации, но увидел даты этого года и прозрел. Господа на дворе 2010 год, проснитесь! Я вам на бесплатном хосте сделаю за час онлайн-кинотеатр, с качеством видео 1080р.
    Да и вы сами сделаете, если в новые а не в старые технологии смотреть будете.

    Максим Крентовский

    Эм… Ничего не понял. Что старого?

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

    К слову, p2p-смотрелки — это, конечно, красиво, но пока там больше вопросов, чем ответов.

    Игорь

    Я так понял, что под новыми технологиями подразумевалось что-то типа Torrent Stream (torrentstream .org).

    Torrent Stream + парсер инфы с трекеров, и нет необходимости заморачиваться с конвертацией и париться по поводу каналов.

    Максим Крентовский

    Ну, тоже верно. Только что-то как-то не сильно попуярно.

    Максим Крентовский

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

  10. Hamsy:

    В плане: «увеличить доступность ресурса для большего числа пользователей, в том числе и с низкоскоростными каналами»
    Есть задумка на видеогалерею репортажей. Этакая — хроника событий.
    Там требуется возможность просмотра пользователями со слабым интернетом. ( по трафику, по скорости ли… не москвичам, если коротко.)
    Пока из мыслей было — Предварительно, на отдельной машине конвертировать видео в много разных размеров, а на закуску — делать ещё и этакое слайд-шоу из кадров видео ( с аудио-дорожкой из оригинального видео ) , для тех у кого интернет совсем плох.
    Не хватает знания деталей.
    Что можно сделать для решения такой задачи ?

    Максим Крентовский

    Боюсь, слайд-шоу будет выглядеть много хуже самого «легкого» ролика. Да и смысла нет, модемные скорости канули в лету даже на сетях сотовой связи.
    Проще делать несколько вариантов: под мобильные сети, для DSL, для широкополосного доступа и HD.

    Hamsy

    По предварительным прикидкам у меня получились такие размеры:
    1080p (HD);
    720p (HD);
    480p;
    360p;
    240p (mobile video 320×240);
    144p (mobile video 176×144);
    120p;
    90p;
    Всё пока очень предварительно, а у Вас, насколько вижу, немалый в этом опыт. Что Вы бы посоветовали ?

    Максим Крентовский

    Я бы рекомедовал оставить ниже 480p только один формат, больше просто смысла не имеет — ужасно плохая детализация.

  11. Marsel:

    Привет всем!
    Я прочёл всё но так и не понял сколько над ОЗУ для онлайн кинотетра
    1-10 человек (Сколько?)
    10-100 человек (Сколько?)
    100-1000 человек (Сколько?)
    1000 и более (Сколько?)

    Marsel

    Размещаю видео я на видео сервисах как ру тюб

    Максим Крентовский

    Тогда Вам все равно, это будет болеть голова у создателей тех сервисов.

  12. Marsel:

    ну а ты что посоветуешь то?

    Marsel

    считай что мой сайт не онлайн кинотеатр а блог
    сколько блогу потребуется ОЗУ?
    1-10 человек (Сколько?)
    10-100 человек (Сколько?)
    100-1000 человек (Сколько?)
    1000 и более (Сколько?)

    Максим Крентовский

    На предмет? Размещайте видео на vimeo, youtube и т.п. — в этом случае Вам будет все равно, основная нагрузка ляжет на их сервера. В остальном все зависит от движка блога, каких-то универсальных решений нет.

  13. Marsel:

    Ну для сайта всё равно нужна же оперативка :)
    какую посоветуешь?
    Ты то что я сказал про видео вообще забудь вот представь сколько озу потребуетсся обычному сайту для просматривании страниц и тд

    Marsel

    *то что я сказал про видео вообще забудь вот представь сколько озу потребуетсся обычному сайту для просматривании страниц и тд

    Максим Крентовский

    Я понял. Если не учитывать нюансы — какой движок, на какой платформе и т.п. — то чем больше, тем лучше. В противном случае надо экспериментировать, но однозначный ответ никто не даст.

  14. Marsel:

    а от своего опыта примерно можешь сказать?
    Например для 10 человек сколько потребуется, сайт например эммм ucoz с обычным оформлением

    Максим Крентовский

    128Mб хватит за глаза. И еще останется.

  15. Marsel:

    на 10 человек да?

    Максим Крентовский

    10 одновременных подключений.

    Marsel

    Спсибо

Максим Крентовский
системный архитектор
E-mail / GTalk: mkrentovskiy@gmail.com
Skype: mkrentovskiy