Pull to refresh

Comments 57

Для получения информации о видео можно поставить модуль для php ffmpeg
Многие на него ругаются, мол, определять размер видео нужно редко, а память будет кушаться всегда.
Хотелось бы продолжения как это потом показывать и т.д.
Спасибо за статью!
ну и apt-get/yum/brew install ffmpeg
UFO just landed and posted this here
Статья для начинающих. Да и в случае желательности свежака можно использовать другие репозитории, посвежее.

Можно и собрать самому, но обычно к этому времени человек уже способен собрать ffmpeg и сам.
UFO just landed and posted this here
Вот тольк одно непонятно, зачем автор гонит x264 в контейнер flv? Flash умеет и mp4 контейнер играть, а вот модули, например к nginx, реализующие псевдостриминг работают или с flv контейнером и родным кодеком (flv модуль) или x264 и только с mp4 контейнером (x264_streaming_module). Поэтому выгоднее кодить в mp4 сразу
У меня nginx со штатным flv модулем, и псевдостриминг работает для h264 в flv конвертере.
Неужели Сысоев приделал x264 стриминг в flv? Пойду почитаю. Но верится с трудом
Поглядел, в changes изменений не видно. Значит кто-то что-то путает
Сысоев ничего не менял.

flv модуль nginx принимает смещение файла в байтах. Поэтому он может хоть tar стримить ))
Другое дело, будет ли тот поток данных, которые вернёт nginx, пригодным для проигрывания видео.

Я сам не понимаю, почему у меня всё работает. Ведь для h264 в mp4 контейнере смещение передаётся не в байтах, а в секундах и серверу приходится напрягаться чтобы определить правильное смещение.

Скорее всего мне просто везёт и работает всё весьма условно. Перемотка, наверное, очень неточная получается. Я думаю, многое ещё зависит от плеера. У меня используется JW Player 5.
Ха. Вот и вылезла проблема с перемоткой, на которую я наткнулся в том числе. На самом деле — flv модуль не умеет по честному стримить x264 внутри flv. Он тупо его отдает как range. Что сносит голову любому плееру. Ибо при этом не отдаются никакие равильные метаданные.

>А вот стриминг mp4 использовать крайне не рекомендуется.

Не рекомендуется опять же в лоб. Дело вот в чем. Так как для mp4 требуется смещение в секундах, то модулю надо найти соответствующий byte range. Решается прогоном через mp4box с перемещением метаданных в начало, и принудительным хинтингом, к примеру по умолчанию, в 500 мс. При этом плееру отдаются метаданные с соответсвием time-keyframe-byte-offset. По которым программер плеера должен делать принудительно seek в обозначенные позиции времени. При этом модулю не приходится «елозить» по файлу в поисках нужного офсета, ибо он знает его из метаданных.

В девелоперских целях оно у нас работает именно на том x264 модуле, без проблем
В flv можно (нужно) точно так же запихнуть в начало метаданные. yamdi в помощь.

А модуль nginx с метаданными mp4 знаком, чтобы не приходилось елозить?
> В flv можно (нужно) точно так же запихнуть в начало метаданные. yamdi в помощь.

Да, у нас это используется. Только вот стоковый flv модуль был сделан для отдачи flv (доставляет строка «static u_char ngx_flv_header[] = „FLV\x1\x1\0\0\0\x9\0\0\0\x9“;»).

> А модуль nginx с метаданными mp4 знаком, чтобы не приходилось елозить?
Ну скажем так. Ввиду того, что написан он довольно коряво, ему это необязательно. Исходя из запрошенного времени, битрейта каждого трека и т.п. инфы о ролике, он находит offset до ближайшего keyframe «математикой». Почему в кавычках? А вот именно потому, что он дергает не метаданные (которых может и не быть, что логично), а делает анализ стуктуры файла, и после этого делает вырезку куска из каждого трека. То есть файл практически всегда читается полностью. Именно поэтому нагрузка на диск больше, а не потому что он «елозит» по файлу.
По сути — когда в особо неудачном mp4 файле нет ни метаданных, ни хинтинга, модуль тот читает весь файл, и по сути собирает все метаданные заново, основываясь на которых выдергивает нужные куски треков, выровненные по ключевым кадрам.
Это как вы себе представляете mp4 файл без метаданных?

