Java 實現壓縮圖片,影片,音訊案例
在 Java 中,要實現影片壓縮通常需要使用外部的庫或工具,因為 Java 標準庫本身並不提供直接的影片處理功能。以下是一些常用的方法和工具來壓縮影片:
FFmpeg:
FFmpeg 是一個開源跨平臺的多媒體處理工具,可以用來對音訊、影片等多媒體資料進行編解碼、轉換和流處理。你可以透過 Java 呼叫 FFmpeg 的命令列來實現影片壓縮。
Xuggler:
Xuggler 是一個 Java 語言的多媒體處理庫,基於 FFmpeg 和 X264 構建,提供了 Java API 來進行影片和音訊的處理。你可以使用 Xuggler 來實現影片的壓縮和轉換。
JCodec:
JCodec 是一個專門用於影片編解碼的 Java 庫,支援常見的影片編解碼格式,包括 H.264、MPEG-4 等。你可以使用 JCodec 來實現影片的壓縮和編解碼操作。
接下來我們使用FFmpeg實現音訊及影片的壓縮
匯入Maven依賴
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
<version>0.0.20131108.vaadin1</version>
<scope>compile</scope>
</dependency>
引數說明
1. ffmpegPath:FFmpeg可執行檔案的路徑。
2. "-i", inputFile.getAbsolutePath():指定輸入檔案的路徑。
3. "-c:v", "libx264":指定影片編解碼器為libx264。
4. "-crf", "28":設定影片的質量,數值越小,影片質量越高,推薦範圍是18-28。
5. "-preset", "fast":設定編碼速度和質量的平衡,"fast"為快速編碼。
6. "-c:a", "aac":指定音訊編解碼器為AAC。
7. "-b:a", "64k":設定音訊位元率為64kbps。
8. "-movflags", "+faststart":對生成的MP4檔案進行最佳化,使其能夠逐步播放。
9. outputFile.getAbsolutePath() + ".mp4":指定輸出檔案的路徑和檔名,同時指定了輸出檔案的格式為MP4。
壓縮影片
//壓縮影片
public static void compressVideo(File inputFile, File outputFile) {
Long startTime = System.currentTimeMillis();
try {
String ffmpegPath = "D:\\develop\\ffmpeg-master-latest-win64-gpl\\bin\\ffmpeg.exe";
// FFmpeg可執行檔案路徑
// 構建FFmpeg命令
String[] command = {
ffmpegPath,
"-i", inputFile.getAbsolutePath(),
"-c:v", "libx264",
"-crf", "28",
"-preset", "fast",
"-c:a", "aac",
"-b:a", "64k",
"-movflags", "+faststart",
outputFile.getAbsolutePath() + ".mp4"
};
// 建立程序生成器
ProcessBuilder processBuilder = new ProcessBuilder(command);
// 重定向程序的輸入、輸出和錯誤流
processBuilder.inheritIO();
// 啟動程序
Process process = processBuilder.start();
// 等待程序完成
process.waitFor();
Long endTime = System.currentTimeMillis();
System.out.println("影片壓縮完成!用時: " + (endTime - startTime));
} catch (Exception e) {
e.printStackTrace();
}
}
壓縮音訊
//壓縮音訊
public static byte[] compressAudio(InputStream inputStream) {
Long startTime = System.currentTimeMillis();
try {
// FFmpeg可執行檔案路徑
String[] command = {
"ffmpeg",
"-i", "pipe:0",
"-b:a", "64k",
"-f", "mp3",
"pipe:1"
};
ProcessBuilder processBuilder = new ProcessBuilder(command);
// 重定向程序的輸入、輸出和錯誤流
processBuilder.redirectInput(ProcessBuilder.Redirect.PIPE);
processBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE);
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
// 啟動程序
Process process = processBuilder.start();
// 將輸入流複製到程序的輸入流中
Thread copyThread = new Thread(() -> {
try {
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) > 0) {
process.getOutputStream().write(buffer, 0, len);
}
process.getOutputStream().close();
} catch (Exception e) {
e.printStackTrace();
}
});
copyThread.start();
// 將程序的輸出流快取到位元組陣列輸出流中
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = process.getInputStream().read(buffer)) > 0) {
byteArrayOutputStream.write(buffer, 0, len);
}
// 等待輸入流複製執行緒完成
copyThread.join();
// 等待程序完成
process.waitFor();
Long endTime = System.currentTimeMillis();
System.out.println("音訊壓縮完成!用時: " + (endTime - startTime));
// 返回壓縮後的音訊檔案資料
return byteArrayOutputStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
實現壓縮圖片
//壓縮圖片
public static InputStream compressImage(InputStream inputStream, String outputFormat) {
BufferedImage image = null;
try {
image = ImageIO.read(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
int newWidth = (int) (image.getWidth() * compressionRatio);
int newHeight = (int) (image.getHeight() * compressionRatio);
BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
compressedImage.createGraphics().drawImage(image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
ImageIO.write(compressedImage, outputFormat, out);
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
ByteArrayInputStream compressedInputStream = new ByteArrayInputStream(out.toByteArray());
return compressedInputStream;
}