Pull to refresh

Comments 108

Андрей, практическое описание основано, видимо, на базе вашего опыта по проекту «Videobam». Интересно было бы услышать Ваше мнение (основанное на опыте) относительно того в каких ситуациях «видеохостинг своими руками» может конкурировать с матерыми гигантами рынка и быть востребованным у пользователей.
В данный момент проект набирает начальную базу пользователей, но уже сейчас понятно, что ниша VideoBam — это видео для взрослых :) В основном, из-за того, что гиганты рынка видео такого характера загружать не позволяют, я думаю, что сервис будет вполне конкурентоспособным.
И Вас не смущает ответственность и возможные проблемы юридического характера за хранение и распространение (а ведь Вы именно этим и занимаетесь) подобного видео? И если не смущают, то как собираетесь их решать?
Меня это не смущает, мы выполнили проект на заказ. У заказчика есть опыт управления подобными проектами (с контентом для взрослых). Модерация будет проходить постфактум, по запросу правообладателей/правоохранительных органов.
Во всем цивилизованном мире адалт-видео не является чем-то противозаконным (незаконным является порно с участием детей и подобное). Как я понимаю, сервис ориентирован не на рунет, тогда в чем проблема?
А что, у адалт-видео нет своих гигантов? Всякие megavideo.com, не говоря уже о redtube и подобных сервисах, уже со своим контентом.
Есть пример, где генерируется ссылка на скачивание. Мне не хотелось делать из статьи копипасты проекта, поэтому вставил только один тематический участок кода. Если будут какие-то конкретные вопросы, с удовольствием поделюсь наработками в личной почте.
Залил мультфильм для теста, весьма шустро работает, конвертирование прошло примерно за 15 секунд.
videobam.com/kDzTx
Проигрывание тоже на отлично, в то время как на RuTube, Vkontakte, даже иногда YouTube забиты каналы и как раньше приходится ждать загрузки :-)
Хороший сервис, молодцы!
Оформи воспользовавшись элементарным хабра-оформлением! Ибо код прямо глаза режет!
Статья очень даже не плохая.
Если тебе надо, прочитаешь и так. Затрахали выскочки которые сами ничего полезного не пишут, только указывать на недочеты могут.
Давай не будем, я не обидел не кого, просто предложил сделать лучше, ибо:
Критикуешь- предлагай. Предлагаешь- делай. Делаешь- отвечай!
Следует отметить, что всё программное обеспечение собирается вручную из исходных кодов

Почему просто не патчить пакеты дистрибутива и держать собственный репозиторий?

Для защиты от копирования ссылок (хотлинкинга) мы используем модуль HTTP Secure Download

У nginx есть x-accel-redirect для таких случаев.

Почему просто не патчить пакеты дистрибутива и держать собственный репозиторий?

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

У nginx есть x-accel-redirect для таких случаев.

Спасибо за наводку, посмотрим в его сторону.
Не нужно для этого X-Accel-Redirect — получатся лишние запросы к бэкенду.

Вместо сторонних модулей уже можно использовать стандарный secure_link:

