使用FFmpeg来批量生成单图+单音频的一图流视频

需求:因为时不时会在B站上分享一些游戏BGM合集,拿到多个音频文件之后要先选一张好看的图片,然后逐个音频地与这张图片合成一个静态的视频,这个过程用视频编辑软件来操作的话非常地重复、费事,故考虑使用FFmpeg来转换合成并实现批量操作。

方案一

ffmpeg -i BGM01.mp3 -i cover.png -b:v 2400k -b:a 192k out.mp4

-i 参数添加输入的音频和图片, -b:v 和 -b:a 分别用于设置视频和音频的比特率。

这样就把音频和图片合成在一起了。视频在本地播放的时候是没有问题的,声音正常,图片会连续显示,但是仔细看看播放信息可发现一些东西:帧率和位率是0,时长只有40ms。

上传的时候也会提示“转码失败” (因为时长太短):

方案二

ffmpeg -loop 1 -y -i cover.png -i BGM01.MP3 -shortest -r 24 -b:a 2400k -b:a 192k out.mp4

我们要做的是让图片不止是有一帧的时长,而是延伸到整个音频的长度,于是这里使用 -loop 来循环播放某个输入的元素,后面跟的1代表使用第一个输入进行循环,同时需要加 -shortest 参数来限制循环的次数,指定视频的时长以输入的中最短的时长为准(也就是音频的长度),否则会无限循环。-r 24则指定帧率。

OK,这回帧率显示正常了,这样生成的视频就可以上传了,可以根据实际需要调整一下码率。

最后就是写一个批量处理的脚本了,可以用任意脚本语言来写,这里用PHP。

注:-hwaccel qsv 是硬件加速选项,可以去掉,具体加速选项参考这里 HWAccelIntro – FFmpeg

<?php
	// 请根据操作系统选择一行执行,删除另外一行
	system("dir /b *.mp3 > list.txt");		   // windows
	system("ls *.mp3 > list.txt");           // linux
		
    $list = file_get_contents("list.txt");
    $files = explode("\n", $list);
    unset($files[count($files) - 1]);       // 清除末行空行
    
    foreach($files as $file) {
        $filename = substr($file, 0, strlen($file) - 4);    //去除文件格式.mp3后缀
        system("ffmpeg -loop 1 -y -hwaccel auto -i cover.png -i \"{$file}\" -shortest -r 24 -b:a 192k \"{$filename}.mp4\"");
    }

CMD

forfiles /M *.mp3 /C "ffmpeg -loop 1 -y -hwaccel auto -i cover2.png -i \"@FILE\" -shortest -r 24 -b:a 192k \"@FNAME.mp4\""

Shell 

#!/bin/bash
ls *.mp3 | while read file 
do
	filename=`echo "$file" | sed s/\.mp3//i`
	ffmpeg -loop 1 -y -hwaccel auto -i cover2.png -i "${file}" -shortest -r 24 -b:a 192k "${filename}.mp4"
done

参考

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值