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的用法了,這章講了通用音頻轉換,那麼下一章是否有通用影片轉換?