secure_link_md5
Для ffmpeg есть хитрый ход: надо указывать параметр -ss самым первым, тогда резать будет быстро.
Правда, это относится только к новым версиям ffmpeg. То, что в репозиториях debian lenny, слишком старо.
Спасибо, очень полезная информация. Мы собрали ffmpeg из SVN, нужно будет попробовать.
Кстати, вы эти тумбнейлы потом как-то обрабатываете?
Да, уменьшаем средствами gd2. Оставляем один оригинальный для показа в качестве подложки видеоплеера пока загружается видео.
Как вариант можно попробовать Imagick, по памяти выигрыш точно будет. Причем его можно использовать консольно.
По сравнению с нагрузкой от конвертации видео — копейки.
UFO just landed and posted this here
BTW, сейчас есть достаточно много готовых tube-скриптов… правда заточенных на распределенную архитектуру не видел… или плохо искал )
+1. Не очень понятная цель проекта при наличии готовых тубных скриптов.
Пруфы на бесплатные тубные скрипты будут? С поддержкой енкодинг-бекендов и т.д.
В таких масштабах и 300 баксов, считай, бесплатно. Ну вот clipshare сразу приходит в голову.
UFO just landed and posted this here
ну у нас примерно 10 клиентов где-то с tube сайтами, как-то работают )
мы базовую установку скриптов только делали, вроде без проблем все, дальнейшую настройку, шаблоны и т.д. уже сами клиенты…
как вы планируете масштабироваться в случае роста? Добавлять новые и новые сервера?
Посмотрите в сторону Amazon S3 и CloudFront.
если адалт то амазон нельзя вроде…
и с правообладателями контента вопрос открытый тоже…
а вообще да, добавлением дисков в текущие сервера + добавление серверов проблема решается…
можно еще гео-распеределенную систему сделать, с отдачей контента с ближайшего сервера для повышения скорости у клиентов.
Да, будем добавлять новые сервера.
Если туда смотреть, то, боюсь, окупать сервис будет очень сложно. Цены на s3 ого-го, если видео раздавать.
Скажите, какой у вас load average на сервере когда ффмпег работает и синхронизация файлов?
Очень шустрый хостинг, приятно удивлен. На ура схавал 200-мегабайтное видео и почти сразу же дал просмотреть. Поразительно!
Спасибо, сейчас пользователей не очень много, так что скорее всего Ваше видео конвертировалось эксклюзивно. Но мы всё равно будем стараться соответствовать слову «FAST» в слогане :)
У нас, кстати, почему-то модуль nginx_mod_h264_streaming отъедал 1 Мб памяти на каждый поток. Плюс была проблема с долгим стартом mp4-видео (для полнометражных фильмов — ожидание доходило до минуты). Не сталкивались с таким?
есть скрипт qt-faststart ставится вместе с ffmpeg, прогоняйте видео через него и будет быстро стартовать
Буферизация и перемотка у меня работают. Проблема mp4 в том, что плеер перед стартом выкачивает некоторый объем каких-то метаданных. На 10 минутном ролике это примерно пара секунд и дальше начинается буферизация и просмотр, а вот на полнометражных фильмах получается ощутимая задержка до минуты.
Для полнометражек задержка 1-2 секунды, что вполне приемлимо. Попробуйте пост-обработку MP4Box-ом, у нас с помощью неё решились многие проблемы стриминга.
Трансляция потокового видео обеспечивается модулем h264 для веб-сервера nginx (http://h264.code-shop.com/). Настройка этого модуля осуществляется очень просто:

/usr/local/nginx/conf/nginx.conf
location ~ \.mp4$ {
mp4;
}


Модуль h264 — это адский ад и смерть диску при seek-ах.
forum.nginx.org/read.php?21,68014,68145#msg-68145

Там тупо взят код из какого-то десктопного плеера.

Почему бы не делать flv? Он прекрасно может быть контейнером для h264. Советую переехать, пока не поздно :)
У нас при использовании кодека h264 в контейнере flv и обработки потом файла для перемотки — картинка в плеере рассыпалась.
Для того, чтобы нормально работала перемотка, в flv надо добавлять после конвертации метаданные. Для этого можно использовать, например, yamdi.
Или я неправильно понял и это и есть «обработка потом файла»? Странно, такого не наблюдал, а чем тогда делалось и с какими параметрами?
Уже не помню, но сейчас проверил — связка ffmpeg+x264+yamdi c отдачей через nginx+flv работает действительно отлично.
Интересная информация, спасибо. К сожалению, flv не подходит из-за отсутствия поддержки в iPhone и iPad.
UFO just landed and posted this here
На Mac OS X такой проблемы нет. Есть проблема в iOS, там флэшовые ролики открываются только при помощи специализированного ПО вроде skyfire (http://skyfire.com). В Safari Flash-видео не работает.
Было бы интересно услышать ответы на следующие вопросы.

1. Вы ограничиваете скорость отдачи видеофайлов?
2. Отдача происходит непосредственно с файлового сервера, или проксируется через сервер конвертации?
3. Каждый видеофайл хранится в одном экземпляре на одном файловом сервере?
4. На файловых серверах raid1?
5. Что делаете при обнаружении горячего видеофайла, когда, к примеру, несколько десятков человек одновременно смотрят его?
RAID на серверах отдачи — это худшее, что можно придумать: вместо одного диска головки двигают все синхронно.

Когда я решал подобную задачу, я хранил идентичный контент на двух серверах (то есть, все сервера были объединены в пары); контент заливался на оба сервера синхронно. На всех серверах обычные диски безо всяких рейдов. Для балансировки достаточно генерировать ссылки поочередно на разные сервера (например, $binary_ip_address % $count_of_servers_in_group).

Если контента много, и есть некоторая значительная доля «горячего» контента, можно ввести дополнительный кэширующий фронтенд с быстрыми дисками (SAS/SSD); вообще начиная с некоторых объемов выгодно разделить задачи хранения и отдачи.
1. Нет, датацентр позволяет отдавать контент с гарантированной скоростью 500Mbit (1Gbit на порту). Пока что скорость отдачи около 150Mbit. Если упрёмся, то будем ограничивать скорость отдачи.
2. Непосредственно с файлового сервера.
3. Да, в одном экземпляре. Бэкапы мы не используем.
4. Да, RAID1.
5. Пока ничего, возможно в будущем будем зеркалировать популярный контент, такая возможность в системе заложена.
Зря raid1, лучше бы на 2 винта каждый ролик копировали. Скорость была бы существенно выше при множестве конкурентных запросов. +в будущем можно копировать на винты на разных серверах, что еще и надежность существенно повысит.
Да, наверное будем переходить на схему с двумя винтами.
Добавлю к списку вопросов: как происходит балансировка отдачи с файловых серверов?
Пока что отдаётся с максимальной скоростью, насколько позволяет соединение клиента.
Спасибо очень интересный пост. Делал тоже самое для своего небольшого видеохостинга: creaspace.ru Так как роликов мало и ориентация на десктопную аудиторию, то на настройках не экономлю. Сейчас использую два прохода. Настройки такие:

ffmpeg -i 1.mp4 -an -pass 1 -vcodec libx264 -vpre max -f mp4 -s 480x270 -b 400k -bt 400k -threads 1 tmp.mp4

ffmpeg -i 1.mp4 -acodec libfaac -ab 64k -ac 2 -pass 2 -vcodec libx264 -vpre max -f mp4 -s 480x270 -b 400k -bt 400k -async 1 -threads 1 tmp2.mp4

Вместо MP4Box использую QT-Faststart. Примочек для nginx не ставил, надо бы посмотреть в эту сторону. Особенно заинтересовал secure download, не задумывался ранее о такой возможности. =) В качестве проигрывателя использую JWPlayer.

