Редактирование видео из командной строки в Linux (вырезать, присоединиться и просмотреть)

32

У меня довольно простые потребности в редактировании - мне нужно разрезать несколько видео, возможно вставить несколько PNG между ними и присоединиться к этим видео (не нужны переходы, эффекты и т. Д.). По сути, pitiviделаю то, что хочу - за исключением того, что я использую 640x480 30 кадров в секунду AVI с камеры, и как только я добавляю более пары минут такого материала, он pitiviначинает зависать при предварительном просмотре и, таким образом, становится непригодным для использования.

Итак, я начал искать инструмент командной строки для Linux; Я предполагаю, что только ffmpeg( командная строка - Использование ffmpeg для вырезания видео - Super User ) и mplayer( Sam - Редактирование видеофайла с mencoder под linux ) пока что кандидаты, но я не могу найти примеры использования, которое я имею в виду.

 

По сути, я бы предположил, что есть инструменты кодирования и проигрывателя (такие как ffmpegvs ffplayили mencodervs mplayer) - такие, что, для начала, последовательность редактирования может быть указана непосредственно в командной строке, предпочтительно с разрешением кадра - псевдокод будет выглядеть так:

videnctool -compose --file=vid1.avi --start=00:00:30:12 --end=00:01:45:00 --file=vid2.avi --start=00:05:00:00 --end=00:07:12:25 --file=mypicture.png --duration=00:00:02:00 --file=vid3.avi --start=00:02:00:00 --end=00:02:45:10 --output=editedvid.avi

... или может иметь текстовый файл "playlist", например:

vid1.avi      00:00:30:12 00:01:45:00 
vid2.avi      00:05:00:00 00:07:12:25 
mypicture.png -           00:00:02:00
vid3.avi      00:02:00:00 00:02:45:10 

... так что это может быть вызвано с

videnctool -compose --playlist=playlist.txt --output=editedvid.avi

Идея здесь будет то , что все видео в том же формате - позволяет инструмент , чтобы избежать перекодирования, а просто делать «сырую копию» вместо (как в mencoder«s скопировать кодек:" -oac copy -ovc copy«) - или в отсутствии того, Несжатое аудио / видео будет в порядке (хотя это займет немного места). В случае неподвижного изображения инструмент будет использовать кодировку, установленную видеофайлами.

 

Дело в том, что я до сих пор вижу это mencoderи ffmpegмогу работать с отдельными файлами; например, вырезать один раздел из одного файла или объединить файлы ( mencoderтакже имеется Редактировать списки решений (EDL) , которые можно использовать для резки с точностью до кадра - так что вы можете определить несколько областей вырезания, но он снова приписывается одному файлу ). Это подразумевает, что я должен сначала порезать куски из отдельных файлов (каждый из которых потребует собственный временный файл на диске), а затем объединить их в окончательный видеофайл.

Тогда я бы вообразил, что существует соответствующий инструмент проигрывателя, который может читать тот же формат формата командной строки / файл списка воспроизведения, что и инструмент кодирования - за исключением того, что он не будет генерировать выходной файл, а вместо этого воспроизводит видео; например, в псевдокоде:

vidplaytool --playlist=playlist.txt --start=00:01:14 --end=00:03:13

... и, при наличии достаточного количества памяти, он будет генерировать предварительный просмотр видео с низким разрешением в ОЗУ и воспроизводить его в окне, предлагая при этом некоторое ограниченное взаимодействие (например mplayer, сочетания клавиш для воспроизведения, паузы, перемотки назад, пошагового кадра). ). Конечно, я представляю время начала и окончания для ссылки на весь список воспроизведения и включаю любой файл, который может оказаться в этом регионе в списке воспроизведения.

Таким образом, конечным результатом всего этого будет: операция командной строки; нет временных файлов во время редактирования - и также нет временных файлов (или транскодирования) при рендеринге окончательного вывода ... что я сам думаю было бы неплохо.

Итак, хотя я думаю, что все вышеперечисленное может быть немного натянутым - существует ли что-нибудь, что приближало бы рабочий процесс, описанный выше?

sdaau
источник
1
Я также часто использую mkvmerge, когда мне нужно разделить / объединить видео.
Ви.
Спасибо за это, @Vi. - никогда раньше не слышал mkvmerge, обязательно позабочусь об этом .. Ура!
Сдау

