javaCV開發詳解之7:讓音頻轉換更加簡單,實現通用音頻編碼格式轉換、重取樣等音頻參數的轉換功能(以pcm16le編碼的wav轉mp3為例)
- 2019 年 11 月 1 日
- 筆記
版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/eguid_1/article/details/52982108
前言:
之前幾章把javaCV-FFmpeg中的能夠實現的基本功能大致梳理了一遍,本章在之前幾章基礎上實現一個通用的音頻編碼和參數轉換器
實現功能:
①音頻編碼轉換②音頻格式轉換③音頻重取樣④等等。。。跟多功能自行探索
程式碼實現:
package cn.eguid.audioConvert; import org.bytedeco.javacpp.avcodec; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.FFmpegFrameRecorder; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.FrameGrabber; import org.bytedeco.javacv.FrameRecorder; import org.bytedeco.javacv.FrameRecorder.Exception; /** * 音頻參數轉換(包含取樣率、編碼,位數,通道數) * * @author eguid * */ public class AudioConvert { /** * 通用音頻格式參數轉換 * * @param inputFile * -導入音頻文件 * @param outputFile * -導出音頻文件 * @param audioCodec * -音頻編碼 * @param sampleRate * -音頻取樣率 * @param audioBitrate * -音頻比特率 */ public static void convert(String inputFile, String outputFile, int audioCodec, int sampleRate, int audioBitrate, int audioChannels) { Frame audioSamples = null; // 音頻錄製(輸出地址,音頻通道) FFmpegFrameRecorder recorder = null; //抓取器 FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFile); // 開啟抓取器 if (start(grabber)) { recorder = new FFmpegFrameRecorder(outputFile, audioChannels); recorder.setAudioOption("crf", "0"); recorder.setAudioCodec(audioCodec); recorder.setAudioBitrate(audioBitrate); recorder.setAudioChannels(audioChannels); recorder.setSampleRate(sampleRate); recorder.setAudioQuality(0); recorder.setAudioOption("aq", "10"); // 開啟錄製器 if (start(recorder)) { try { // 抓取音頻 while ((audioSamples = grabber.grab()) != null) { recorder.setTimestamp(grabber.getTimestamp()); recorder.record(audioSamples); } } catch (org.bytedeco.javacv.FrameGrabber.Exception e1) { System.err.println("抓取失敗"); } catch (Exception e) { System.err.println("錄製失敗"); } stop(grabber); stop(recorder); } } } public static boolean start(FrameGrabber grabber) { try { grabber.start(); return true; } catch (org.bytedeco.javacv.FrameGrabber.Exception e2) { try { System.err.println("首次打開抓取器失敗,準備重啟抓取器..."); grabber.restart(); return true; } catch (org.bytedeco.javacv.FrameGrabber.Exception e) { try { System.err.println("重啟抓取器失敗,正在關閉抓取器..."); grabber.stop(); } catch (org.bytedeco.javacv.FrameGrabber.Exception e1) { System.err.println("停止抓取器失敗!"); } } } return false; } public static boolean start(FrameRecorder recorder) { try { recorder.start(); return true; } catch (Exception e2) { try { System.err.println("首次打開錄製器失敗!準備重啟錄製器..."); recorder.stop(); recorder.start(); return true; } catch (Exception e) { try { System.err.println("重啟錄製器失敗!正在停止錄製器..."); recorder.stop(); } catch (Exception e1) { System.err.println("關閉錄製器失敗!"); } } } return false; } public static boolean stop(FrameGrabber grabber) { try { grabber.flush(); grabber.stop(); return true; } catch (org.bytedeco.javacv.FrameGrabber.Exception e) { return false; } finally { try { grabber.stop(); } catch (org.bytedeco.javacv.FrameGrabber.Exception e) { System.err.println("關閉抓取器失敗"); } } } public static boolean stop(FrameRecorder recorder) { try { recorder.stop(); recorder.release(); return true; } catch (Exception e) { return false; } finally { try { recorder.stop(); } catch (Exception e) { } } } }
用心你會發現這章跟前面幾章很相似?
測試效果
以wav轉mp3為例
// 測試 public static void main(String[] args) { //pcm參數轉換 // convert("東部資訊.wav", "eguid.wav", avcodec.AV_CODEC_ID_PCM_S16LE, 8000, 16000,1); //pcm轉mp3編碼示例 convert("東部資訊.wav", "eguid.mp3", avcodec.AV_CODEC_ID_MP3, 8000, 16,1); }
相信到這裡從第一章看過來的已經基本掌握了javaCV-FFmpeg的用法了,這章講了通用音頻轉換,那麼下一章是否有通用影片轉換?