Можно поинтересоваться содержимым: -vpre videobam и каким образом подбирались настройки кодирования для устройств Apple?
Он в насоящее время похож на сборную солянку и всё еще находится в процессе оптимизации :)

pastie.org/1432128

Основной костяк из Baseline-профиля, идущего в комплекте с ffmpeg.
Полная автоматизация для порно проектов: создание набора скриншотов, тизер на видео, полное видео по специальной ссылке.
Я бы сам с удовольствием создал подобную систему — масштабировать то есть что. Да и какие нагрузки нужно выдерживать — проноэфекты (типа хаброэфект, но долбятся активнее).
API пока еще в разработке, не успеле выкатить к моменту запуска. Так же, делаем еще iPhone-приложение.
Спасибо за статью.
nfs при росте вашего проекта может стать узким звеном. Почему бы не попробывать WebDav для операций записи на файлсервер и nginx на каждом файлсервере для «отдачи».
Лучше просто делать файлы доступными по http и чтобы раздающие сервера сами себе файлик подтягивали используя очередь. Уменьшит нагрузку на сервер кодирования в случае нескольких копий файла (вторая копия может быть сделана с сервера раздачи уже) + уменьшит риск положить все в случае возникновения большого количества файлов в очереди (в случае, например, сбоя системы копирования).
Очередь и WebDav друг другу не мешают, а даже наоборот :)

Забирать стораджами с конверт-сервера в принципе тоже можно, но только ради этого на него держать на нем php (perl/python/...) неохота…
Преимущество решения — если ролик копируется на много серверов, то можно сделать, чтобы с сервера кодирования он перетягивался только 1 раз. +существенно быстрее будут работать скрипты контроля целостности в случае, например, замены винта. Это, правда, решается rsync'ом, но такой вариант накладывает существенные ограничения на структуру хранения данных (некие папки должны быть полностью идентичны).
А еще управление файлами на стороне раздающего сервера позволяет скопировать популярный файл на несколько винтов или перераспределить файлы в соответствии с их востребованностью (чтобы нагрузка на винты сервера была более-менее равномерной). Аналогично можно по нескольким серверам перераспределением заниматься.
Можно, конечно, с одного места рулить, используя что-то типа fxp, но ту-же нагрузку на винты лучше все равно снимать локально.

В общем php или замена на раздающем сервере все равно пригодится со временем и схема, когда каждый сервер сам контролирует файлы, что на нем лежат, выглядит более гибкой.
videobam очень даже не плохой ресурс! Спасибо за статью!
У меня с опцией -threads 0 файлы портятся. mp4 не до конца кодируются, а 3жп вообще с ошибкой вылетают. ФФмпег, правда, не последний а 0.5.2
Ну у меня норм, мне кажется у тебя проблема в кодировке файла до конвертации.
Попробуй загрузить другой файл, записан на другое устройство для уверенности что это
неполадка сервиса, и если это так то напиши в поддержку что-ли… А если нет, сам понимаешь.
Спасибо за статью, по крайней мере, для меня сейчас эта тема весьма актуальна.