mdat атом без moov невозможно восстановить. В нём всегда есть метаданные. Другой вопрос в том, что фреймы могут идти неравномерно. flv всё таки полу-потоковый формат, а mp4 чисто файловый контейнер.
Mod-H264-Streaming-Nginx-Version2 собственно и использует парсинг всей этой фигни (mdat atom moov) для нахождения вырезанию нужного. Имелось ввиду, что он не использует те «метаданные», которые использует Flash, и которые, насколько я понимаю, и переносят в начало всякие MP4Box и Yamdi
flash не использует никакие метаданные для seek-а, хотя как раз мог бы.

MP4Box переносит вперед moov атом. Это нужно для того, что бы при скачивании mp4 файла можно было уже сразу понять, как разложены данные в mdat и начать сразу проигрывать.

yamdi вообще mp4 не обрабатывает.
>yamdi вообще mp4 не обрабатывает

Yamdi применительно к FLV конечно же. MP4Box/qt-faststart для MP4

>flash не использует никакие метаданные для seek-а, хотя как раз мог бы.

Решается програмным путем, я уже описывал как. По событию OnMetadata можно дернуть метаданные, включая два массива: 'filepositions' и 'times'. Первый задает соответствие keyframes->bytes, второй keyframes->times. Соответственно можно плеером прыкать четк по ключевым кадрам (при этом прося у flv модуля байты, а у mp4 модуля время)
Через qt-fastart переместить в мп4 метаданные в начало и будет нормально стримить nginx
Может, я чего не так делал, но файлики, прогнанные через MP4Box почему-то отказываются нормально воспроизводиться на iУстройствах, остановился на qt-faststart. Особо не разбирался почему и что там криво работало — замену нашел и ладно.
А потому что iDevices расчитаны на слегка другую упаковку, которая ближе к quicktime mp4.
Тем что ноги ее растут из QuickTime и изначально qt-faststart служил как раз для хинтинга mov. И стриминга через QT/Darwin Streming Server
Жаль не растрыта тема cfr и 2pass кодирования видео, а также параметров пресетов.
Стандартное кодирование видео — это хорошо, но если вам нужно балансировать между хорошим качество и размером видео — необходимо создавать свои пресеты, а также выбирать метод анализа видео изходя из ожидаемого результата, и времени, которого надо потратить на конвертацию.
Ну эта тема гораздо обширнее, чем 200 параметров libx264 степень влияния на результат которых, может свести с ума =)

Вам же требуется многомерная оптимизация по следующим характеристикам:
1) результирующее качество
2) битрейт
3) флуктуации битрейта
4) время сжатия

Могу по своим наблюдениям сказать: один из самых сильно влияющих параметров — это qpmin
Если он ниже 25, то условно SD на атоме не сжимается. Если выше, то сжимается с запасом.
Второй очень важный параметр — subme. Если его опустить с 5 до 3, то скорость сжатия может без особого изменения битрейта увеличиться в два-три раза.

Остальные параметры так же важны, но они не на каждом видео дают такой же резкий и хорошо наблюдаемый результат.
Тут нужно сделать отступление. При конфигурировании x264 БЕЗ параметра --enable-shared библиотека будет инсталлироваться в каталог по умолчанию (у меня это /usr/local/bin) и при запуске ffmpeg будет выдавать ошибку о неизвестном местоположении библиотеки libx264

На сколько я помню без параметра --enable-shared библиотека не будет собираться ВООБЩЕ. Будет скомпилирован только исполняемый x264 (для чего он нужен — не знаю).
Ну и собственно именно с параметром --enable-shared бибилотека БУДЕТ устанавливаться в каталог по-умолчанию, что и показал вам checkinstall.
А еще есть параметр --enable-static.

Помог параметр --prefix=/shared при конфигурировании x264.

Интересно, чем? И зачем засорять корень всякими сомнительными директориями?
Помог тем, что с ним все заработало
Не верю что помог именно он.
Вообще с трудом представляю ситуацию, когда компилятор захотел бы искать библиотеки в нестандартных местах, если только перед этим ему не подсказали искать их именно там.
Хотелось бы узнать возможно ли в процессе захвата видео с устройства выбирать отдельный источник аудио и как это сделать. Рыл доки — не нашёл внятного описания.
Жаль, что не описан процесс кодирования в h264 + mp4. Кодировать в flv-контейнер — это еще ничего, а вот когда нужен h264, да еще и с псевдостримингом — вот тогда начинаются танцы.
Да какие там танцы то?
Все точно так же
Кодим:
ffmpeg -i source.file -s 640x360 -f mp4 -vcodec libx264 -vpre hq -threads 0 -b 1500k -bt 1500k -r 25 -g 25 -acodec libfaac -ab 96k -ar 22050 filename.mp4
Хинтим:
MP4Box -inter 500 filename.mp4

