java简单封装ffmpeg

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值