如何在Android中壓縮視頻?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
成都創新互聯長期為千余家客戶提供的網站建設服務,團隊從業經驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯網生態環境。為瑪曲企業提供專業的網站設計制作、成都做網站,瑪曲網站改版等技術服務。擁有10年豐富建站經驗和眾多成功案例,為您定制開發。使用方法
基本原理:將android環境下可執行文件ffmpeg存放在本地,代碼執行ffmpeg的壓縮命令。
//將開源庫中asset目錄的ffmpeg可執行文件,拷貝到 app的data/data/files目錄 FFmpeg.getInstance(this).loadBinary(null);
執行ffmpeg的一個命令:比如查看ffmpeg的當前版本:./ffmpeg -version
接著就可以在代碼中,使用ffmpeg的各種命令了:把命令寫入String[],然后調用fFmpeg.execute 即可
獲取視頻文件的信息
String[] command = new String[]{"-i", arg.filePath}; try { fFmpeg.execute(commands, new ExecuteBinaryResponseHandler(){ @Override public void onStart() {} @Override public void onProgress(String message) { Log.e("dml", "onProgress: message is " + message); } @Override public void onFailure(String message) { Log.e("dml", "onFailure: message is " + message); } @Override public void onSuccess(String message) { Log.e("dml", "onSuccess: message is " + message); } @Override public void onFinish() { Log.e("dml", "onFinish: "); } }); } catch (FFmpegCommandAlreadyRunningException e) { e.printStackTrace(); }
壓縮視頻:
String[] commands = new String[]{"-threads","1","-i", arg.filePath, "-c:v", "libx264","-crf","30","-preset", "superfast" ,"-y", "-acodec","libmp3lame",arg.thumbVideoPath}; fFmpeg.execute(commands, new ExecuteBinaryResponseHandler(){});
參數解釋:
-threads: 執行線程數,傳入1 單線程壓縮
-i:input路徑,傳入視頻文件的路徑
-c:v:編碼格式,一般都是指定libx264
-crf: 編碼質量,取值范圍是0-51,默認值為23,數字越小輸出視頻的質量越高。這里的30是我們經過測試得到的經驗值
-preset:轉碼速度,ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow和placebo。ultrafast編碼速度最快,但壓縮率低,生成的文件更大,placebo則正好相反。x264所取的默認值為medium。需要說明的是,preset主要是影響編碼的速度,并不會很大的影響編碼出來的結果的質量。
-acodec:音頻編碼,一般采用libmp3lame
arg.thumbVideoPath:最后傳入的是視頻壓縮后保存的路徑
-y:輸出時覆蓋輸出目錄已存在的同名文件(如果不加此參數,就不會覆蓋)
問題解決
此開源庫用于視頻壓縮在實際開發中存在不少問題,下面一一解決
1.壓縮進度反饋
執行轉碼命令后,onProgress只是不停輸出字符串,而且文本很長 需要正則表達式從中截取轉碼進度反饋:
@Override public void onProgress(String s) { Pattern timePattern = Pattern.compile("(?<=time=)[\\d:.]*"); Scanner sc = new Scanner(s); String match = sc.findWithinHorizon(timePattern, 0); if (match != null) { String[] matchSplit = match.split(":"); if (duration!= 0) { float progress = (Integer.parseInt(matchSplit[0]) * 3600 + Integer.parseInt(matchSplit[1]) * 60 + Float.parseFloat(matchSplit[2])) / duration; int showProgress = (int) (progress * 100); if(showProgress>100){ showProgress = 100; } notify.compressProgress(getTag(),showProgress); } } }
2.低碼率視頻壓縮會變大
實際中發現有些原質量較差的視頻壓縮后,體積反而變大。
處理方法:壓縮前先執行對視頻提取信息的命令,小于1024kb/s的視頻 不壓縮:
@Override public void onProgress(String s) { //Log.d("dml","pre onProgress = " + s); if(s.contains("Stream #0:0")){ String tem = s.substring(0, s.indexOf("kb/s")); String type ; int pos = tem.lastIndexOf(","); if (pos != -1) { type = tem.substring(pos + 1,tem.length()).trim(); try { Integer integer = Integer.parseInt(type); if(integer > 1024){ pressV(fFmpeg);//執行壓縮 }else { //放棄壓縮,直接使用原文件 } }catch (Exception e){ } } } }
并且在壓縮成功后,檢查壓縮后的文件和原文件大小,如果變大了,直接使用原文件。
3.多線程壓縮多個視頻
開源庫中執行ffmpeg的命令是在AsycTask執行的:
ffmpegExecuteAsyncTask = new FFmpegExecuteAsyncTask(command , timeout, ffmpegExecuteResponseHandler); ffmpegExecuteAsyncTask.execute();
execute 方法在api 11之后是串行方法,就是說開源庫已經限制為單線程。
改為:ffmpegExecuteAsyncTask.executeOnExecutor(Executors.newCachedThreadPool()); 可以使用多線程
測試中發現多個視頻同時壓縮,手機會嚴重發熱,強烈建議采用原設計 。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注創新互聯行業資訊頻道,感謝您對創新互聯的支持。
當前名稱:如何在Android中壓縮視頻-創新互聯
新聞來源:http://vcdvsql.cn/article32/ceodsc.html
成都網站建設公司_創新互聯,為您提供微信小程序、品牌網站設計、電子商務、網站排名、網站收錄、網站制作
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