Wer macht den Job: ffmpeg oder die Shell?

8

Erster Teil meiner Frage:

Ich habe in der ffmpeg-Dokumentation ( section 3.2 How do I encode single pictures into movies?) Folgendes gelesen :

Führen Sie den folgenden Befehl aus, um einzelne Bilder in Filme zu codieren:

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

Beachten Sie, dass "% d" durch die Bildnummer ersetzt wird: img% 03d.jpg bedeutet die Sequenz img001.jpg, img002.jpg usw.

Meine Frage ist: Wer macht die Übersetzung zwischen img%03d.jpgund img001.jpg, img002.jpg, etc? Ist es die Shell oder ffmpeg?

Zweiter Teil:

Ich möchte ffmpeg bitten, eine Folge von Bildern in ein Video zu kodieren. Meine Sequenzen beginnen jedoch häufig mit einem anderen Index als 1 (z. B. können wir ihn aufrufen start_index) und enden mit einem Index, den wir aufrufen können end_index. Darüber hinaus verwendet die Sequenz Wertinkremente increment, z.

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

wo start_indexwar 25, end_indexwar 100 und incrementwar 5.

Ich möchte ffmpeg eine Bildsequenz wie oben zuführen, ohne die Sequenz zuerst umbenennen zu müssen. In der Dokumentation wird erklärt, wie dies mit symbolischen Links gemacht wird, aber ich habe mich gefragt, ob es eine Möglichkeit gibt, sie insgesamt zu vermeiden, möglicherweise mithilfe von Advanced Globbing auf zsh.

Amelio Vazquez-Reina
quelle

Antworten:

8

Teil 1: % ist kein Sonderzeichen, daher wird das img%d.jpgArgument so übergeben, wie es ist ffmpeg.

Teil 2: In Bezug auf die ffmpegDokumentation gibt es meines Erachtens keine andere Möglichkeit, Eingabedateien bereitzustellen. Daher müssen Sie möglicherweise Symlinks verwenden oder auf das „Update“ warten:

Wenn das Muster "% d" oder "% 0Nd" enthält, muss der erste Dateiname der durch das Muster angegebenen Dateiliste eine Zahl enthalten, die einschließlich zwischen 0 und 4 liegt. Alle folgenden Zahlen müssen fortlaufend sein. Diese Einschränkung kann hoffentlich behoben werden.

Stéphane Gimenez
quelle
5

Dies kann nur mit Rohren erfolgen, d. H. ohne Umbenennung und ohne Symlinks.

Hier ist ein Skript, das ich zusammengestellt habe, Kommentare und alles.
Ich habe es so eingestellt, dass es mit 1 Bild pro Sekunde abgespielt wird.
Die Bildverarbeitung verwendet Paketnetpbm

z.B: 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
quelle
Danke @fered, das ist sehr hilfreich. Ihr Skript macht noch mehr als ich wollte, was großartig ist. Ich versuche jetzt, das Skript an meine Bedürfnisse anzupassen. Wenn ich die while-Schleife durch eine einfache Schleife ersetze, die weder vorskaliert noch Hintergrundfarben hinzufügt:, while IFS= read -d $'\0' -r file ;do pnmcomp -align=center -valign=middle <(anytopnm "$file" 2>/devnull) donefunktioniert das Skript nicht mehr (dh ich bekomme pipe: could not find codec parameters). Wissen Sie, warum? Muss pnmscaleoder muss ich unbedingt mit Bildern ppmmakefüttern ? ffmpegpnm
Amelio Vazquez-Reina
1
@intrpc. Das Einrahmen von Bildern unterschiedlicher Größe war nur meine persönliche Einstellung zu diesem Thema. Ich wollte das schon immer tun, seit ich die Fähigkeit zur Verwendung verloren habe avisynth(eine leistungsstarke Video-Scripting-Umgebung - avisynth ist nur Windows :( Der Hauptgrund, warum ich ein netpbmFormat verwendet habe, ist, dass ich immer wieder Beiträge über Probleme beim Zuführen von JPEGs in die Pipe sah. Deshalb habe ich nur den Weg des geringsten Widerstands gewählt. Die Videokodierung ist der Schritt, der zu Qualitätsverlusten führt, aber das Erhöhen der Bildgröße hilft ... Ich nehme an, Sie haben Ihre spezifischen Gründe für die Verwendung eines Videos, aber eine einfache Diashow kann für Sie arbeiten.
Peter.O
3

Nur für den ersten Teil: Es ist ffmpeg, das den Job macht. Die Shell versteht die %dZeichenfolge nicht als spezielles Muster in Dateinamen.

Kusalananda
quelle