谁在做这个工作:ffmpeg还是shell?


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?是shell还是ffmpeg?

第二部分:

我想请ffmpeg将一系列图像编码为视频。但是,我的序列通常以不同于1的索引开头(例如,我们可以称之为start_index),并以可以调用的索引结尾end_index。此外,该序列使用value的增量increment,例如:

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

其中start_index是25,end_index100,和increment为5。

我想将类似上述的图像序列输入ffmpeg,而不必先重命名该序列。该文档解释了如何使用符号链接来执行此操作,但是我想知道是否有一种方法可以完全避免使用它们,也许在zsh上使用高级glob。

Answers:


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
}

感谢@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)。你知道为什么吗?我是否一定需要pnmscaleppmmake饲料ffmpegpnm的图像?
阿梅利奥·瓦兹克斯·雷纳

1
@intrpc。不同大小图片的取景只是我个人对这个问题的看法。自从失去使用能力以来,我一直想这么做avisynth(一个强大的视频脚本环境-avisynth仅适用于Windows :(我使用一种netpbm格式的主要原因是,我一直看到有关将jpeg馈送到管道的问题的帖子,因此,我只是选择了阻力最小的路径。视频编码将是导致质量下降的步骤,但是增大帧大小会有所帮助...我想您有使用视频的特定原因,但是需要简单的幻灯片放映可能会为您工作
Peter.O 2011年

3

仅对于第一部分:这是ffmpeg的工作。Shell无法将%d字符串理解为文件名中的特殊模式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.