一个常见的导致ffmpeg滤镜链“Invalid stream specifier”错误的原因
如题,这个错误好像特别容易犯,但好像中文互联网上还没有人记录过。故在此简记,为像我一样初学ffmpeg的朋友填个坑。
目前有一个特别“长”(物理)的视频primary.mp4。我希望将其横向拉长到指定分辨率(6166x1080)后,切出左侧的3840x1080部分和右侧的3840x1080部分,分别输出为left.mp4和right.mp4。遂构造滤镜链:
ffmpeg -i primary.mp4 -filter_complex "[0:v]scale=6166:1080[scaled];[scaled]crop=3840:1080:0:0[left];[scaled]crop=3840:1080:2327:0[right]" -map "[left]" left.mp4 -map "[right]" right.mp4
看一下这个滤镜链可以被整理成如图所示:
而执行报错:
[mov,mp4,m4a,3gp,3g2,mj2 @ 000001485bf9e600] Invalid stream specifier: scaled.
Last message repeated 1 times
Stream specifier 'scaled' in filtergraph description [0:v]scale=6166:1080[scaled];[scaled]crop=3840:1080:0:0[left];[scaled]crop=3840:1080:2327:0[right] matches no streams.
简单来看似乎是流“scaled”没有找到。而其原因相当简单但好像从来没听有人提及过。那就是同一个流(“[scaled]”)不能被重复使用。
当scale滤镜输出流“[scaled]”之后,在后面我们用了这个流两次,分别是切左侧和切右侧视频的crop。而这是不允许的。
也就是说,图上这个位置这样的连接是不允许的:
那么如何解决呢?答案是用split滤镜将“[scaled]”流给拆成两个“[scaled1]”和“[scaled2]”,再将两个流分别喂给两个crop:
ffmpeg -i primary.mp4 -filter_complex "[0:v]scale=6166:1080[scaled];[scaled]split[scaled1][scaled2];[scaled1]crop=3840:1080:0:0[left];[scaled2]crop=3840:1080:2327:0[right]" -map "[left]" left.mp4 -map "[right]" right.mp4
此外,split滤镜具有一个参数“outputs”。设置该参数为整数数字几就可以让它拆分出多少个流来。
就是这样。