Возможно, вопрос немного личный, но какие сервера у вас стоят и какая для них рабочая нагрузка?
Кстати, а что будет если скриншот сгенерируется не по ключевому кадру и там будет размазня? Можно ли заставить ffmpeg/mplayer генерировать скришот именно по ключевому кадру в некотором временнОм диапазоне?
Мы делаем скриншоты два раза — на оригинальном файле, чтобы показать пользователю во время конвертации и для уже сконвертированного файла, где количество кейфреймов определено нами.
Нет, я имею в виду, можно ли сказать mplayer выдать в качестве скриншота именно кейфрейм? т.к. с большой вероятностью не-кефрейм может оказаться размазней
Насколько я знаю, mplayer в любом случае выдаёт скриншоты именно по ближайшим кейфреймам.
Спасибо за статью!

Работаю над функционалом видеохотсинга для своего проекта.
Тоже использую ffmpeg, и столкнулся с той же проблемой, которая присутствует у вас:

Видеоролик снятый на iPhone в портретной ориентации конвертируется и вопроизводится в неправильной ориентации.

Суть в том, что видео снятое в формате QuickTime в портретной ориентации, имеет неверную ориентацию при воспроизведении во всех плейерах кроме собственно QT. Примером такого видео может служить любой видеоролик снятый с помощью iPhone (3G/3GS/4).
Я нагуглил и опробовал исправление этого глюка с помощью фильтра transpose:

ffmpeg -vf="transpose=1"


Однако, я пока не смог найти способа программного определения неверной ориентации в файле-источнике.

Если уважаемая аудитория сталкивалась с этой проблемой и знает способ ее решения, буду весьма признателен за совет.
P.S. Ниже ссылка на видео загруженное мной для демонстрации этого глюка (снято на iPhone 3GS)
videobam.com/nQtbr
Взято с pauloliveira.net/tech/httppauloliveira-nettechp4

Videos on iPhone are recorded on Quicktime format. This format always record videos on landscape and insert metadata on the archive with the orientation info (portrait or landscape) on the moment that was recorded. Note that the iPhone consider the orientation at the moment that you touch the button “Record”, if you rotate the device during the recording the orientation doesn’t change.


Там же есть рекомендация по модификации исходников 2-х библиотек.
UFO just landed and posted this here
У вас не возникло проблем с загрузкой больших файлов при помощи SWF Uploader? У меня и моего коллеги стабильно наблюдались подвисания браузеров для файлов > 200-300Mb. Поэтому решили использовать обычную загрузку через HTTP.
UFO just landed and posted this here
Очень интересный опыт и оригинальная реализация очереди. Спасибо.
UFO just landed and posted this here
Круто. Это решение стоит выложить как опен-сорц проект например на гитхаб — я бы с удовольствием поучаствовал в разработке
Что именно вы предлагаете выложить на гитхаб? Архитектуру? Сборку используемых программ? Ключи для ffmpeg?

Кроме вебморды тут особых своих разработок то и нет, только success story применения готового.

ЗЫ: статья отличная, просто не понимаю, что вы предлагаете выложить :)
А название видеофайла меняете на синтетическое или оставляете оригинал? Если оставляете оригинал, то подход «все видео сохраняются в директории вида videos/a/ab/video.mp4, где “a” и “ab” — это первые буквы в названии видео» может вполне себе прибить ext3 при популярных названиях вида «sex», «porn», «putin» и т.п.
Как вариант генерить uniqid() и потом размещать по папкам в соответствии с двумя последними генерированными символами id. У нас так на хостинге картинок. Всего получается порядка 256 папок. Если надо больше — можно три символа использовать. Все равно используется БД и хранить там id клипа не сложно.
Оставляем оригинальные, но, действительно, нужно менять на синтетические. Спасибо за подсказку.
Уважаемые автор и хабросообщество, а не подскажите ли вы видеоплеер/либо ещё какое решение, которое позволяло бы проигрывать файлики по описанию близкие к SMIL. Приведу пример. Пусть у нас есть некий псевдо-файлик вида

    <videoset>
    <video from="5" to="15">1.mp4</video>
    <video from="5" to="15">2.mp4 </video>
    <video from="20" to="30">3.mp4 </video>
    </videoset>

