Chi sta facendo il lavoro: ffmpeg o la shell?


8

Prima parte della mia domanda:

Ho letto sulla documentazione di ffmpeg ( section 3.2 How do I encode single pictures into movies?) quanto segue:

Per codificare singole immagini in filmati, eseguire il comando:

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

Si noti che `% d 'è sostituito dal numero dell'immagine: img% 03d.jpg indica la sequenza img001.jpg, img002.jpg, ecc ...

La mia domanda è: chi sta facendo la traduzione tra img%03d.jpge img001.jpg, img002.jpg, etc? È la shell o ffmpeg?

Seconda parte:

Vorrei chiedere a ffmpeg di codificare una sequenza di immagini in un video. Tuttavia, le mie sequenze spesso iniziano con un indice diverso da 1 (ad esempio, possiamo chiamarlo start_index) e terminano con un indice che possiamo chiamare end_index. Inoltre, la sequenza utilizza incrementi di valore increment, ad esempio:

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

dove start_indexaveva 25 anni, end_index100 e increment5.

Vorrei alimentare una sequenza di immagini come sopra in ffmpeg senza dover prima rinominare la sequenza. La documentazione spiega come farlo con collegamenti simbolici, ma mi chiedevo se c'è un modo per evitarli del tutto, magari usando il globbing avanzato su zsh.

Risposte:


8

Parte 1: % non è un carattere speciale, quindi l' img%d.jpgargomento viene passato così com'è a ffmpeg"fare il lavoro" stesso.

Parte 2: guardando la ffmpegdocumentazione, non penso che ci sia un altro modo per fornire i file di input, quindi potresti dover usare i link simbolici o attendere la "correzione":

Se il modello contiene "% d" o "% 0Nd", il primo nome file dell'elenco file specificato dal modello deve contenere un numero inclusivamente contenuto tra 0 e 4, tutti i seguenti numeri devono essere sequenziali. Si spera che questa limitazione possa essere corretta.


5

Può essere fatto usando solo tubi, ad es. senza rinominare e senza collegamenti simbolici.

Ecco una sceneggiatura che ho messo insieme, commenti e tutto il resto.
Ho impostato per giocare a 1 fotogramma al secondo.
L'elaborazione delle immagini utilizza il pacchettonetpbm

per esempio: 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
}

Grazie @fered, questo è molto utile. La tua sceneggiatura fa anche più di quello che volevo, il che è fantastico. Ora sto cercando di adattare la sceneggiatura alle mie esigenze. Se sostituisco il ciclo while con un semplice ciclo, ciò non precede né aggiunge il colore di sfondo: while IFS= read -d $'\0' -r file ;do pnmcomp -align=center -valign=middle <(anytopnm "$file" 2>/devnull) donelo script smette di funzionare (cioè ottengo pipe: could not find codec parameters). Sai perché? Devo necessariamente pnmscaleo ppmmakenutrirmi ffmpegdi pnmimmagini?
Amelio Vazquez-Reina,

1
@intrpc. L'inquadratura di foto di dimensioni diverse era solo la mia inclinazione personale sulla questione. Ho voluto farlo da quando ho perso la possibilità di usare avisynth(un potente ambiente di scripting video - avisynth è solo Windows :( Il motivo principale per cui ho usato un netpbmformato è che continuavo a vedere post su problemi che alimentavano jpegs nella pipe, quindi ho appena scelto il percorso di minor resistenza. La codifica video sarà il passo che causa la perdita di qualità, ma aumentare le dimensioni del frame aiuta ... Suppongo che tu abbia i tuoi motivi specifici per utilizzare un video, ma una semplice presentazione potrebbe funzionare per te.
Peter

3

Solo per la prima parte: è ffmpeg a fare il lavoro. La shell non comprende la %dstringa come un modello speciale nei nomi dei file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.