Ответы:

17

Да, есть. Попробуйте использовать приложение под названием «Melt». Смотрите документацию здесь:

https://www.mltframework.org/docs/melt/

Если вы используете дистрибутив Debian:

apt-get install melt
Ielton
источник
на Mac:brew install mlt
kraftydevil
23

Хорошо, так как я не могу найти много информации об meltиспользовании командной строки, вот некоторые примечания .. (и после этого посмотрите этот ответ. Использование подстановки процессов для обмана программ, ожидающих файлы, с конкретными расширениями в качестве аргумента? - Unix & Linux Stack Exchange для скрипта пример через bash)

Для начала - есть пакет Ubuntu / Debian для melt(у меня Ubuntu 11.04 с MLT melt 0.6.2); ссылка, предоставленная @Ielton, предназначена для «Media Lovin 'Toolkit» (MLT), который meltявляется частью (но также openshotи kdenlive). Вот ссылка на текстовые файлы документации из их git: mltframework.org/mlt.git/tree - docs / ; обратите внимание, что в вики есть страница о BuildScripts .

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

 

Во-первых, в командной строке meltвы можете управлять воспроизведением через кадры; например, чтобы «создать» белую заготовку длиной 15 кадров и просмотреть ее с помощью встроенного meltпроигрывателя, используйте

melt -blank 15

Когда вы просматриваете с помощью melt, вы также получите информацию о командной строке stderrдля встроенного проигрывателя:

$ melt -blank 15 
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|1=-10| |2= -5| |3= -2| |4= -1| |5=  0| |6=  1| |7=  2| |8=  5| |9= 10|
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
+---------------------------------------------------------------------+
|               H = back 1 minute,  L = forward 1 minute              |
|                 h = previous frame,  l = next frame                 |
|           g = start of clip, j = next clip, k = previous clip       |
|                0 = restart, q = quit, space = play                  |
+---------------------------------------------------------------------+
Current Position:         15

Как только meltвоспроизведение закончится, оно не выйдет, поэтому вы должны набрать qдля выхода.

Следует отметить, что в России есть так называемые «производители» и «потребители» melt. Если ничего не указано, то «потребителем» по умолчанию является окно SDL (Simple DirectMedia Layer), воспроизводящее видео; поэтому приведенная выше команда такая же как:

melt -blank 15 -consumer sdl

Таким образом, если мы хотим сохранить то melt, что отображается, мы должны изменить потребителя на то, что будет поддерживать формат файла. Чтобы получить список потребителей:

$ melt -query "consumers"
---
consumers:
  - sdl
  - sdl_audio
  - sdl_preview
  - sdl_still
  - gtk2_preview
  - avformat
  - libdv
  - xml
  - decklink
  - null
...

libdvВыход DV потребителя отформатированных данных непосредственно stdout, так , чтобы сохранить видео на .dvфайл , который вы хотите сделать:

melt -blank 15 -consumer libdv > test.dv

Обратите внимание, что из перечисленных потребителей единственным форматом, который я пробовал, также можно открыть в другом приложении libdv(я использовал в vlcкачестве другого приложения); однако, это может не сработать для другого типа транскодирования ( например, если вместо пустого я пытаюсь преобразовать фрагмент из .flvфайла, результирующий файл .dv открывается и воспроизводится vlc, но поврежден ).

 

Теперь для редактирования части; по существу, вы можете указать ряд разделов file-name / in / out непосредственно в командной строке; скажем, у вас есть файл, video.avi- тогда вы могли бы сделать:

melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79

или чуть лучше отформатирован:

melt \ 
video.avi in=30 out=79 \ 
-blank 15 \
video.avi in=30 out=79

Это означает, что video.aviот его кадра 30 до его кадра 79 будут воспроизведены; затем 15-кадровый бланк; и затем video.aviпоследовательность от кадра 30 до кадра 79 снова.

Чтобы использовать изображения (скажем, .png) в композиции для редактирования видео:

melt \
video.avi in=30 out=79 \
test.png in=0 out=15 \
video.avi in=30 out=79 \
-blank 15