в котором по сути описывается 3 фрагмента видео 10 секунд каждый из разных файлов.
Так вот, задача в том, чтобы плеер проиграл их НЕ последовательно (как плейлист), а расположил на одном таймбаре длинной 30 секунд, и при перемещении курсора на позицию например 25 секунд в в видеосете, начинала играться 5 секунда видео.
Пока что из всех, кто умеет это делать, я нашла только QuickTime plugin — но это не есть оптимальное решение не разу в плане универсальности и поддержки на разных устройствах. Очень хочется найти что-нибудь, написанное на flash/html5 для этих целей.
UFO just landed and posted this here
Затрудняюсь с ответом. Вероятно, Вам действительно поможет JS API плееров. Так же, посмотрите в сторону RTMP (http://flowplayer.org/plugins/streaming/rtmp.html).
UFO just landed and posted this here
Почти все написано верно, топик вообще очень полезный, у меня применены немного другие вещи (например ffmpeg из свн для генерации превьюшек или qt-faststart вместо mp4box — банально qt-faststart идет в составе сорцов ffmpeg), плюс сделан CDN для разграничения раздачи в мир и по Украине, но тем не менее нашел интересные себе вещи, которые тоже будет интересно попробовать.

Кроме того в комментариях много полезных мыслей, идей, решений.
UFO just landed and posted this here
вы наверное не совсем правильно поняли. ffmpeg у меня собран из SVN не для этого — мне нужна поддержка последних фич, т.к. в сборках чаще всего код устаревший и многие видео кодируются с багами и прочим.
UFO just landed and posted this here
это сейчас так, когда 0.6 версия ффмпег появилась. А когда была 0.5 и сборки были за май или ферваль 2009 года в репозиториях — было совсем не весело.

Поэтому имхо, сборка из SVN надежнее, чем ждать релизов.
UFO just landed and posted this here
>ИМХО, сборки менее надежны, т.к. существуют известные проблемы с обновлением.

О каких известных проблемах с обновлением речь?
UFO just landed and posted this here
для дебиан-подобных систем нет проблем делать сборку, а потом из нее пакет и таким образом устанавливать в систему. При этом не будет никаких проблем при обновлении, т.к. в системе это будет совсем другой пакет, к примеру ffmpeg_svn
UFO just landed and posted this here
а покажите, с какими ключами он собран «из коробки»?
UFO just landed and posted this here
UFO just landed and posted this here
даже если он установлен из пакета — пакет имеет конфигурационный файл и ключи сборки, с которыми был собран пакет.

Если вы запустите ffmpeg -v (к примеру) — то увидите список этих ключей. Их я и прошу.

Я спрашивал не про ключи кодирования. А вообще странный код у вас на самом деле — копирует видео в том же качестве, что и исходное… Какой толк от видео в HD к примеру зажатого в flv контейнер? Качество хуже, размер файла больше.
UFO just landed and posted this here
>Кстати, размер файла даже тут уменьшается, и значительно. Так как изменяется, как минимум, разрешение видео и частота дискретизации звука. Файл с фильмом в 500МБ в AVI контейнере превращается в 50МБ в FLV.

То, что уменьшается — это и ежику понятно. Только есть же еще битрейт и т.д… Качество же страдает в итоге… Или у вас главный параметр — размер стал меньше? )

Могли бы x264 загонять в flv и было бы качество намного лучше. Только там бы -sameq не прошло бы, насколько я помню.

Насчет ключей — вот что у вас должно было бы быть:

"# ffmpeg -v
FFmpeg version SVN-r26264, Copyright © 2000-2011 the FFmpeg developers
built on Jan 8 2011 17:33:47 with gcc 4.3.2
configuration: --prefix=/usr --libdir=/usr/lib --shlibdir=/usr/lib --bindir=/usr/bin --incdir=/usr/include/ffmpeg --enable-libx264 --enable-postproc --enable-libxvid --enable-pthreads --enable-libvorbis --enable-gpl --enable-x11grab --enable-shared --enable-libmp3lame --enable-libtheora --enable-libfaac --enable-nonfree --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libgsm --enable-version3 --enable-avfilter --enable-libspeex --enable-zlib --enable-libschroedinger --disable-encoder=libschroedinger --enable-libdc1394 --enable-libdirac --disable-decoder=libdirac --enable-libopenjpeg --extra-cflags=-Wall --cc=ccache cc --enable-swscale --enable-libvpx
libavutil 50.36. 0 / 50.36. 0
libavcore 0.16. 0 / 0.16. 0
libavcodec 52.107. 0 / 52.107. 0
libavformat 52.92. 0 / 52.92. 0
libavdevice 52. 2. 3 / 52. 2. 3
libavfilter 1.72. 0 / 1.72. 0
libswscale 0.12. 0 / 0.12. 0
libpostproc 51. 2. 0 / 51. 2. 0
ffmpeg: missing argument for option 'v'"
UFO just landed and posted this here
Sign up to leave a comment.

Articles