由于项目需求,需要将android手机上的录音文件上传到后台,可是在android上的录音都是amr格式的,在mac上无法播放。直接android上转码又不太好实现。于是这个工作交给后端来实现。
JAVE是基于ffmpeg的很强大的转码工具。下载地址 http://www.sauronsoftware.it/projects/jave/download.php
下载了最新的1.0.2版本,加载到工程中。调用方法:
private boolean convertAmr2MP3(File src, File target) {
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
Encoder encoder = new Encoder();
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
try {
encoder.encode(src, target, attrs);
return true;
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InputFormatException e) {
e.printStackTrace();
} catch (EncoderException e) {
e.printStackTrace();
}
return false;
}
it.sauronsoftware.jave.InputFormatException
at it.sauronsoftware.jave.Encoder.parseMultimediaInfo(Encoder.java:659)
at it.sauronsoftware.jave.Encoder.encode(Encoder.java:840)
at it.sauronsoftware.jave.Encoder.encode(Encoder.java:713)
at com.music.read.MusicFileParser.convertAmr2MP3(MusicFileParser.java:256)
at com.music.read.MusicFileParser.loadFile(MusicFileParser.java:75)
at com.music.read.MusicFileParser.access$000(MusicFileParser.java:24)
at com.music.read.MusicFileParser$1.run(MusicFileParser.java:43)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Using an alternative ffmpeg executable
JAVE is not pure Java: it acts as a wrapper around an ffmpeg (http://ffmpeg.mplayerhq.hu/) executable. ffmpeg is an open source and free software project entirely written in C, so its executables cannot be easily ported from a machine to another. You need a pre-compiled version of ffmpeg in order to run JAVE on your target machine. The JAVE distribution includes two pre-compiled executables of ffmpeg: a Windows one and a Linux one, both compiled for i386/32 bit hardware achitectures. This should be enough in most cases. If it is not enough for your specific situation, you can still run JAVE, but you need to obtain a platform specific ffmpeg executable. Check the Internet for it. You can even build it by yourself getting the code (and the documentation to build it) on the official ffmpeg site. Once you have obtained a ffmpeg executable suitable for your needs, you have to hook it in the JAVE library. That's a plain operation. JAVE gives you an abstract class called it.sauronsoftware.jave.FFMPEGLocator. Extend it. All you have to do is to define the following method:
public java.lang.String getFFMPEGExecutablePath()
This method should return a file system based path to your custom ffmpeg executable.
Once your class is ready, suppose you have called it MyFFMPEGExecutableLocator, you have to create an alternate encoder that uses it instead of the default locator:
Encoder encoder = new Encoder(new MyFFMPEGExecutableLocator())
You can use the same procedure also to switch to other versions of ffmpeg, even if you are on a platform covered by the executables bundled in the JAVE distribution.
Anyway be careful and test ever your application: JAVE it's not guaranteed to work properly with custom ffmpeg executables different from the bundled ones.
我下载的是这个MAC版
使用类加载器,获取ffmpeg的真实路经
public class MyFFMPEGExecute extends FFMPEGLocator {
protected String getFFMPEGExecutablePath() {
String path = MyFFMPEGExecute.class.getResource("/res/ffmpeg").getPath();
return path;
}
}
private boolean convertAmr2MP3(File src, File target) {
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
Encoder encoder = new Encoder(new MyFFMPEGExecute());
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
try {
encoder.encode(src, target, attrs);
return true;
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InputFormatException e) {
e.printStackTrace();
} catch (EncoderException e) {
e.printStackTrace();
}
return false;
}
it.sauronsoftware.jave.EncoderException: Stream mapping:
at it.sauronsoftware.jave.Encoder.encode(Encoder.java:863)
at it.sauronsoftware.jave.Encoder.encode(Encoder.java:713)
at com.music.read.MusicFileParser.convertAmr2MP3(MusicFileParser.java:256)
at com.music.read.MusicFileParser.loadFile(MusicFileParser.java:75)
at com.music.read.MusicFileParser.access$000(MusicFileParser.java:24)
at com.music.read.MusicFileParser$1.run(MusicFileParser.java:43)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
看来还是得,后来找到一个更新版本的jave的jar包。JAVE官网最新的版本发布日期是2009年!所以可能是这个原因
加入新的jar包后重新编译运行,仍然报错。但这此报的异常又变了,感觉有希望
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 8 more
commons-logging
commons-logging
1.2
Dec 29 10:44:57 java[2994] : CGAffineTransformInvert: singular matrix.
Dec 29, 2017 10:45:13 AM it.sauronsoftware.jave.Encoder parseMultimediaInfo
WARNING: Output line: ffmpeg version 3.4.1-tessus Copyright (c) 2000-2017 the FFmpeg developers
Dec 29, 2017 10:45:13 AM it.sauronsoftware.jave.Encoder parseMultimediaInfo
WARNING: Output line: built with Apple LLVM version 8.0.0 (clang-800.0.42.1)
Dec 29, 2017 10:45:13 AM it.sauronsoftware.jave.Encoder parseMultimediaInfo
WARNING: Output line: configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --disable-ffplay
Dec 29, 2017 10:45:13 AM it.sauronsoftware.jave.Encoder parseMultimediaInfo
WARNING: Output line: libavutil 55. 78.100 / 55. 78.100
Dec 29, 2017 10:45:13 AM it.sauronsoftware.jave.Encoder parseMultimediaInfo
WARNING: Output line: libavcodec 57.107.100 / 57.107.100
可以正常播放,音质还不错。除了能转amr还可以转其其它的很多格式。
在网上搜来搜去,都是转载别人文章,而且就是简单的几行调用代码。很少有人写相关的总结,所以决定写个入坑过程,给真正需要的朋友。
最后,附上最新的jave的jar文件以及MAC版的ffmpeg下载地址:点击打开链接