Обратите внимание , что для test.png, in=параметр не должен быть 0 - однако, изображение будет отображаться out- inвремя; в этом случае было бы проще просто in=0полностью исключить параметр.

 

Хорошо, что эта последовательность редактирования может быть сохранена - или, как meltона называется, сериализована - в файл; Обратите внимание, что существует два способа такой сериализации: «простой» или XML. Например, чтобы сохранить указанную выше команду как «простой» сериализованный файл, мы можем просто добавить -serialise [filename]переключатель в команду:

$ melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -serialise file.melt 
Project saved as file.melt.

Теперь file.meltсодержит:

video.avi
in=30
out=79
-blank
15
video.avi
in=30
out=79

По-видимому, этот «простой» сериализованный формат файла не содержит символа «комментирования» - если я пытаюсь добавить # commentстроку « », он meltжалуется: « Не удалось загрузить« # comment » » (но, кроме того, кажется, что такой строка игнорируется, и воспроизведение продолжается в любом случае). " .melt" кажется расширением, которое meltраспознает как простой сериализованный файл.

Теперь, чтобы воспроизвести этот сериализованный файл, мы в принципе могли бы просто вызвать melt file.melt- однако, более полная командная строка была бы:

melt melt_file:file.melt -consumer sdl

... что означало бы: использовать melt_file«производитель», чтобы открыть file.melt, и визуализировать его кадры в «потребителе» sdl(окне).

Обратите внимание, что у меня есть опыт, что (скажем) .flvвидео воспроизводятся без проблем в командной строке - однако, вызывают ошибку сегментации, когда они указаны в file.meltсериализованном файле! .dvвидео, созданные meltсами по себе, кажется, работают нормально в file.melt...

 

Тип сериализации XML может быть достигнут с помощью -consumer xml:переключателя ( вместо-serialise ) - так что приведенный выше пример теперь будет:

melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -consumer xml:file.mlt

Чтобы «воспроизвести» недавно сгенерированный file.mltXML-файл, теперь можно сделать напрямую melt file.mlt- или, более полная командная строка будет:

melt xml:file.mlt -consumer sdl

... что означало бы: использовать xml«продюсер» ( обратите внимание, ранее он был потребителем ), чтобы открыть file.mlt, и отобразить его фреймы в «потребителе» sdl(окне).

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

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

