JAVE2(Java音頻視頻編碼器)庫是ffmpeg項目上的Java包裝器。 開發人員能夠利用JAVE2將音頻和視頻文件從一種格式轉碼爲另外一種格式。 在示例中,您能夠將AVI文件轉換爲MPEG文件,能夠將DivX視頻流轉換爲(相似YouTube的)Flash FLV文件,能夠將WAV音頻文件轉換爲MP3或Ogg Vorbis文件,能夠分離並 對音頻和視頻軌道進行轉碼,您能夠調整視頻的大小,更改其大小和比例等。
JAVE2支持許多其餘格式,容器和操做。
Jave2 的首頁上介紹:java
JAVE2是一個小的Java庫,它將ffmpeg包裝到java類中。 它是基於Carlo Pelliccia的傑做。 因爲再也不維護該代碼,所以咱們採用了該代碼,並用當前版本替換了ffmpeg可執行文件,並修改了代碼以使其與新的二進制文件一塊兒使用。linux
Jave2 是在Jave的基礎上進行開發的,Jave基於Carlo Pelliccia的 Jave版本,帶有源代碼的原始項目頁面能夠在這裏找到:
www.sauronsoftware.it/projects/ja… 。我點擊或許塵封好久的 Jave 網站,很慶幸打開了,而後看了下介紹個文檔,真的是好久沒更新了。
git
In order to use JAVE in your Java application, you have to add the file jave-1.0.jar in your application CLASSPATH. JAVE runs on a Java Runtime Environment J2SE v.1.4 or later.github
意思也就是要用JAVE的話,須要將_jave-1.0.jar _加入到應該的CLASSPATH下,而後JRE 的版本是J2SE v.1.4+。看了這句描述,你就應該知道這個項目是「古董」級別的項目了。編程
J2SE v.1.4 ,估計不少小夥伴只是聽過,根本沒有用過。windows
文檔中其餘的一些使用說明就不詳細展開了,感興趣的夥伴能夠看下。地址上面已經貼出來。 app
jave2 github :github.com/a-schild/ja… ,看了下 四個月前還在更新
ide
Java8+ : 是否是很熟悉,這個應該是用過了吧,支持的操做系統那也是挺全面的。從「古董」過來的成爲了「寶藏」。
工具
從github描述上,支持Maven/Gradle的方式引入依賴的jar,比 jave1.0的時候須要先從官網download jar,而後 手動在加入應用的 CLASSPATH 仍是高端不少。網站
Jave2包含兩個主要組件:
一、 jave-core依賴關係,包括全部Java代碼,與平臺無關
二、 jave-nativebin- 依賴關係,其中包括每一個平臺的二進制可執行文件
有一個jave-all-deps項目,其中包括核心以及全部Windows和Linux二進制文件。
這裏介紹下Maven的引入方式(使用前看下最新的版本號)
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-all-deps</artifactId>
<version>2.7.3</version>
</dependency>
複製代碼
若是你想在一個或多個平臺上使用,那麼必需要引入 jave-core ,
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-core</artifactId>
<version>2.7.3</version>
</dependency>
複製代碼
而後是平臺的特定jar。
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-nativebin-linux64</artifactId>
<version>2.7.3</version>
</dependency>
複製代碼
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-nativebin-win64</artifactId>
<version>2.7.3</version>
</dependency>
複製代碼
<dependency>
<groupId>ws.schild</groupId>
<artifactId>jave-nativebin-osx64</artifactId>
<version>2.7.3</version>
</dependency>
複製代碼
Gradle方式這裏就不作介紹 ,自行看文檔說明,也比較簡單。
我用的是window 64 ,引入了最新 2.7.3版本 jave-core 、 jave-nativebin-win64
public class ArmToMp3Test {
private static Logger logger = LoggerFactory.getLogger(ArmToMp3Test.class);
public static void main(String[] args) {
try {
File source = new File("D:\\tmp\\Java編程技術樂園.amr");
File target = new File("D:\\tmp\\java編程技術樂園amrToMp3.mp3");
//Audio Attributes
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(128000);
audio.setChannels(2);
audio.setSamplingRate(44100);
//Encoding attributes
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
//Encode
Encoder encoder = new Encoder();
encoder.encode(new MultimediaObject(source), target, attrs);
} catch (Exception ex) {
logger.error("ArmToMp3Test#main 異常", ex);
}
}
}
// 執行完,在 D:\\tmp\Java編程技術樂園amrToMp3.mp3
複製代碼
用到 ws.schild.jave.EncoderProgressListener 接口:編碼進度偵聽器接口。 實現類的實例能夠用來聽的編碼過程。
public interface EncoderProgressListener {
/** * This method is called before the encoding process starts, reporting * information about the source stream that will be decoded and re-encoded. * 這種方法是在編碼過程開始以前被調用,報告關於將被解碼和再編碼的源數據位流的信息. * @param info Informations about the source multimedia stream. */
public void sourceInfo(MultimediaInfo info);
/** * This method is called to notify a progress in the encoding process. * 這種方法被稱爲通知在編碼過程當中的進度。 * @param permil A permil value representing the encoding process progress. */
public void progress(int permil);
/** * This method is called every time the encoder need to send a message * (usually, a warning). * 這種方法被稱爲每次編碼器須要發送一條消息(一般,一個警告)。 * @param message The message sent by the encoder. */
public void message(String message);
}
複製代碼
/** * 自定義實現 {@Link EncoderProgressListener}監聽編碼進度 * @Author: dufy */
public class MyChanageEncoderProgressListener implements EncoderProgressListener {
private static Logger logger = LoggerFactory.getLogger(MyChanageEncoderProgressListener.class);
@Override
public void sourceInfo(MultimediaInfo info) {
long ls = info.getDuration() / 1000;
int hour = (int) (ls / 3600);
int minute = (int) (ls % 3600) / 60;
int second = (int) (ls - hour * 3600 - minute * 60);
String length = hour + "時" + minute + "分" + second + "秒";
logger.info("MyChanageEncoderProgressListener#sourceInfo--->{}",info.toString());
logger.info("MyChanageEncoderProgressListener#length--->{}",length);
}
@Override
public void progress(int permil) {
logger.info("MyChanageEncoderProgressListener#progress--->{}",permil);
}
@Override
public void message(String message) {
logger.info("MyChanageEncoderProgressListener#message--->{}",message);
}
}
複製代碼
public class MovToMp4ListenerTest {
private static Logger logger = LoggerFactory.getLogger(MovToMp4ListenerTest.class);
public static void main(String[] args) {
try {
File source = new File("D:\\tmp\\高清有碼-小電影.mov");
File target = new File("D:\\tmp\\高清無碼-小電影.mp4");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libvorbis");
VideoAttributes video = new VideoAttributes();
video.setCodec("mpeg4");
video.setBitRate(new Integer(160000));
video.setFrameRate(new Integer(30));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp4");
attrs.setAudioAttributes(audio);
attrs.setVideoAttributes(video);
//Encode
Encoder encoder = new Encoder();
encoder.encode(new MultimediaObject(source), target, attrs, new MyChanageEncoderProgressListener());
} catch (Exception ex) {
logger.error("MovToMp4ListenerTest#main 異常", ex);
}
}
}
複製代碼
這裏 有兩個點說明下:
hour + "時" + minute + "分" + second + "秒
注:由於音視頻的編碼格式挺多,不少編解碼協議還沒看。上面例子也是找的文檔配置,若有不對,歡迎指出。
其實jave2還有不少高端的操做,後續有機會在整理出來。
一、有說小夥伴在執行的時候遇到了
Cannot run program "C:\xxx\Local\Temp\jave\ffmpeg-amd64-2.7.3.exe"
ws.schild.jave.EncoderException: java.io.IOException: Cannot run program "C:\Users\acer\AppData\Local\Temp\jave\ffmpeg-amd64-2.7.3.exe": CreateProcess error=2, 系統找不到指定的文件。
at ws.schild.jave.Encoder.encode(Encoder.java:640)
at ws.schild.jave.Encoder.encode(Encoder.java:398)
at ws.schild.jave.Encoder.encode(Encoder.java:363)
at org.learn.jave2.ArmToMp3Test.main(ArmToMp3Test.java:35)
複製代碼
報這個錯這就是沒加 jave-nativebin-win64
這個依賴。
這裏說明下,添加了win-64 jar,執行的時候會默認在本地下載一個 ffmpeg-amd64-2.7.3.exe 。

