Как порезать видео на кусочки, перекодировать с ffmpeg и собрать в конечный файл?
Представим себе, что пользователь загружает 4Gb видео на сайт. Можно дождаться окончания его аплоада и приняться за кодирование в нужный формат.
А можно по мере аплоада отрезать куски видео, кодировать их отдельно, возможно, используя несколько серверов, а потом собрать в конечный результат.
Вопрос про второй вариант: кто-нибудь знает, как?
P.S.: важно, чтобы можно было перекодировать таким образом любое видео, которое ffmpeg может перекодировать без деления на куски.
P.P.S.: в результате нужен .mp4 (h264) файл.
Если вам зальют файл mp4 у которого информация о контейнере только в конце файла, то хрен вы что сделаете с бинарной информаций, нет сведений ни о чем. Даже если вы умудритесь кодировать файл, то суть кодека h264 в би фреймах, где кодируются кадры насквозь. Берется пакет картинок из 24 штук, далее вычисляются вектора перемещения пикселей — статические остаются на месте и еще куча всего… Вы на склейке если глюки в звуке не получите, то квадраты по картинке точно. Это в приницпе нарушение логики h264 алгоритма то что вы хотите. Хотите быстро кодировать, используйте крутое железо и заточеные алгоритмы под него. Таже самая технология cuda даст прирост огого.
С железом все ок — кодирование проходит быстрее аплоада (3МБ/с).
Я игрался с этой возможнстью, действительно, уперся в то, что не любой формат удается так порезать, но с некоторыми это получилось. Получившиеся кусочки потом не всегда удавалось собрать в единый видео файл.
А как это делает youtube? На сколько я понимаю, он использует тот же ffmpeg?
Ютуб страдает тем же самым. Я заливал на него разные ролики — не понял законономерности когда кодирует при заливке когда ждать полной заливки. У ютуба до html5 был загрузчик на яве ( в нагрузку ). Сдается мне стянуть информацию о видео видеоролике т.е локально прочитать все его свойства можно через html5.
Но кодировать получанные в данные в h264 не получится, ибо сам по себе кодек основан на промежуточный ключевых каддрах и тм алская математика — склейки не получится.
Слается мне ютуб делает хитрее! Он сначала кодирует в средний формат FLV 640 на 480 — а он помоему как раз очень удобно склеивается, а потом, когда пользователь видет залитый результат — предупреждает его, что в лучшем качестве еще не готово! и именно лучшее качество есть h264.
Т.е предвариловка в flv — месседж что лучшее качество fullHD еще ждать, а потом уже и это успевает.
html5 имеет file api — он умеет файлы без аплоада отображать в доме. Не во всех браузерах работает. Flash вообще может впитать в себя весь файл и получить его байткод, но если речь идет о 4Gb, это плохая затея.
FLV — это неплохой вариант, на самом деле. Минус в том, что его не получится проиграть на мобильных устройствах, а вот на самом сайте — легко. Да и вообще это вполне разумно сначала кодировать в минимальном разрешении, а потом в остальных.
Допустим, задачка немного меняется: кодируем не в h264, а в flv.
Как резать, как кодировать и как потом собирать?
Я пробовал резать ffmpeg-ом (используя тот же кодек), но это плохо тем, что некоторые видео форматы приходится дочитать до этого места, прежде чем удастся отрезать. Пробовал просто cut-ом.
ух. FLV у нас оказывается тоже контейнер) Видимо он просто для потока хорош.
Нy раз есть такие программы rutracker.org/forum/viewtopic.php?t=3700352
не знаю как они работают покачеству…
то суть я понимаю их такова:
Нужно найти в контейнере точно начало потока и точно его конец. Обрезать соединять здесь видео можно на уровне бинарных данных. Если часть выбрали, то просто цепляем к нему хедер и футер с оригинального файла. Но это не прокатывает, что то нужно еще делать:
Я как то баловался с GOPRO видюшками, просили восстановить видео с убитой гоу про. Файл физически набит информацией, но походу метку atom контейнера mp4 gopro пишет по окончанию записи.
Кидал поток бинарный через winhex из одного файла в другой — думал что плеер переключится легко — ведь ролики с одной камеры — все идентично, но нифига не вышло! не так просто оказалось) Видимо обрезка должна происходить на стыке GOP ( group of picture ) между ключевыми кадрами формата. Winhex же просто матрица) Вобщем здесь все сложно, нужно ковырять было жестко видеоконтейнеры… Потому в своем случае я нашел прогу которая пыталась! восстановить видео по шаблону, просила дать хороший файл с той же камеры и прочее… сделала…
На сколько хватает моих бедных знаний то нужно:
— поделить видео на секции, делают же закачку даунлоад менеджеры по сегментам
— к примеру на 5 секций. с 0 по 10 байт с 10 по 20 и так далее. Ждем загрузки всех байт из какой либо секции ( ) присваиваем ей имя нужный порядковый номер.
— говорим энкодеру что это вот, бать, входной формат такой h263 25fps, не черезстрочное, и вся прочая мутота с оригинального заголовка файла.
— энкодер выдает новый файл контейнер (если просто видео поток то хорошо, не надо распаковывать)
— делаем последние 3 шага со всем сегментами, клеим их так же на уровне байтов, упаковываем в контейнер. Отдаем браузеру. Здесь важный шаг — какой формат можно так легко кромсать и склеивать без глюков при склейке?
— Может ютуб отдает файл при загрузке сразу энкодеру, а когда тот натыкается на конец байтов со входного видеофайла ( ну не залился он еще) просто делаем энкодеру паузу на 5 сек и новая попытка.