<?xml version="1.0" encoding="utf-8"?>
<mlt root="/path/to" title="video.avi">
  <profile description="automatic" width="320" height="240" progressive="1" sample_aspect_num="1" sample_aspect_den="1" display_aspect_num="320" display_aspect_den="240" frame_rate_num="25" frame_rate_den="1" colorspace="601"/>
  <producer id="producer0" in="30" out="79">
    <property name="mlt_type">producer</property>
    <property name="aspect_ratio">1.000000</property>
    <property name="length">125</property>
    <property name="eof">pause</property>
    <property name="resource">video.avi</property>
    <property name="meta.media.nb_streams">2</property>
    <property name="meta.media.0.stream.type">video</property>
    <property name="meta.media.0.stream.frame_rate">25.000000</property>
    <property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
    <property name="meta.media.0.codec.frame_rate">25.000000</property>
    <property name="meta.media.0.codec.pix_fmt">yuv420p</property>
    <property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
    <property name="meta.media.0.codec.colorspace">601</property>
    <property name="meta.media.0.codec.name">mpeg4</property>
    <property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
    <property name="meta.media.0.codec.bit_rate">0</property>
    <property name="meta.media.1.stream.type">audio</property>
    <property name="meta.media.1.codec.sample_fmt">s16</property>
    <property name="meta.media.1.codec.sample_rate">22050</property>
    <property name="meta.media.1.codec.channels">1</property>
    <property name="meta.media.1.codec.name">mp2</property>
    <property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
    <property name="meta.media.1.codec.bit_rate">64000</property>
    <property name="seekable">1</property>
    <property name="meta.media.sample_aspect_num">1</property>
    <property name="meta.media.sample_aspect_den">1</property>
    <property name="meta.attr.title.markup"></property>
    <property name="meta.attr.author.markup"></property>
    <property name="meta.attr.copyright.markup"></property>
    <property name="meta.attr.comment.markup"></property>
    <property name="meta.attr.album.markup"></property>
    <property name="audio_index">1</property>
    <property name="video_index">0</property>
    <property name="mlt_service">avformat</property>
  </producer>
  <producer id="producer1" in="30" out="79">
    <property name="mlt_type">producer</property>
    <property name="aspect_ratio">1.000000</property>
    <property name="length">125</property>
    <property name="eof">pause</property>
    <property name="resource">video.avi</property>
    <property name="meta.media.nb_streams">2</property>
    <property name="meta.media.0.stream.type">video</property>
    <property name="meta.media.0.stream.frame_rate">25.000000</property>
    <property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
    <property name="meta.media.0.codec.frame_rate">25.000000</property>
    <property name="meta.media.0.codec.pix_fmt">yuv420p</property>
    <property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
    <property name="meta.media.0.codec.colorspace">601</property>
    <property name="meta.media.0.codec.name">mpeg4</property>
    <property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
    <property name="meta.media.0.codec.bit_rate">0</property>
    <property name="meta.media.1.stream.type">audio</property>
    <property name="meta.media.1.codec.sample_fmt">s16</property>
    <property name="meta.media.1.codec.sample_rate">22050</property>
    <property name="meta.media.1.codec.channels">1</property>
    <property name="meta.media.1.codec.name">mp2</property>
    <property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
    <property name="meta.media.1.codec.bit_rate">64000</property>
    <property name="seekable">1</property>
    <property name="meta.media.sample_aspect_num">1</property>
    <property name="meta.media.sample_aspect_den">1</property>
    <property name="meta.attr.title.markup"></property>
    <property name="meta.attr.author.markup"></property>
    <property name="meta.attr.copyright.markup"></property>
    <property name="meta.attr.comment.markup"></property>
    <property name="meta.attr.album.markup"></property>
    <property name="audio_index">1</property>
    <property name="video_index">0</property>
    <property name="mlt_service">avformat</property>
  </producer>
  <playlist id="playlist0">
    <entry producer="producer0" in="0" out="49"/>
    <blank length="16"/>
    <entry producer="producer1" in="0" out="49"/>
  </playlist>
  <tractor id="tractor0" title="video.avi" global_feed="1" in="0" out="115">
    <track producer="playlist0"/>
  </tractor>
</mlt>
sdaau
источник
Кроме того, вот пример для вырезов с точностью до
sdaau
7

Решение этой проблемы ffmpeg выглядит примерно так:

mkfifo temp1 temp2 temp3
ffmpeg -i input.wmv -ss 30 -to 60 -c copy output.wmv temp1 2> /dev/null & \
ffmpeg -i input2.wmv -t 60 -c copy temp2 2> /dev/null & \
ffmpeg -i input3.wmv -i image.png -filter_complex "[0:v][1:v] \
overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy temp3 2> /dev/null & \
ffmpeg -f mpegts -i "concat:temp1|temp2|temp3" -c copy output.mp4

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

В этом примере используется время 30-60 первого ввода, затем добавляется первая минута второго ввода, затем вставляется файл изображения, а затем все третье видео.

Код снят с:

Страница сцепления ffmpeg: https://trac.ffmpeg.org/wiki/Concatenate

Страница суперпользователя Использование ffmpeg для разрезания видео

страница суперпользователя https://video.stackexchange.com/questions/12105/add-an-image-in-front-of-video-using-ffmpeg

codeMonkey
источник
Спасибо за это, я также недавно узнал о ffmpeg-concat , который написан на JavaScript (и вам нужно npmустановить его), поэтому я решил упомянуть об этом
sdaau
4

Я тоже искал такой инструмент, и кажется, что расплав - это инструмент для работы, однако документацию практически невозможно понять / пропустить. Вы можете сделать практически любую комбинацию редактирования. У меня были кадры с «экшн-камеры» ... хотя звук был непригодным. Я присоединился к видео (h264), добавил 60-кадровое замирание и заменил звук звуковой дорожкой, используя:

% melt -video-track vid1.avi vid2.avi -mix 60 -mixer luma vid3.avi \
   -mix 60 -mixer luma -audio-track vorbis:track1.ogg vorbis:track2.ogg \
   -consumer avformat:OUT.avi acodec=libmp3lame vcodec=libx264

Вы можете прочитать больше об этом здесь . Основной сайт здесь .

user196805
источник