优秀的编程知识分享平台

网站首页 > 技术文章 正文

windows下通过nodejs将音频和图片进行批量合并

nanyue 2024-08-06 18:18:02 技术文章 6 ℃

背景

客户有一批音频需要处理成视频,最好是带有图片,于是就有了下文。

原始目录结构

-- mp3
----01
------01.mp3
------01.jpg
----02
------02.mp3
------02.jpg

将目录全部处理成为同名,实现只是一个很简单的nodejs调用批处理操作,只是不用手动了。

ffmpeg 原始命令

ffmpeg -r 15 -f image2 -loop 1 -i d:/zzs/pp/2/index.jpg -i d:/zzs/pp/2/index.mp3 -s 720x480 -pix_fmt yuvj420p -t 567 -vcodec libx264 -y d:/zzs/pp/2/index.mp4

-loop 1 每帧循环
-s 分辨率
-t 输出视频时长

以上命令应该是能处理大部分的音频、图片吧 ,没有兼容测试,不过肯定会有其他问题,再进行微调就行。

代码

//将mp3 转化为mp4 文件

var ffmpeg = "d:/soft/ffmpeg/bin/";//ffmpeg path
var fs = require('fs');
var async = require('async');
var path = require('path');

//将目标下的文件夹获得,然后把里面的mp3 和 mp4 整合

function TOMP4( opts ){

    this.opts = opts;
    var arr = this.getFolder();
    this.start(arr);

}

//获得文件夹
TOMP4.prototype.getFolder  = function(){
    var thiz = this,opts = thiz.opts,target = opts.target;
    var arr = fs.readdirSync(target);
    return arr;
}
//获得mp3的时长,用于输出
TOMP4.prototype.getDuration = function( path,cb ){
    var exec = require('child_process').exec;
    exec(ffmpeg+'ffmpeg -i '+path,function(error,stdout,stderr){
        var std = error.toString();
        var bb = std.match(/Duration: ([0-9:.]*),/);
        var time = bb[1];
        console.log(time);
        var timeArr = time.split(':');
        var seconds = 0;
        timeArr.forEach(function( a, index ){
            a = Math.round(a);
            seconds += a * (index == 0 ? 3600 : (index == 1 ? 60 : 1));
        });
        cb(seconds);
    });
}
//调用命令转码
TOMP4.prototype.tomp4 = function(picpath,mp3path,topath,duration,cb){
    var exec = require('child_process').exec;
    console.log(mp3path+': 正在转化中,请等待....');
    exec(ffmpeg+'ffmpeg -r 15 -f image2 -loop 1 -i '+picpath+' -i '+mp3path+' -s 720x480 -pix_fmt yuvj420p -t '+duration+' -vcodec libx264 -y '+topath,function(err,stdout,stderr){
        console.log(mp3path+' 转化完成');
        cb(null,null);
    });
}
//启动入口
TOMP4.prototype.start = function( arr ){
    var thiz = this,opts = thiz.opts,target = opts.target,mp3 = opts.mp3,pic = opts.pic;
    async.mapLimit(arr,1,function(item,cb){
        thiz.transform(item,cb);
    },function(){
        console.log('全部转化完毕')
    });
}
//转化-函数
TOMP4.prototype.transform = function( item , cb ){
    var thiz = this,opts = thiz.opts,target = opts.target,mp3 = opts.mp3,pic = opts.pic,to = opts.to;
    var mp3Path = path.join(target,item,mp3);
    var picPath = path.join(target,item,pic);
    var toPath = path.join(target,item,to);
    thiz.getDuration(mp3Path,function(duration){
        thiz.tomp4(picPath,mp3Path,toPath,duration,cb);
    });
}

//调用
var aa = new TOMP4(
    {
        target : 'd:/zzs/pp/',
        mp3 : 'index.mp3',
        pic : 'index.jpg',
        to : 'index.mp4'
    }
);

代码逻辑

  • 确定ffmpeg的调用路径、mp3的路径(只处理两级)、确定mp3/pic/to的名字;
  • 获得MP3所在路径下的一级文件夹,存入数组(一个文件夹对应一个音频)
  • 对数组进行循环,获得对应的路径,然后获得音频的时长,然后进行处理

截图



说明

代码比较粗糙,因为是临时性的工作,没有做很多的处理,只是勉强能用。

Tags:

最近发表
标签列表