软件项目技术点(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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?