2

Я читал о резке и сращивании с использованием concat, но этого мне недостаточно.

Я хотел бы вырезать отмеченные части видео и объединить в один видеофайл без перекодирования. Можно ли разрезать и объединить (в памяти) за один раз?

Не должно быть никакого теоретического ограничения на количество видео частей, которые нужно вырезать или объединить. Аудио должно быть синхронизировано.

Видео: H.264+AAC

Редактировать:

Из ответов я узнал, что перекодирование видео все еще необходимо.

Я хотел бы уточнить, что вырезание видеоклипов из середины видеофайла может выполняться в несколько этапов. Я думал, что обработка видео за один раз была бы мудрой производительностью, сохраняя некоторую активность ввода-вывода. Однако это не самоцель.

1 ответ1

5

Ваш вопрос, если я правильно понял, состоит из четырех основных частей:

  • Как вырезать отрезок времени из фильма
  • Как объединить несколько сегментов вместе
  • Как сделать вышеупомянутое, не перекодируя фильм, следовательно, не теряя качества
  • Как сделать вышеупомянутое эффективно с точки зрения скорости

Сокращение отрезка времени

Вы можете отрезать сегмент, пропустив его начальную точку с помощью опции -ss , затем либо установив продолжительность сегмента с помощью -t , либо установив конечную точку с помощью -to:

# skip 30 seconds, then copy the next 60 seconds
ffmpeg -ss 30 -t 60 full-movie.mp4 segment.mp4

В документации ffmpeg, пожалуйста, обратитесь к разделу 5.4 Основные параметры относительно разницы между размещением параметров -ss и -t перед входным файлом или перед выходным файлом. После того, как вы поэкспериментируете с этим, вы можете найти это различие значимым в вашем случае.

Важное примечание: приведенный выше пример приводит к перекодированию видео. Ниже мы обсудим возможность сделать это без транскодирования.

Слияние нескольких сегментов

Существует три основных способа выполнения слияния фильмов, два из которых лучше всего описаны в этой вики-статье ffmpeg, а третий - демультиплексор concat. Если все ваши сегменты идентичны с точки зрения спецификации кодирования /v и формата контейнера, вы, вероятно, найдете самый простой способ - протокол concat: :

# merge the segments
ffmpeg -i "concat:seg1.mp4|seg2.mp4|seg3.mp4" final.mp4

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

Вырезание и слияние без перекодирования

Причина того, что примеры в предыдущих разделах требуют транскодирования, заключается в том, что каждый файл и каждый результирующий сегмент представляют собой отдельный фильм, который был упакован так, чтобы обеспечить все, что вы ожидаете при открытии полного фильма, например продолжительность фильма и другие. метаданные. Но вы же не хотите воспроизводить их как отдельные фильмы, вы хотите, чтобы эти сегменты стали частью большого видеопотока. Таким образом, вместо того, чтобы подавать ffmpeg с коробочными фильмами, вам лучше переупаковать - re-mux - входные файлы в потоковый контейнер в реальном времени, забыв о заголовках, которые вам на самом деле не нужны. В случае H.264 формат потокового мультиплексирования называется MPEG-TS, и вот как вы повторно мультиплексируете свой поток, не транскодируя его:

# re-muxing the whole movie (see a better option in next example)
ffmpeg -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb full-movies-as-ts.ts

Ну, так как вы уже в этом, вы могли бы также использовать эту возможность, чтобы вырезать только нужный вам сегмент:

# skip 30 seconds and re-mux a 60 seconds segment
ffmpeg -ss 30 -t 60 -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb segment.ts

Когда вы объединяете сегменты TS, вы также можете повторно мультиплексировать обратно в контейнер mp4:

# merge the segments and re-mux them as mp4
ffmpeg -i "concat:seg1.ts|seg2.ts|seg3.ts" -c:v copy -c:a copy -movflags empty_moov -flags global_header -bsf:v dump_extra edited-final.mp4

Так что теперь мы сделали все это, не перекодировав фильм, сохранив оригинальное качество. Но, как всегда, есть одна оговорка ...

ПРЕДУПРЕЖДЕНИЕ: вырезание может быть сделано только на границе ключевого кадра. Объяснение: H.264 организует сжатые кадры в пакеты, каждый из которых начинается с полного, но сжатого изображения первого кадра, за которым следуют дельты следующих кадров, тем самым уменьшая объем памяти, требуемый для каждого пакета. Для нашей цели каждый пакет подобен запечатанному почтовому индексу всех кадров за эту длительность - это либо все, либо ничего. Если вы хотите просто часть пакета, то вам нужно разархивировать его и вернуть обратно, другими словами - перекодировать. Таким образом, приведенный выше метод уместен, только если у вас есть ключевой кадр в каждой позиции, где вы хотите вырезать фильм. Например, если у вас есть ключевой кадр каждые 5 секунд, вы можете вырезать его только каждые 5 секунд.

Итак, теперь вопрос заключается в том, можете ли вы принять ограничения на точки обрезки, тем более что вы, вероятно, не знаете, где в вашем фильме есть ключевые кадры. И именно поэтому я предложил выше прочитать в 5.4 Основные параметры об указании -s и -t перед вводом или перед выводом. Если вы укажете перед вводом, то ffmpeg найдет ближайший ключевой кадр для выполнения вашего запроса, который будет «более или менее» там, где вы хотели выполнить вырезку. Если вы не возражаете против точности резки, тогда хорошо, сделайте это.

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

# skip PRECISELY 30 seconds and transcode a 60 seconds TS segment
ffmpeg -i full-movie.mp4 -ss 30 -t 60 -bsf:v h264_mp4toannexb segment.ts

Поскольку результирующие сегменты будут в TS, нет необходимости в другом транскоде при объединении сегментов вместе.

скорость

В вики-статье ffmpeg о слиянии рассказывается о том, как запустить весь процесс через каналы, что устраняет необходимость в промежуточных файлах и ускоряет весь процесс. DO NOT. Это займет у вас больше времени. Причина того, что выполнение всего этого в памяти займет больше времени, заключается не в том, что он будет работать дольше, а в том, что у вас не будет промежуточных результатов, пока вы не поймете, как все это выполнить, и вы обнаружите, что снова запускаете весь процесс и снова. Таким образом, теория труб хороша, но в вашем случае вы должны начать с разработки и совершенствования каждого шага. Вы обнаружите, что для того, чтобы заставить все работать и получить достойный результат, потребуется еще немного доработать и настроить. Как только вы освоите весь процесс и захотите выполнить некоторые сценарии для автоматического массового редактирования, вы можете вернуться к концепции трубопроводов.

Надеюсь, что выше помогает.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .