软件项目技术点(17)——视频转码
AxeSlide软件项目梳理 canvas绘图系列知识点整理
了解本节内容技术点:
安装模块“fluent-ffmpeg” https://github.com/fluent-ffmpeg/node-fluent-ffmpeg
API地址:http://www.ffmpeg.org/
需求背景,我们的软件可以插入视频,并且播放视频。
但是WebKit内核的nw.js跟chrome一样用HTML5的标签<video>去播放视频,支持的格式只有三种 Ogg、MPEG4、WebM,但是我们想支持更多的视频格式,这就需要在插入视频的时候进行格式转换,这样我们支持的视频格式可以有这么多种".webm,.ogv,.ogg,.mp4,.mov,.avi,.wmv,.mpg,.mpeg,.mkv,.rmvb"。
下面我们插入一个mov格式的视频
fileInput弹框选择后获取文件路径,onchange事件定义如下:
我们调用videoInsertProcess函数对插入的视频进行处理,如下图:
videoInsertProcess函数首先检测文件大小是否在100M之内,我们软件只支持100M以内的文件,为避免软件占用过多内存。代码如下图:
判断视频是否需要进行转码的过程如下图:
代码里也没有过多注释,主要是根据我们软件的业务需求写的逻辑,主要就是循环判断streams流,codec_type是否为video;如果是继续判断codec_name是否是我们支持的vp8,vp9,h264编码格式,如果不是的话就需要进行转码
插入的视频如果需要转码的话,会提醒用户是否要进行转码插入,如下图提示框:
点击转码按钮。创建ffmpeg命令, var videoEncoder = new Common.VideoEncoder(filePathStr);//filePathStr插入视频的源路径
调用convertToWebm方法,传入目标路径,成功处理回调函数,失败处理回调函数。
如下过程:
函数convertToWebm的具体代码如下:
1 //视频转换为webm格式 2 convertToWebm(targetPath, onComplete: Function, onError: Function) { 3 var that = this; 4 var bit_rate = Number(targetPath["bitRate"]); 5 var channelsgt2 = targetPath['channelsgt2'] || false; 6 var bit_rate_str; 7 var options = []; 8 //计算bitRate信息,封装options 9 if (isFinite(bit_rate)) { 10 if (bit_rate < 1024) { 11 bit_rate_str = Math.round(bit_rate).toString(); 12 } 13 else if (bit_rate < 1024 * 1024) { 14 bit_rate_str = Math.round(bit_rate / 1024).toString() + 'K'; 15 } 16 else { 17 bit_rate_str = Math.round(bit_rate / (1024 * 1024)).toString() + 'M'; 18 } 19 options.push('-b:v ' + bit_rate_str); 20 } 21 if (channelsgt2 === true) { 22 options.push('-ac 2'); 23 } 24 options.push('-deadline realtime'); 25 26 targetPath = targetPath.valueOf();//还原target 路径 27 28 that.encoder.videoCodec('libvpx') 29 .outputOptions(options) //cpu-used -5 30 .on('start', function (cmd) { 31 index.showProgressBar("0%", SoftWare.transcoding_going, "", function () { 32 that.encoder.kill(); 33 }); 34 }) 35 .on('end', function () { 36 document.getElementById("progress_bar").style.display = "none"; 37 onComplete(false); 38 }) 39 .on('error', function (err) { 40 document.getElementById("progress_bar").style.display = "none"; 41 if (err.message === "ffmpeg was killed with signal SIGKILL") { 42 index.showMask(true); 43 index.showWaitMoment(true); 44 return; 45 } 46 onError(err); 47 }) 48 .on('progress', function (progress) { 49 var percent: number = progress.percent; 50 if (percent) { 51 index.showProgressBar(percent.toFixed(1) + "%", SoftWare.transcoding_going, ""); 52 } 53 }) 54 .save(targetPath); 55 }