了解本節內容技術點:
安裝模塊“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 }
文章列表