Jave2-Java音頻視頻編碼器

Jave2-Java音頻視頻編碼器

Jave2是什麼


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

在這裏插入圖片描述


大體看了下Documentation,以下安裝要求。

Installation and requirements

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 怎麼玩

jave2 github :github.com/a-schild/ja… ,看了下 四個月前還在更新
ide

在這裏插入圖片描述

支持的操做系統+要求

在這裏插入圖片描述


Java8+ : 是否是很熟悉,這個應該是用過了吧,支持的操做系統那也是挺全面的。從「古董」過來的成爲了「寶藏」。
工具

支持 Maven/Gradle

從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。

  • 若是僅在 Linux 64Bit 平臺,則加入下面的依賴配置。
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-linux64</artifactId>
    <version>2.7.3</version>
</dependency>
複製代碼
  • 若是僅在 Windows 64Bit 平臺,則加入下面的依賴配置。
<dependency>
    <groupId>ws.schild</groupId>
    <artifactId>jave-nativebin-win64</artifactId>
    <version>2.7.3</version>
</dependency>
複製代碼
  • 若是僅在 MACOS 64Bit 平臺,則加入下面的依賴配置。
<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

將arm文件轉爲mp3文件

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);

}
複製代碼
  • MyChanageEncoderProgressListener
/** * 自定義實現 {@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);
	}
}
複製代碼
  • MovToMp4ListenerTest
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 。
![image.png](imgconvert.csdnimg.cn/aHR0cHM6Ly9…[object Object]&name=image.png&originHeight=168&originWidth=520&size=10220&status=done&style=none&width=260)
相關源碼:

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) {
	// 拷貝文件代碼,具體略
}
複製代碼

Jave2 總結


Jave 雖然不在維護了,可是 它的「哥哥」 Jave2 出現了,功能仍是很強大的,基本上能知足工做的一些對 音頻視頻 的操做了。
若是看了本文你也想玩一下這個工具,須要本文的演示代碼以及相關文件(想看高清無碼-小電影.mov)的話。能夠關注公衆號,回覆 Jave2 獲取。

在這裏插入圖片描述
若有其餘問題,也歡迎留言,一塊兒探討交流。


image.png | center| 747x519
相關文章
相關標籤/搜索