Обработка пользовательких видео

    Некоторое время я занимался (и занимаюсь до сих пор) веб-проектом, где необходимо было добавить фичу для загрузки пользовательских видео-роликов. Собственно, какие могут быть пользовательские видео? Очень разного качества и разнообразных форматов. Начиная от обычных flash файлов, которые представляют наименьшую проблему, до различных записей с телефонов. Встала задача — сделать демона, который бы занимался обработкой очереди загруженных файлов и выполнял следующие функции:
    — Конвертирование видео в flash формат (FLV), ипользуя VP6 кодек
    — Обновление метаинформации видеофайла
    — Создание thumbnails из видео
    — Дальнейшии манипуляции с БД

    Конкретно в этой статье я рассмотрю варианты обработки уже сконвертированного в формат flash видео-ролика. Итак приступим.

    1. Обработка метаинформации

    После того как мы получили заветный flash ролик, надо обновить его метаинформацию, а конкретно ключевые позиции. Это необходимо для поддежки режима просмотра — streaming. Т.е «прыгать» по длине видео без загрузки всего файла. Софт который этим занимается обычно именуют Metadata Injector. Для линукса я пробовал:
    — FlvTool2 — rubyforge.org/projects/flvtool2
    — Yamdi — yamdi.sourceforge.net

    FlvTool2 — приложение, написанное на Ruby. Сначала я остановился на нем. Но как показали испытания он не подходит для обработки больших файлов, т.к загружает файл в память, что есть не гуд. Некоторые файлы ( > 200 mb) обрабатывались по 5 минут. Есть свои плюсы — результат пишется в исходный файл. Так же позволяет «обрезать» файлы, что бывает очень нужным.

    Yamdi — приложение, написанное на C. Оригинальное название Yet Another Meta Data Injector. Работает очень шутро. Результат его работы представляет собой новый файл, что наиболее удобно, т.к исходник сразу можно удалить или перенести на длительное хранение. Так же позволяет вставлять ивент onLastSecond

    Оба приложения могут генерить XML файл с перечнем всех параметров, что дальше ипользуется при обновлении информации видео в БД.
    Свой выбор я остановил на Yamdi, как наиболее быстром.

    2. Создание thumbnails

    Итак, получили готовый FLV файл, XML c метаинформацие. Дальше для этого видео необходимо создать прерью 320x240 (картинка, которая отображается в плеере до того как юзер нажмет старт, пример можно посмотреть на RuTube), несколько мелких превьющек 120x96. В этой области тоже немного утилит.

    1. FFmpegffmpeg.mplayerhq.hu
    Базовая программа для работы с видео. Я использовал только для конвертирования видео, для остального — не очень подходит, т.к не дает возможности сгенерить все изображения ( с произольными временными точками ) за раз. Точнее там эта функция несколько ограниченная.

    2. PHP Extensionffmpeg-php.sourceforge.net
    Модуль для php который позволяет напрямую работать с flash файлом. Умеет собирать превью в GIF файл, иногда бывает нужным. Единственное, работает медленно по сравнению с другими утилитами. Плюс — удобный API, если в проекте используется PHP.

    3. FFMpegThumbnailercode.google.com/p/ffmpegthumbnailer
    Написана на С++ и работает очень быстро. Изначально автор создавал ее для декстоп менеджеров. С недавнего времени обзавелась кучей полезных фич, типо видео фильтров. Возможно использовать в своих C++ программах. Поддерживает 2 выходных формата (jpg/png), выбранную точку можно задавать с помощью абсолютного времени (hh:mm:ss) или в виде процента. Работает со всеми форматами отлично, но бывают сбои на специфичных файлах (mp4). Вообщем, идеально подходит для задачи.

    3. На заметку

    Первое время мы использовали JWPlayer 4 (без модификации) то столкнулись с проблемой. На серверах работал nginx 0.6.32, который, как выяснилось, не работал с этим плеером. Проблема заключалась в том, что новая версия плеера добавляля в строку запроса файла прочую информацию, вроде этой:

    myvideo.flv?start=2659763&width=280&client=FLASH%20MAC%209,0,124,0&version=4.0%20$Rev:%2030%20

    Решилось все очень просто, патчем для веб-сервера: www.ruby-forum.com/attachment/2307/patch.flv

    4. Заключение

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

    P.S. Давно на русском не писал ничего, может немного криво звучит :)
    Поделиться публикацией

    Комментарии 33

      –1
      Спасибо, интересно.
        +4
        а что ж самое интересное-то пропустили?
        • НЛО прилетело и опубликовало эту надпись здесь
          +3
          Что-то как-то мало информационной нагрузки.
            +5
            AVI в FLV (Подобрать под себя битрейт и размер), пример (все одной строкой):
            mencoder -forceidx -oac mp3lame -of lavf -lameopts abr:br=56 -srate 22050 -ovc lavc -lavcopts vcodec=flv:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -vf scale=320:240 -o test.flv test.avi

            скриншот:
            ffmpeg -y -i «test.flv» -vcodec png -ss 2 -vframes 1 -an -f rawvideo «test.png»
              0
              Не советую скриншоты делать ffmpeg'ом, ибо тормозит он (прокручивает до заданного места). Здесь лучше всего подойдет mplayer, он довольно быстро делает.
              +2
              Как по мне — то mplayer идеально справляется с созданием скриншотов, определением параметров видео и т.д.
              А для перекодировки использую mencoder, после которой обрабатываю файл flvtool2.
                0
                Приведите, пожалуйста, пример команды для создания скриншота.
                  0
                  mplayer -vf screenshot myvideo.avi

                  И при просмотре жать «s» в нужных местах.
                    0
                    Спасибо. Я ожидал, что это можно сделать исключительно консольными средствами.
                      0
                      Так для этого ж mencoder есть из того же пакета.
                0
                Умоляю, кто-нибудь, НУ ХОТЬ КТО-НИБУДЬ!

                СКАЖИТЕ! Как мне 250 Gb закодированного VP7'м кодеком видео на 64битном убунту сконвентировать в любой другой формат? mp4, к примеру!

                • НЛО прилетело и опубликовало эту надпись здесь
                    –1
                    # Часть ответа да ещё и не туда вставилась. Уже сколько месяцев эту багу исправить не могут?

                    Как правильно поставить виндовые кодеки (куда их засунуть) и почему после apt-get install mplayer а затем его запуска выдавалась ошибка о некорректном конфигурационном файле? (решение нашёл в гугле, но как-то непонятны мне причины ошибки)

                    tennessee.ubuntuforums.com/showthread.php?t=961182 — собственно мой тред. не у меня одного такие проблемы.

                    mencoder 232.avi -o test_converted.avi -oac copy -ovc lavc -lavcopts vcodec=mpeg4:mbd=1:vbitrate=1800 -ffourcc XVID

                    MEncoder 1.0rc2-4.2.3 © 2000-2007 MPlayer Team
                    CPU: AMD Athlon(tm) 64 X2 Dual Core Processor 6000+ (Family: 15, Model: 67, Stepping: 3)
                    CPUflags: Type: 15 MMX: 1 MMX2: 1 3DNow: 1 3DNow2: 1 SSE: 1 SSE2: 1
                    Compiled for x86 CPU with extensions: MMX MMX2 3DNow 3DNowEx SSE SSE2

                    success: format: 0 data: 0x0 — 0x148ad2
                    AVI file format detected.
                    [aviheader] Video stream found, -vid 0
                    [aviheader] Audio stream found, -aid 1
                    VIDEO: [VP70] 768x576 24bpp 25.000 fps 1887.3 kbps (230.4 kbyte/s)
                    [V] filefmt:3 fourcc:0x30375056 size:768x576 fps:25.00 ftime:=0.0400
                    Opening video filter: [expand osd=1]
                    Expand: -1 x -1, -1; -1, osd: 1, aspect: 0.000000, round: 1
                    ================================================== ========================
                    Requested video codec family [vp7] (vfm=vfwex) not available.
                    Enable it at compilation.
                    Cannot find codec matching selected -vo and video format 0x30375056.
                    Read DOCS/HTML/en/codecs.html!
                    ================================================== ========================

                    Exiting…
                      0
                      Не знаю, как в 64 битной Убунте, но в 32 разрядной винде бинарные кодеки скачиваются с оффсайта mplayer, вроде под названием windows-essential (да и в Линуксе в принципе те же кодеки используются), и все работает. Так что советую не заморачиваться с убунтой, если не работает.

                      А конфиг можно и руками поправить, в чем проблема?
                        0
                        ну как же можно не заморачиваться? это ведь видеоматериалы одного сайта, которые хотелось бы дать возможным просматривать онлайн.

                        изначально сделал сопоставление роликам материалов на ютьюбе (с помощью их api поиска), но не для всех нашлись версии. а просто так слить к себе и у себя сконвертировать — на мегабите это будет долго, очень (

                        датацентр в Германии — так что поехать туда с хардом тоже не получится (
                          0
                          Тогда могу предложить еще 2 варианта: 1) перекачать на другой сервер, с 32 битной системой. 2) Все-таки руками скачать и поставить кодеки, никаких 64-битных версий у них никогда не будет, так как это бинарные .dll файлы, которые выдраны из различных программ. Вроде как на 64-битных системах 32-битные программы дложны выполняться, хотя это конечно смотря какой процессор.

                          > это ведь видеоматериалы одного сайта, которые хотелось бы дать возможным просматривать онлайн.

                          И все лицензионные?;)
                    +1
                    sudo apt-get install ffmpeg
                    ffmpeg -i infile outfile.mp4

                    Должно сработать, если ffmpeg прочитает файл. Обратное происходит исключительно редко.
                    0
                    Ставил, ставил набор в32 кодеков.

                      0
                      это первая статья, так сказать вводная что-ли. вообще здесь не о том как сконвертить да скриншот получить, а скорее начало описания как все это дело прикрутить к видео сервису. скоро еще напишу
                        0
                        А как технически осуществляются эти прыжки с использованием тех самых метаданных? То есть, кликнул пользователь в незагруженную точку, что происходит?
                          0
                          в FLV видео загоняется информация о ключевых точках (cue points). т.е позиций в файле откуда начинать отдавать контент. а контент отдают модули flv streaming в nginx, lighttpd, и других серверах
                          0
                          Спасибо за статью, давно искал что-то на эту тему!
                            +1
                            Вместо flvtool2 можно использовать flvtool++:

                            flvtool++ is a tool for hinting and manipulating the metadata of FLV files. It was originally created for Facebook's Video project (http://facebook.com/video/) for fast video hinting. It is loosely based on the Ruby FLVTool2, but is written in C++ for performance reasons.

                            mirror.facebook.com/facebook/flvtool++/
                              0
                              а он как работает? пишет новый файл или в оригинал? как долго будет выполняться обработка файла 700 мб?
                                0
                                может писать новый, может в оригинал добавить. файлы по 300 — 400 метров обрабатываются по несколько секунд.
                              0
                              Модуль для php который позволяет напрямую работать с flash файлом. Умеет собирать превью в GIF файл, иногда бывает нужным.

                              php-ffmpeg умеет делать ЛЮБОЙ формат скриншота, ибо выдергивает скриншот напрямую в GD Image Format — а там хоть куда
                                0
                                я не говорил что он этого не может. вообще GIF собирать самое то с Imagick
                                0
                                а вопрос… как заставить понимать пхп, что начинается процесс демона? (конвертация итд)
                                просто я в этом полный ноль и хотелось бы понять что к чему

                                ну как я понимаю — загружаем файл… а вот что далее?
                                  –3
                                  Тоже была необходимость сделать сервис с использованием пользовательского видео. Потом посчитал, подумал и решил остановиться на rutube api.
                                    0
                                    По собственному опыту скажу, к сожалению не удается довести порядка 10% видео до автоматической обработки, что на больших объемах проблемно, используя mencoder и ffmpeg, там есть определенные проблемы, очень часто невозможно seek файлу сделать, для отрывка. Но они молодцы, других альтернатив я не вижу, и разработчики постепенно правят все ошибки.
                                      0
                                      >очень часто невозможно seek файлу сделать, для отрывка

                                      Даже с -forceidx?

                                      В крайнем случае, можно прогнать mencoder -oac copy -ovc copy -of avi input.avi -o output_fixed.avi
                                        0
                                        Делал для препода девушки похожий проект по найденым мануалам в сети

                                        Похоже прошёл тотже путь, что и автор темы.
                                        Собственно основная часть моего кода такова
                                                exec ("/usr/local/bin/mencoder '".$target_name."' -o '".$target_path.$filename.".flv' -of lavf  -oac mp3lame -lameopts abr:br=56 -srate 22050 -ovc lavc -ofps 25 -lavcopts vcodec=flv:vbitrate=1000:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 > '".$target_path.$filename.".1.log' 2>&1");

                                                
                                        exec ("/usr/local/bin/flvtool2 -UP '".$target_path.$filename.".flv' >'".$target_path.$filename.".2.log' 2>&1");

                                                
                                        exec ("/usr/local/bin/mplayer -nosound -vo jpeg:outdir='".$target_path."' '".$target_path.$filename.".flv' -frames 1 -ss 0 >'".$target_path.$filename.".3.log' 2>&1");

                                                
                                        rename("uploads/00000001.jpg","uploads/".$filename.".jpg");  

                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                        Самое читаемое