相關源碼:
Encoder encoder = new Encoder();
public Encoder() {
this.locator = new DefaultFFMPEGLocator();
}
// DefaultFFMPEGLocator
public DefaultFFMPEGLocator() {
// 獲取操做系統類型
String os = System.getProperty("os.name").toLowerCase();
boolean isWindows = os.contains("windows");
boolean isMac = os.contains("mac");
LOG.debug("Os name is <{}> isWindows: {} isMac: {}", new Object[]{os, isWindows, isMac});
File dirFolder = new File(System.getProperty("java.io.tmpdir"), "jave/");
if (!dirFolder.exists()) {
LOG.debug("Creating jave temp folder to place executables in <{}>", dirFolder.getAbsolutePath());
dirFolder.mkdirs();
} else {
LOG.debug("Jave temp folder exists in <{}>", dirFolder.getAbsolutePath());
}
// 獲取文件的後綴
String suffix = isWindows ? ".exe" : (isMac ? "-osx" : "");
String arch = System.getProperty("os.arch");
// 獲取 ffmpeg 文件,
File ffmpegFile = new File(dirFolder, "ffmpeg-" + arch + "-" + "2.7.3" + suffix);
LOG.debug("Executable path: {}", ffmpegFile.getAbsolutePath());
if (ffmpegFile.exists()) {
LOG.debug("Executable exists in <{}>", ffmpegFile.getAbsolutePath());
} else {
LOG.debug("Need to copy executable to <{}>", ffmpegFile.getAbsolutePath());
this.copyFile("ffmpeg-" + arch + suffix, ffmpegFile);
}
if (!isWindows) {
try {
Runtime.getRuntime().exec(new String[]{"/bin/chmod", "755", ffmpegFile.getAbsolutePath()});
} catch (IOException var9) {
LOG.error("Error setting executable via chmod", var9);
}
}
// 知道了文件的路徑
this.path = ffmpegFile.getAbsolutePath();
LOG.debug("ffmpeg executable found: {}", this.path);
}
private void copyFile(String path, File dest) {
// 拷貝文件代碼,具體略
}
複製代碼
Jave 雖然不在維護了,可是 它的「哥哥」 Jave2 出現了,功能仍是很強大的,基本上能知足工做的一些對 音頻視頻 的操做了。
若是看了本文你也想玩一下這個工具,須要本文的演示代碼以及相關文件(想看高清無碼-小電影.mov)的話。能夠關注公衆號,回覆 Jave2 獲取。