Dec
18
|
Видеохостинг своими руками
|
Как и обещал, немного расскажу о том, как создать свой видеохостинг «с нуля».
Все, что я дальше напишу — мой личный опыт и возможно не является доскональным решением вопроса и есть другие, более оптимальные (возможно даже в комментариях отметятся люди, которые знают как сделать лучше — буду благодарен).
Вопрос создания
Основная сложность, как на меня, это закачка, обработка и отдача видео.
Закачка видео
Основная задача и проблема, как на меня тут следующая: загрузка видео (как впрочем и его отдача) не должна тормозить работу
Одну машину называем host.ru, вторую upload.host.ru и используем технологию (звучит пафостно, но это не технология совсем, так, умное название) CDS — Cross Domain Scripting (больше об этом можно узнать в гугле). Это позволит нам с помощью javascript, отправлять запрос на upload.host.ru, а он, в свою очередь, благодаря CDS будет иметь возможность вызывать куски
В качестве серверной части, которая будет отдавать информацию о процессе закачки я выбрал расширение — uploadprogress для пхп. Расширение стабильное, а следовательно можно использовать в работе и не переживать о багах. Примеры использования приводить не буду — думаю пытливый читатель найдет в гугле.
Таким образом все счастливы — пользователь видит информацию о прогрессе загрузки видео,
Все это я решил использовать для того, чтобы не разносить вебморду проекта на две машины, что неудобно для девелопмента и синхронизации.
Обработка видео
При обработке видео стоит вопрос, как правильно обрабатывать видео, чтобы не ужимать его чрезмерно.
Машинка, которая называется upload.host.ru имела на борту у себя операционную систему Debian. На ней с помощью apt’a было установлено FFMpeg и Mencoder в качестве конвертеров для обработки видео.
Видео после того, как заливалось пользователем, складывалось в отдельную папку, откуда забиралось скриптом, который раз в минуту проверял список необработанных видео (у обработанных видео добавлялся префикс .processed в названии) и забирал на обработку.
Скрипт был написан на перле, администратором, который помогал мне все это добро настроить. Впоследствии я уже только занимался модификацией данного скрипта (заодно и о перле немного больше узнал).
Основная проблема с обработкой видео состояла в том, чтобы подобрать правильные ключи к конвертеру, которые будут обеспечивать максимально «правильную обработку» и перекодировку видео. Под наиболее правильной я понимаю такую, которая не будет увеличивать размер видео в результате перекодировки, будет уменьшать разрешение видео, если оно слишком большое и будет правильно его конвертировать. Т.к. я до этого вообще никакого понимания о видео и его особенностях и форматах толком не имел, для меня это стало основной головной болью, т.к. часто получалось, что либо видео не обрабатывалось, либо увеличивалось в размере, либо глючило (видео не совпадало с аудио), либо тормозило при проигрывании (разрешение при декодировке не было изменено, поэтому так происходило).
Во многих туториалах советую указывать битрейт видео при декодировании. Однако нельзя указывать тупо битрейт, не зная текущий битрейт видео. Например пользователь заливает видео с YouTube, которое имеет битрейт 68К. Тогда нужно сначала определить битрейт видео и только потом принять решение, в какой битрейт его кодировать. Я выбрал такую стратегию при кодировке видео:
- Если битрейт видео больше 1024К, то видео кодируем в два битрейта — 128К и 1024К (для обладателей разных каналов по скорости интернет)
- Если битрейт больше 128K, но меньше 1024K, то кодируем только в 128К
- Если битрейт ниже 128К, то битрейт не меняем и используем ключи к ffmpeg такие
«-sameq -vcodec copy». Где первый ключ говорит, что при кодировании нужно сохранить тоже качество видео, что и у исходного файла, а второй говорит, что нужно скопировать кодек для кодирования из исходника.
Определить текущий битрейт видео можно довольно просто (не забудьте только поставить mplayer в системе), запустив следующую команду в консоли:
mplayer $wrkfile -identify -vo null -nocache -nolirc -nojoystick
-channels 6 -loop 1 -frames 1 | grep ID_VIDEO_BITRATE
Бывают случаи, когда mplayer не определяет битрейт видео, либо ставит его равным 0, тогда для определения битрейта можно воспользоваться утилитой ffprobe (установить можно через
ffprobe -show_files $wrkfile | grep bit_rate
$wrkfile — полный путь к видеофайлу, информацию о котором мы хотим получить.
Аналогичными командами можно получить и разрешение текущего видео:
mplayer $wrkfile -identify -vo null -nocache -nolirc -nojoystick
-channels 6 -loop 1 -frames 1 | grep ID_VIDEO_WIDTH
mplayer $wrkfile -identify -vo null -nocache -nolirc -nojoystick
-channels 6 -loop 1 -frames 1 | grep ID_VIDEO_HEIGHT
по которым можно принять решение, нужно ли менять разрешение видео. Я для себя решил, что видео буду конвертировать с разрешением 640 на 480, если закачанное видео больше этого разрешения.
После получения исходных данных о видео — можно его кодировать, указав правильные ключи для тех вещей, которые мы меняем. Вы можете о ключах узнать в руководстве к конвертерам, либо я более подробно опишу процесс конвертации в последующих заметках на эту тему, если будет нужно (или если попросят раскрыть тему полнее).
Все, теперь остается сгенерировать
ffmpeg -ss $seconds -i $outfile -vcodec mjpeg -vframes 1 -an
-f rawvideo -s $thumb_size preview.jpg
Данная команда сгенерирует картинку в формате jpeg для указанной секунды ($seconds) обработанного видео ($outfile) указанного размера ($thumb_size — в формате 160×120). Таким образом можно сделать несколько
На этом обработка видео завершена, данные можно записывать в базу с флагом, что видео обработалось.
Отдача видео
С этим вопросом я тоже не стыкался до этого в целом. Решено было отдавать видео пользователям посредством Nginx, как
Настроив домашнюю директорию, куда складируются обработанные видео, теперь можно отдавать видеофайлы в наш выбранный
Отдельным вопросом стоит вопрос
Для решения этой задачи, опять же, использовался Nginx, т.к. он уже содержит готовый модуль для этих целей — http://sysoev.ru/nginx/docs/http/ngx_http_flv_module.html (при условии, что мы отдаем конент в формате flv. Но можно отдавать и в mp4, плагин для псевдостриминга для mp4 для nginx тоже есть — http://wiki.nginx.org/NginxMP4StreamingLite (вполне возможно есть и другие решения)
На этом все или пока что все. Или почти все. Т.к. это только очень краткое описание того, что нужно сделать, чтобы поднять свой видеохостинг. В следующий раз постараюсь описать каждый из этапов
Если есть вопросы — пишите, постараюсь ответить, если буду знать ответ и будет время.
P.S. Про HTML5 и Theora можете не спрашивать, активно слежу за развитием в данной области, надеюсь, что скоро вообще не нужно будет использовать сторонние
19.12.2009 в 00:26
Мы недавно делали подобный сервис. Вот некоторые моменты, которые выяснились нами в процессе:
Сконвертированное видео хорошо еще дополнительно обрабатывать с помощью flvtool2 или yamdi (этот быстрее). Эти команды расставляют метаописание по всему файлу. Нужно для того, чтобы можно было воспользоваться ngx_flv и перемоткой в любое место.
Превьюшки делали с помощью ffmpegthumbnailer.
Отдавали видео с помощью заголовка X_ACCEL_REDIRECT, т.к. надо было дополнительно перед отдачей сделать множество проверок.
Ну и кодеки для mplayer/mencoder лучше брать самые свежие или даже из СВНа. Потому что юзеры иногда заливают видео в таких невероятных форматах, что диву даешься.
19.12.2009 в 00:34
point:
Верно упомянули, я забыл про это сказать. Я использую yamdi для этих целей, т.к. после перекодировки метаинформацию нужно инжектировать в полученный файл.
А зачем? Вариант описанный мною не требует установки дополнительных вещей. Или вы не знали про этот способ?
Какие проверки например?
У меня так вышло, что mencoder у меня используется только для формата application/octet-stream .
А вот насчета форматов – это верно, у пользователей куча разных видеоформатов бывает..Но это и хорошо, для откатки скрипта декодера.
19.12.2009 в 01:14
> А зачем? Вариант описанный мною не требует установки дополнительных вещей. Или вы не знали про этот способ?
Знали, но уже не вспомню, почему остановились на этом
> Какие проверки например?
Аутентификация, проверка балланса, принадлежности к “френдам” и т.д.
> У меня так вышло, что mencoder у меня используется только для формата application/octet-stream .
mencoder == mplayer без возможности вывода видео на графическое устройство. А с mime заголовком application/octet-stream можно отдавать всё что угодно, хоть текстовый файл.
> Но это и хорошо, для откатки скрипта декодера.
На staging мы тоже обкатывали. Всё было ок. Но реальные пользователи внесли свои коррективы и нужно было срочно накладывать патчи на кодеки и компилировать их вручную. Ух. Вспомню, вздрогну
19.12.2009 в 01:40
Тоесть проверку доступности видео?
Нет, это все понятно, я имею ввиду, что есть файлы, которые имеют тип, например “ISO Media” и определяются через mime как octet-stream. Про то, что отдавать можно что угодно – это понятно, но речь о видео, которые пользователи заливают, а мы декодируем.
Наример какие патчи на кодеки и компилирование вручную? Мне такого не пришлось делать совершенно, но были другие проблемы, например пришлось использовать форсирование типа видео при кодировании через ffmpeg, т.к. иначе он не понимал файл и писал, что не может его декодировать.
20.12.2009 в 15:05
Судя по активности комментаторов, больше эта тема никому не интересна?
Жаль, думал будет больше людей.
20.12.2009 в 22:35
Та ні чому тема взагалі то дуже цікава.
Ми особисто також пишемо сервіс трансляції тематичного відео правда все це має працювати на python(django).
Можна згадати про готові модулі для роботи з ffmpeg + про сервери стрімінгу, також коли кількість відео значно росте ( up 500Гб ) слід подумати про те щоб його “правильно” складати.
Ми вибираємо для цього youtube, благо що у них api відмінне.
А взагалі стаття корисна. Дякую.
20.12.2009 в 22:58
rootart :
В каком плане? Раскладывать на разные машинки просто и раздавать с них же.. по-моему тут все тривиально, разве нет?
И почему именно 500 Гб?
20.12.2009 в 22:58
rootart :
В каком плане? Раскладывать на разные машинки просто и раздавать с них же.. по-моему тут все тривиально, разве нет?
И почему именно 500 Гб?
И еще не понял – зачем создавать видеохостинг и видео хранить на ютубе? В чем соль?
21.12.2009 в 00:32
> Тоесть проверку доступности видео?
Не доступности, а проверку прав доступа.
>Наример какие патчи на кодеки и компилирование вручную?
Простите, тоже уже не скажу. Давненько это было. Просто юзер залил видео, оно не сконвертилось. Попробовали вручную, получили trace ошибок. Погуглив, нашли патч, который потом лёг в СВН основного проекта.
А компилировали через FreeBSD-шные порты. Там видно весь лог ошибок.
>В каком плане? Раскладывать на разные машинки просто и раздавать с них же.. по-моему тут все тривиально, разве нет?
Если нет задачи контроля доступа к видео, то конечно проблем нет. Иначе нужен хороший программный дизайн, чтобы небыло single point of failure. Наскоком и без хорошей теоретической подготовки хорошо с первого раза не получится.
21.12.2009 в 01:05
Еще вопрос по теме: кто-то делал что-то похожее на Related Videos у YouTube ?
Интересует алгоритм, в открытых источниках толком ничего нет по этой теме. Я сделал по-своему, но выходит не очень вкусно, хотелось бы красивее алгоритма.
24.09.2010 в 22:47
[...] предыстории: с самого начала видеохостинга у меня ffmpeg был просто втупую поставлен через менеджер [...]