ffmpeg在C和C++下有直接可以使用的API,但是在JAVA上没找到很好用的开源包。
于是我对其进行了很简单的封装。实际上我是在基于操作系统命令行层面的封装,利用java的跨平台性,可以在windows和linux下使用。
基本上思想就是调用命令行的ffmpeg可执行文件,然后重定位输出,抓取分析输出内容来实现我们的需求。
/**
*
*/
package com.nvvideo.util;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.nvvideo.util.cmd.CmdExecuter;
import com.nvvideo.util.cmd.IStringGetter;
/**
* FFMpegUntil
* <p>Title: FFMpeg工具类</p>
* <p>Description: 本类封装FFMpeg对视频的操作</p>
* <p>Date: 2010-7-14</p>
* <p>Copyright: Copyright (c) 2010</p>
* <p>Company: novel-supertv.com</p>
* @author chenggong
* @version 1.0
*/
public class FFMpegUtil implements IStringGetter{
private int runtime = 0;
private String ffmpegUri;//ffmpeg地址
private String originFileUri; //视频源文件地址
private enum FFMpegUtilStatus { Empty, CheckingFile, GettingRuntime };
private FFMpegUtilStatus status = FFMpegUtilStatus.Empty;
/**
* 构造函数
* @param ffmpegUri ffmpeg的全路径
* 如e:/ffmpeg/ffmpeg.exe 或 /root/ffmpeg/bin/ffmpeg
* @param originFileUri 所操作视频文件的全路径
* 如e:/upload/temp/test.wmv
*/
public FFMpegUtil( String ffmpegUri, String originFileUri ){
this.ffmpegUri = ffmpegUri;
this.originFileUri = originFileUri;
}
/**
* 获取视频时长
* @return
*/
public int getRuntime(){
runtime = 0;
status = FFMpegUtilStatus.GettingRuntime;
cmd.clear();
cmd.add(ffmpegUri);
cmd.add("-i");
cmd.add(originFileUri);
CmdExecuter.exec(cmd, this);
return runtime;
}
/**
* 检测文件是否是支持的格式
* 将检测视频文件本身,而不是扩展名
* @return
*/
public boolean isSupported(){
isSupported = true;
status = FFMpegUtilStatus.CheckingFile;
cmd.clear();
cmd.add(ffmpegUri);
cmd.add("-i");
cmd.add(originFileUri);
CmdExecuter.exec(cmd, this);
return isSupported;
}
private boolean isSupported;
/**
* 生成视频截图
* @param imageSavePath 截图文件保存全路径
* @param screenSize 截图大小 如640x480
*/
public void makeScreenCut( String imageSavePath , String screenSize ){
cmd.clear();
cmd.add(ffmpegUri);
cmd.add("-i");
cmd.add(originFileUri);
cmd.add("-y");
cmd.add("-f");
cmd.add("image2");
cmd.add("-ss");
cmd.add("8");
cmd.add("-t");
cmd.add("0.001");
cmd.add("-s");
cmd.add(screenSize);
cmd.add(imageSavePath);
CmdExecuter.exec(cmd, null);
}
/**
* 视频转换
* @param fileSavePath 文件保存全路径(包括扩展名)如 e:/abc/test.flv
* @param screenSize 视频分辨率 如640x480
* @param audioByte 音频比特率
* @param audioCollection 音频采样率
* @param quality 视频质量(0.01-255)越低质量越好
* @param fps 每秒帧数(15或29.97)
*/
public void videoTransfer(
String fileSavePath,
String screenSize,
int audioByte,
int audioCollection,
double quality,
double fps ){
cmd.clear();
cmd.add(ffmpegUri);
cmd.add("-i");
cmd.add(originFileUri);
cmd.add("-y");
cmd.add("-ab");
cmd.add( Integer.toString(audioByte) );
cmd.add("-ar");
cmd.add( Integer.toString(audioCollection) );
cmd.add("-qscale");
cmd.add( Double.toString(quality) );
cmd.add("-r");
cmd.add( Double.toString(fps) );
cmd.add("-s");
cmd.add(screenSize);
cmd.add( fileSavePath );
CmdExecuter.exec(cmd, null);
}
private List<String> cmd = new ArrayList<String>();
@Override
public void dealString( String str ){
switch( status )
{
case Empty:
break;
case CheckingFile:{
Matcher m = Pattern.compile("Unknown format").matcher(str);
if( m.find() )
this.isSupported = false;
break;
}
case GettingRuntime:{
Matcher m = Pattern.compile("Duration: \\w+:\\w+:\\w+").matcher(str);
while (m.find())
{
String msg = m.group();
msg = msg.replace("Duration: ", "");
runtime = TimeUtil.runtimeToSecond(msg);
}
break;
}
}//switch
}
}
用到另外封装的一个命令行执行器
/**
*
*/
package com.nvvideo.util.cmd;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
/**
* CmdExecuter
* <p>Title: 命令执行器</p>
* <p>Description: 封装对操作系统命令行发送指令相关操作</p>
* <p>Date: 2010-7-14</p>
* <p>Copyright: Copyright (c) 2010</p>
* <p>Company: novel-supertv.com</p>
* @author chenggong
* @version 1.0
*/
public class CmdExecuter {
/**
* 执行指令
* @param cmd 执行指令
* @param getter 指令返回处理接口,若为null则不处理输出
*/
static public void exec( List<String> cmd, IStringGetter getter ){
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(cmd);
builder.redirectErrorStream(true);
Process proc = builder.start();
BufferedReader stdout = new BufferedReader(
new InputStreamReader(proc.getInputStream()));
String line;
while ((line = stdout.readLine()) != null) {
if( getter != null )
getter.dealString(line);
}
proc.waitFor();
stdout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
当做回调函数的接口(JAVA没有回调,没有委托……只会用接口)
/**
*
*/
package com.nvvideo.util.cmd;
/**
* IStringGetter
* <p>Title: 字符串接收者接口</p>
* <p>Description: </p>
* <p>Date: 2010-7-14</p>
* <p>Copyright: Copyright (c) 2010</p>
* <p>Company: novel-supertv.com</p>
* @author chenggong
* @version 1.0
*/
public interface IStringGetter {
/**
* 处理字符串
* @param str
*/
public void dealString( String str );
}
分享到:
相关推荐
首先,我们要了解Java封装FFmpeg的基本原理。通常,这涉及到使用JNI(Java Native Interface)或JNA(Java Native Access)来调用FFmpeg的C/C++库。这样,Java代码可以调用FFmpeg的函数,执行多媒体操作,而无需离开...
在Java中,你可以创建一个`FFmpegWrapper`类来封装FFmpeg的命令行操作。下面是一个简单的示例,展示了如何调用FFmpeg进行视频截图和格式转换: ```java import org.bytedeco.ffmpeg.global.avformat; import org....
- `ffmpeg-java`:这是一个Java封装的FFmpeg库,可以直接通过Maven或Gradle添加依赖。使用它,可以创建Java对象来执行FFmpeg命令。 - `fluent-ffmpeg`:这是一个更高级的Java库,提供了更友好的API来操作FFmpeg。...
首先,`ffmpeg.jar`是Java版的FFmpeg封装,它提供了与FFmpeg命令行工具类似的接口,方便在Java程序中调用FFmpeg的功能。你需要先将这个JAR文件添加到项目的类路径中,以便能够使用其提供的API。 FFmpeg支持多种操作...
3. **ffmpeg.jar**: 这是JavaCV对FFmpeg库的Java封装,允许开发者在Java中进行音视频的处理和分析。包括视频的读取、播放、编码、解码、剪辑、转码等功能。 4. **opencv.jar**: OpenCV是一个流行的计算机视觉库,...
此外,为了保证程序的可维护性和扩展性,可以考虑将命令行构建和执行的过程封装到单独的函数中,这样在未来需要支持其他格式或者调整转换参数时,改动会更简单。 总结来说,通过Java调用FFmpeg和Mencoder进行视频...
导入依赖就可以运行
在Java开发中,通过封装FFmpeg命令,可以方便地在应用程序中集成音视频处理功能。本压缩包提供的"ffmpeg java 封装工具类"正是为了解决这个问题,它将FFmpeg的功能与Java编程语言相结合,提供了一套易于使用的API。 ...
ffmpeg本身没有支持java的AIP,所以在这里使用java中runtime操作ffmpeg获取视频文件的分辨率、码率、时长等信息,以及自动截图功能。 其中有个java项目、ffmpeg-win32程序包
在JavaCV中,这些功能被封装成了易于使用的Java接口,使得开发者无需深入了解底层的C/C++代码,就能在Java环境中调用FFmpeg的能力。 在“javacv1.41-ffmpeg”的压缩包内,"jar"文件很可能包含了以下关键组件: 1. ...
在Java平台上,FFmpeg通过提供Java封装库使得开发者能够利用其功能来处理多媒体数据,例如播放、录制、转换音频和视频格式等。这个Java包类库通常被称为JavaFFmpeg或者JAVE(Java Video Encoder)。 FFmpeg的核心...
`FFmpegUtil.java`这个文件很可能是封装了调用FFmpeg命令的Java类。在这个类中,开发者可能会定义如下的方法: 1. `compressVideo(String inputPath, String outputPath, int bitrate)`: 这个方法接收输入视频路径...
3. **Java封装FFmpeg** 在这个项目中,开发者创建了一个Java类,该类包含了调用FFmpeg命令的方法,如`pushStream()`,它会根据参数构造FFmpeg的命令字符串,然后通过JNI调用系统命令执行推流操作。这样做的好处是,...
1. **ffmpeg-linux-ppc64le.jar**: 这是针对Linux操作系统,PowerPC 64位Little Endian架构的FFmpeg库的Java封装。它使Java程序能够处理该平台上音视频的编解码任务。 2. **ffmpeg-android-x86.jar**: 专为Android...
而Java则提供了一个稳定的运行环境和丰富的库来封装FFmpeg的功能,使得在Java应用中调用FFmpeg变得更加便捷。 1. **Java调用FFmpeg**: Java通过调用系统命令或者使用第三方库(如`xuggle`、`javacv`、`ffmpeg-...
为了提高代码的健壮性和可维护性,建议使用成熟的Java库如`ffmpeg-cli-wrapper`或`minimp3`来封装FFmpeg命令。这些库提供了更友好的API,可以避免直接处理命令行字符串的复杂性。 此外,还可以通过调整FFmpeg参数...
这些库封装了FFmpeg的API,提供了更友好的Java接口。例如,使用JAVE(Java Audio Video Encoder): ```java import it.sauronsoftware.jave.*; AudioAttributes audio = new AudioAttributes(); audio.setCodec(...
2. **使用Java库封装FFmpeg**:有一些Java库如Xuggle、JAVE(Java Audio Video Encoder)和 Lavf(Java bindings for Libavformat)提供对FFmpeg的封装,使得调用更加便捷,同时能更好地管理和处理FFmpeg的输入输出...
此外,对于大型项目,使用成熟的Java库如Xuggler(虽然已不再维护,但仍有大量项目在使用)可以提供更高级的功能和更好的封装,减少直接操作FFmpeg命令的复杂性。 总之,Java FFmpeg视频转换涉及了多媒体处理的基本...
在Java中,我们通常通过调用FFmpeg的命令行接口或者使用已经封装好的Java库来实现这些功能。 FFmpeg本身是一个C语言编写的程序,但开发者可以通过Java FFmpeg Wrapper或者其他Java库(如Xuggle)来在Java应用中使用...