Кто делает работу: ffmpeg или оболочка?

8

Первая часть моего вопроса:

Я прочитал в документации ffmpeg ( section 3.2 How do I encode single pictures into movies?) следующее:

Чтобы закодировать отдельные картинки в фильмы, выполните команду:

  ffmpeg -f image2 -i img%d.jpg movie.mpg    

Обратите внимание, что `% d 'заменяется номером изображения: img% 03d.jpg означает последовательность img001.jpg, img002.jpg и т. Д.

Мой вопрос: кто делает перевод между img%03d.jpgи img001.jpg, img002.jpg, etc? Это оболочка или ffmpeg?

Вторая часть:

Я хотел бы попросить ffmpeg кодировать последовательность изображений в видео. Однако мои последовательности часто начинаются с индекса, отличного от 1 (например, мы можем вызвать его start_index), и заканчиваются индексом, который мы можем вызвать end_index. Кроме того, последовательность использует приращения значения increment, например:

img_0025.png, img_0030.png, img_0035.png, ... img_0100.png

где start_indexбыло 25, end_indexбыло 100, и incrementбыло 5.

Я хотел бы передать последовательность изображений, как указано выше, в ffmpeg без необходимости переименовывать последовательность в первую очередь. Документация объясняет, как сделать это с символическими ссылками, но мне было интересно, есть ли способ вообще их избежать, возможно, с помощью расширенного перемещения по zsh.

Амелио Васкес-Рейна
источник

Ответы:

8

Часть 1: % не является специальным символом, поэтому img%d.jpgпередается аргумент, ffmpegкоторый «выполняет работу» сам.

Часть 2: Глядя на ffmpegдокументацию, я не думаю, что есть другой способ предоставить входные файлы, поэтому вам, возможно, придется использовать символические ссылки или подождать «исправления»:

Если шаблон содержит «% d» или «% 0Nd», первое имя файла списка файлов, указанного шаблоном, должно содержать число, включающее от 0 до 4, все последующие числа должны быть последовательными. Это ограничение может быть исправлено.

Стефан Хименес
источник
5

Это можно сделать только с помощью труб, т.е. без переименования и без символических ссылок.

Вот сценарий, который я собрал, комментарии и все.
Я настроил его на воспроизведение со скоростью 1 кадр в секунду.
Обработка изображений использует пакетnetpbm

например: images-to-vid '$HOME/images" '\./img_[0-9]{4}[^/0-9]*' 1024 768

# Make a video from images whose sizes and aspect-ratios may vary.
# 
# Each image is resized to fit maximized within the video frame.  
# The images are positioned centrally and padded (when required) 
#     
# Images are sourced using 'find'.  
# They are selected according to a regular expression.   
# Symbolic links are ignored.  
#
# Output from 'find' is sorted by path, ie. not by name alone,
#  but with a -maxlevel 1, this is typically the same...
#  You will need to customize the sort if this is not suitable.       
#
# Note about 'find':  
#    This script uses 'find -regex' instead of 'find -name'. 
#    The pattern must match the whole returned path, 
#       from ^ to $ inclusive  
#    The -regextype option is: posix-extended 
#
srceD="${1}"        # Source Directory
srceR="${2}"        # Source imaage extended Regex pattern
targW="${3:-800}"   # Target pixel Width
targH="${4:-600}"   # Target pixel Height
targB="${5:-black}" # Target Background colour (X11 colours)
targM="${6:-4}"     # Target screen geometry Modulo (as required by Target codec)
TARGw=$((targW-(targW%targM))); ((TARGw==targW)) || { echo "Target Width  must be divisible by $targM. Rounding down to $TARGw" 1>&2 ; targW=$TARGw; }
TARGh=$((targH-(targH%targM))); ((TARGh==targH)) || { echo "Target Height must be divisible by $targM. Rounding down to $TARGh" 1>&2 ; targH=$TARGh; }
# TODO: test for W/H == 0

cd "$srceD" || exit 2
find . -maxdepth 1 \
    \( -type f \) -and -not \
    \( -type l \) \
       -regextype posix-extended \
       -regex "$srceR" \
       -print0 | 
  sort -z | 
{ 
  while IFS= read -d $'\0' -r file ;do
      # make Composite image on coloured Background
      pnmcomp -align=center -valign=middle \
              <(anytopnm "$file" 2>/dev/null |
                pnmscale -xysize $targW $targH) \
              <(ppmmake "$targB" $targW $targH) 
  done |
  ffmpeg -r 1 \
         -f image2pipe \
         -vcodec ppm \
         -i - \
         -y -s ${targW}x${targH} \
         -vcodec mjpeg \
          images.avi
}
Peter.O
источник
Спасибо @fered, это очень полезно. Ваш сценарий делает даже больше, чем я хотел, и это здорово. Сейчас я пытаюсь адаптировать сценарий к моим потребностям. Если я заменю цикл while на простой цикл, который не прескалирует и не добавляет цвет фона: while IFS= read -d $'\0' -r file ;do pnmcomp -align=center -valign=middle <(anytopnm "$file" 2>/devnull) doneскрипт перестает работать (т.е. я получаю pipe: could not find codec parameters). Ты знаешь почему? Должен ли я обязательно pnmscaleили ppmmakeкормить ffmpegс pnmизображениями?
Амелио Васкес-Рейна
1
@intrpc. Обрамление фотографий разного размера было моей личной склонностью к этому вопросу. Я хотел сделать это с тех пор, как утратил возможность использовать avisynth(мощная среда для создания сценариев видео - avisynth предназначена только для Windows :( Основная причина, по которой я использовал netpbmформат, заключается в том, что я продолжал видеть сообщения о проблемах подачи jpegs в канал, поэтому я просто выбрал путь наименьшего сопротивления. Кодирование видео будет шагом, который вызывает потерю качества, но увеличение размера кадра помогает ... Я полагаю, у вас есть конкретные причины для использования видео, но простое слайд-шоу может работать на вас.
Питер.
3

Только для первой части: это ffmpeg делает работу. Оболочка не понимает %dстроку как специальный шаблон в именах файлов.

Кусалананда
источник