利用jave2进行音频处理
很多朋友都知道,ffmpeg是一個功能強大的多媒體處理工具,可惜它并不是java語言開發(fā),如果需要在java項目中使用時,得自己寫很多代碼,幸好github上有一個開源項目jave2把ffmpeg做了封裝,很大程度上簡化了開發(fā),使用方法如下:
先添加依賴項
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-all-deps</artifactId>
<version>3.1.1</version>
</dependency>
以下是一些常用示例:
1、獲取音頻文件的編碼信息
MultimediaInfo getMediaInfo() {
String sourceFilePath = "/Users/jimmy/Downloads/bgm.wav";
File file = new File(sourceFilePath);
if (file != null && file.exists()) {
try {
MultimediaObject multimediaObject = new MultimediaObject(file);
MultimediaInfo m = multimediaObject.getInfo();
return m;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
System.out.println(getMediaInfo());輸出如下:
ws.schild.jave.info.MultimediaInfo (format=wav (metadata={encoder=Lavf58.27.103}, duration=101850, video=null, audio=ws.schild.jave.info.AudioInfo (decoder=pcm_s16le ([1][0][0][0] / 0x0001), samplingRate=44100, channels=2, bitRate=1411000))
從上面可以看出,該文件是wav格式,時長為101.850秒,編碼格式為pcm_s16le,采集率為44100,雙聲道,bit率為1411000
2、wav轉(zhuǎn)mp3
boolean convert2Mp3() {
String sourceFilePath = "/Users/jimmy/Downloads/bgm.wav";
String targetFilePath = "/Users/jimmy/Downloads/bgm.mp3";
try {
File source = new File(sourceFilePath);
File target = new File(targetFilePath);
//Audio Attributes
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(64000);
audio.setChannels(2);
audio.setSamplingRate(44100);
//Encoding attributes
EncodingAttributes attrs = new EncodingAttributes();
attrs.setInputFormat("wav");
attrs.setOutputFormat("mp3");
attrs.setAudioAttributes(audio);
//Encode
Encoder encoder = new Encoder();
encoder.encode(new MultimediaObject(source), target, attrs);
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
return true;
}
3、轉(zhuǎn)換編碼格式
static boolean changeCode() {
String sourceFilePath = "/Users/jimmy/Downloads/bgm.wav";
String targetFilePath = "/Users/jimmy/Downloads/bgm_2.wav";
//Audio Attributes
AudioAttributes audio = new AudioAttributes();
audio.setCodec("pcm_u8");
audio.setBitRate(64000);
audio.setChannels(2);
audio.setSamplingRate(8000);
//Encoding attributes
EncodingAttributes attrs = new EncodingAttributes();
attrs.setInputFormat("wav");
attrs.setOutputFormat("wav");
attrs.setAudioAttributes(audio);
//Encode
Encoder encoder = new Encoder();
try {
encoder.encode(new MultimediaObject(new File(sourceFilePath)), new File(targetFilePath), attrs);
//輔助輸出,觀察編碼格式的變化
MultimediaObject srcObj = new MultimediaObject(new File(sourceFilePath));
MultimediaObject targetObj = new MultimediaObject(new File(targetFilePath));
System.out.println(srcObj.getInfo());
System.out.println(targetObj.getInfo());
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
return true;
}
第7行,設(shè)置了新的編碼pcm_u8
4、分離左右聲道
boolean splitChannel() {
String source = "/Users/jimmy/Downloads/bgm.wav";
String left = "/Users/jimmy/Downloads/bgm_left.wav";
String right = "/Users/jimmy/Downloads/bgm_right.wav";
File leftFile = new File(left);
File rightFile = new File(right);
if (leftFile.exists()) {
leftFile.delete();
}
if (rightFile.exists()) {
rightFile.delete();
}
DefaultFFMPEGLocator locator = new DefaultFFMPEGLocator();
ProcessWrapper ffmpeg = locator.createExecutor();
ffmpeg.addArgument("-i");
ffmpeg.addArgument(source);
ffmpeg.addArgument("-map_channel");
ffmpeg.addArgument("0.0.0");
ffmpeg.addArgument(left);
ffmpeg.addArgument("-map_channel");
ffmpeg.addArgument("0.0.1");
ffmpeg.addArgument(right);
BufferedReader br = null;
try {
ffmpeg.execute();
br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()));
String line;
while ((line = br.readLine()) != null) {
//輸出處理過程中的日志(輔助觀察處理過程)
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
try {
//輔助輸出,觀察編碼格式的變化
MultimediaObject srcObj = new MultimediaObject(leftFile);
MultimediaObject targetObj = new MultimediaObject(rightFile);
System.out.println(srcObj.getInfo());
System.out.println(targetObj.getInfo());
} catch (Exception ex) {
ex.printStackTrace();
}
return true;
}
聲道分離后,會生成2個文件,分別對應(yīng)于左右聲道。
5、拼接音頻(比如:把某段音頻重復N次,合成1個新音頻)
boolean mergeAudio() {
// ffmpeg -i bullet.wav -i bullet.wav -i bullet.wav -filter_complex '[0:0] [1:0] concat=n=3:v=0:a=1 [a]' -map [a] bullet_3.wav
//先生成要拼接的音頻清單
int times = 5;
String src = "/Users/jimmy/Downloads/bullet.wav";
String target = "/Users/jimmy/Downloads/bullet_" + times + ".wav";
File targetFile = new File(target);
if (targetFile.exists()) {
targetFile.delete();
}
DefaultFFMPEGLocator locator = new DefaultFFMPEGLocator();
ProcessWrapper ffmpeg = locator.createExecutor();
for (int i = 1; i <= times; i++) {
ffmpeg.addArgument("-i");
ffmpeg.addArgument(src);
}
ffmpeg.addArgument("-filter_complex");
ffmpeg.addArgument("[0:0] [1:0] concat=n=" + times + ":v=0:a=1 [a]");
ffmpeg.addArgument("-map");
ffmpeg.addArgument("[a]");
ffmpeg.addArgument(target);
BufferedReader br = null;
try {
ffmpeg.execute();
br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()));
String line;
while ((line = br.readLine()) != null) {
//輸出處理過程中的日志(輔助觀察處理過程)
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
6、截取音頻中的某一段
void cut() throws EncoderException {
String src = "/Users/jimmy/Downloads/bgm.wav";
String target = "/Users/jimmy/Downloads/bgm_1_3.wav";
File targetFile = new File(target);
if (targetFile.exists()) {
targetFile.delete();
}
File srcFile = new File(src);
MultimediaObject srcMultiObj = new MultimediaObject(srcFile);
MultimediaInfo srcMediaInfo = srcMultiObj.getInfo();
Encoder encoder = new Encoder();
EncodingAttributes encodingAttributes = new EncodingAttributes();
//設(shè)置起始偏移量(秒)
encodingAttributes.setOffset(1.0F);
//設(shè)置切片的音頻長度(秒)
encodingAttributes.setDuration(2.0F);
//設(shè)置音頻屬性
AudioAttributes audio = new AudioAttributes();
audio.setBitRate(srcMediaInfo.getAudio().getBitRate());
audio.setSamplingRate(srcMediaInfo.getAudio().getSamplingRate());
audio.setChannels(srcMediaInfo.getAudio().getChannels());
//如果截取的時候,希望同步調(diào)整編碼,可以設(shè)置不同的編碼
// audio.setCodec("pcm_u8");
audio.setCodec(srcMediaInfo.getAudio().getDecoder().split(" ")[0]);
encodingAttributes.setInputFormat("wav");
encodingAttributes.setAudioAttributes(audio);
//寫文件
encoder.encode(srcMultiObj, new File(target), encodingAttributes);
}
最后說一個可能會存在的問題:默認情況下,jave2在執(zhí)行時,會把ffmpeg可執(zhí)行文件釋放到"java.io.tmpdir"臨時目錄下,但在tomcat等容器下執(zhí)行時,如果啟用tomcat的用戶,與java應(yīng)用的執(zhí)行用戶不同,可能會存在無寫入權(quán)限的問題。遇到這種情況,可以先用代碼把java.io.tmpdir這個系統(tǒng)變量,指到其它有權(quán)限的目錄,執(zhí)行完后,再還原回來
String oldTmpDir = System.getProperty("java.io.tmpdir");
try {
System.setProperty("java.io.tmpdir", "有權(quán)限寫入的新臨時目錄");
// todo (jave2的其它處理)
} finally {
System.setProperty("java.io.tmpdir", oldTmpDir);
}
作者:菩提樹下的楊過
出處:http://yjmyzz.cnblogs.com
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權(quán)利。
總結(jié)
以上是生活随笔為你收集整理的利用jave2进行音频处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL教程(三)—— MySQL的安
- 下一篇: 使用浏览器访问或调试微信公众号(跳过微信