Laravel FFMPEG使用中-t时长过滤参数被忽略的解决方案咨询
问题说明
以下FFMPEG命令可正常运行,实现将单张图片循环生成指定时长的视频:
ffmpeg -loop 1 -i flyer.jpg -c:v libx264 -t 15 -pix_fmt yuv420p -vf scale=1080:720 out.mp4
通过Laravel FFMPEG扩展实现相同效果的初始代码如下:
FFMpeg::fromDisk('images') ->open('flyer.jpg') ->export() ->addFilter('-loop', 1) ->addFilter('-c:v', 'libx264') ->addFilter('-t', '15') ->addFilter('-pix_fmt', 'yuv420p') ->addFilter('-vf', 'scale=1080:720') ->save('timelapse.mp4');
运行后其余滤镜参数均正常生效,但用于指定输出时长的-t 15参数未生效,输出视频时长不符合预期。
问题根因
FFMPEG对参数顺序有严格要求:-loop属于输入侧参数,必须放置在对应输入文件的-i参数之前才能正常工作:
- 可正常生效的命令写法(
-loop 1在-i之前):
ffmpeg -loop 1 -i flyer.jpg -c:v libx264 -t 15 -pix_fmt yuv420p -threads 12 -vf [in]scale=1080:720 out.mp4
- 无法正常生效的命令写法(
-loop 1在-i之后):
ffmpeg -i flyer.jpg -loop 1 -c:v libx264 -t 15 -pix_fmt yuv420p -threads 12 -vf [in]scale=1080:720 out.mp4
Laravel FFMPEG中addFilter()方法用于添加输出侧参数,所有通过该方法传入的参数默认会被拼接在-i参数之后,因此用该方法添加-loop会触发参数顺序错误,直接导致-t时长控制失效。
解决方案
不要通过addFilter()添加输入侧的-loop参数,也不要手动传入-t参数,改用扩展内置方法绑定输入参数、设置输出时长即可,可直接运行的代码如下:
FFMpeg::fromDisk('images') ->open(function ($inputMedia) { // 将-loop绑定为输入参数,会自动拼接到对应-i参数之前 $inputMedia->addInputOption('-loop', 1); }, 'flyer.jpg') ->export() ->addFilter('-c:v', 'libx264') ->addFilter('-pix_fmt', 'yuv420p') ->addFilter('-vf', 'scale=1080:720') ->setDuration(15) // 调用内置时长设置方法,等效于-t 15,自动放置在正确参数位 ->save('timelapse.mp4');
补充说明
- 若使用7.0以下版本的Laravel FFMPEG,不支持闭包形式传入输入参数,升级扩展版本后即可使用上述写法
- 视频编码、像素格式、缩放滤镜这类输出侧参数,仍可正常通过
addFilter()添加,不受影响 - 上述代码生成的最终FFMPEG命令与手动验证过的有效命令参数顺序完全一致,可正常输出15秒、分辨率1080*720的视频
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