Натачиваем кривоватый h264.code-shop.com/trac/wiki/Mod-H264-Streaming-Nginx-Version2
PROFIT!
ЕМНИП, mp4box был(есть?) крайне кривой и крешился через раз.
Ну у меня 0.4.6-DEV-rev2784, более-менее стабилен.
Добавил ваш комментарий в избранное, проверю по необходимости.
Я с этим ковырялся года два назад, помню что вроде компилил mp4box руками и не совсем удачно оно все работало, но свое дело делало.
недавно встал вопрос, не смог найти ответа. Может вы подскажете: может ли ffmpeg картинку как-нить обработать? Смысл в том, что иногда попадаются битые джепеги, у которых похоже не прописаны заголовки. В итоге просмотрщики картинок их нормально открывают, а к примеру гуглопикаса, не принимает этот файл, типа как не картинка это. Вот и думаю как можно такие файлы отрипейрить.
А не пробовали через ImageMagick?
только ради этого его ставить совершенно не хочется
Пресеты ffmpeg-а уже канули в Лету, сейчас они рекомендуют пользоваться штатными пресетами от libx264.

Не понял. Зачем вы удалили пакеты и собирали сами из исходников?
потому что ffmpeg из пакетов не работает с x264 из пакетов, наверное поэтому
есть в принципе debian-multimedia.org но очень легко получить жуткую свистопляску с пакетами.
ога, debian-multimedia.org конечно есть, и свистопляска присутствует. Нет, в принципе, для новичка и если кодить только в FLV можно поставить из него все и оно даже будет работать. Но вот тот же пресловутый экстеншн php-ffmpeg на ихнем ffmpeg уже не соберется. И готового x264 у них нет, а ffmpeg собран без его поддержки. В общем через полгода мучения, пришлось собрать все ручками комплектом.
ну да, обычно «ручками» всё и приходится.
мы использовали путь, менее затратный по процессорному времени, когда убедились, что ffmpeg для быстрой обработки нам не подходил: заменили его на mencoder, который идёт в debian отдельным пакетом.

с тех пор только его и используем.
Еще год назад это было одно и тоже. В чем фокус?
Чем же он вам не подходил? Вы ведь не думаете, что в mencoder стоит другой энкодер для H264?
команда time показала, что на одном и том же файле на одном и том же железе mencoder почему-то работает в три раза быстрее. можете померять.
поверьте, вы просто не так пользовались. mencoder и ffmpeg — это по факту разные оболочки к одному и тому же. Да, в mencoder-е есть немного другого кода, связанного с упаковкой контейнеров, но он практически не влияет на скорость работы.

Если у вас была разница в 3 раза, то это 100% исключительно настройки энкодера. Например, вы могли неправильно указать опцию threads или вообще не лазили в опции, тогда явно тут ffmpeg не причем.

Пожалуйста, не распространяйте ложную информацию о том, что они отличаются скоростью.
ok, как появится время — проверю.
Уважаемый(?) Blackman — когда сдираете мануал с другого сайта, иногда включайте мозг, пожалуйста.

Рерайт текста с небольшими изменениями, изменением порядка и даже одинаковыми ошибками в командах — это круто.

Оригинал тут: tresnet.ru/archives/223

В приличном обществе — за такое не инвайт, а канделябр полагается.
В строках 42-43 функции get_video_size() перепутаны ширина и высота, должно быть:

$vheight = $oheight = $ma['height'];
$vwidth = $owidth = $ma['width'];
$ffmpeg_path = 'ffmpeg'; // Путь к ffmpeg
$in = 'ATB — Let You Go.avi'; // Входящий файл

$command = $ffmpeg_path. ' -threads 0 -y -i "'. $in… $out. '"';
$conv = exec($command);


Понимаю, что возможно так и есть, но лучше лишний раз предупредить.
Если «Входящий файл» берется с названия файла переданного на сервер, то посоветовал бы, название обрабатывать, дабы избежать инъекции.
Sign up to leave a comment.

Articles