Java ffmpeg 工具类封住

package com.zzg.ffmpeg;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import com.zzg.ffmpeg.config.FfmpegConfig;
import com.zzg.ffmpeg.config.params.FfmpegParam;
import com.zzg.ffmpeg.config.params.FfmpegParams;
import com.zzg.ffmpeg.exception.FfmpegTransformException;
import com.zzg.ffmpeg.media.Media;
import com.zzg.ffmpeg.media.MediaType;


/**
 * ffmpeg 核心功能代码
 * 
 * @author zzg
 *
 */
public class Ffmpeg {

	private final FfmpegConfig ffmpegConfig;

	private final List<Media> medias;

	private final FfmpegParams params;

	private List<Integer> successValues = new ArrayList<Integer>(Arrays.asList(0));
	
	/**
     * Timeout to wait while generating a PDF, in seconds
     */
    private int timeout = 10;
    
	public int getTimeout() {
		return timeout;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	public Ffmpeg() {
		this(new FfmpegConfig());
	}

	public Ffmpeg(FfmpegConfig ffmpegConfig) {
		super();
		this.ffmpegConfig = ffmpegConfig;
		this.medias = new ArrayList<Media>();
		this.params = new FfmpegParams();
	}

	/**
	 * 输入文件
	 * 
	 * @param source
	 */
	public void addMediaInput(String source) {
		this.medias.add(new Media(source, MediaType.input));
	}

	/**
	 * 输出文件
	 * 
	 * @param source
	 */
	public void addMediaOutput(String source) {
		this.medias.add(new Media(source, MediaType.output));
	}

	/**
	 * ffmpeg 请求参数
	 * 
	 * @param param
	 * @param params
	 */
	public void addParam(FfmpegParam param, FfmpegParam... params) {
		this.params.add(param, params);
	}

	public byte[] getFFMPEG() throws IOException, InterruptedException {
		ExecutorService executor = Executors.newFixedThreadPool(2);
		try {
			// cmd 执行命令
			String command = getCommand();
			System.out.println("输出指令:" + command);
			Process process = Runtime.getRuntime().exec(getCommandAsArray());

			Future<byte[]> inputStreamToByteArray = executor.submit(streamToByteArrayTask(process.getInputStream()));
			Future<byte[]> outputStreamToByteArray = executor.submit(streamToByteArrayTask(process.getErrorStream()));

			process.waitFor();

			if (!successValues.contains(process.exitValue())) {
				byte[] errorStream = getFuture(outputStreamToByteArray);

				throw new FfmpegTransformException(command, process.exitValue(), errorStream,
						getFuture(inputStreamToByteArray));
			}
			return getFuture(inputStreamToByteArray);
		} finally {
            executor.shutdownNow();
        }

	}

	private Callable<byte[]> streamToByteArrayTask(final InputStream input) {
		return new Callable<byte[]>() {
			public byte[] call() throws Exception {
				return IOUtils.toByteArray(input);
			}
		};
	}

	private byte[] getFuture(Future<byte[]> future) {
		try {
			return future.get(this.timeout, TimeUnit.SECONDS);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Gets the final ffmpeg command as string
	 * 
	 * @return the generated command from params
	 * @throws IOException
	 */
	public String getCommand() throws IOException {
		return StringUtils.join(getCommandAsArray(), " ");
	}

	protected String[] getCommandAsArray() throws IOException {
		List<String> commandLine = new ArrayList<String>();
		// 指令部分ffmpeg
		commandLine.add(ffmpegConfig.getFfmpegCommand());

		commandLine.add("-i");

		// 输入文件
		for (Media media : medias) {
			if (media.getType().equals(MediaType.input)) {
				commandLine.add(media.getSource());
			}
		}

		// 参数部分
		commandLine.addAll(params.getParamsAsStringList());

		// 输出文件
		for (Media media : medias) {
			if (media.getType().equals(MediaType.output)) {
				commandLine.add(media.getSource());
			}
		}
		return commandLine.toArray(new String[commandLine.size()]);
	}

}
package com.zzg.ffmpeg.config;

import java.io.IOException;
import java.nio.charset.Charset;
import org.apache.commons.io.IOUtils;
import com.zzg.ffmpeg.exception.FfmpegConfigurationException;

/**
 * ffmpeg 配置对象
 * 
 * @author zzg
 *
 */
public class FfmpegConfig {
	private String ffmpegCommand = "ffmpeg";

	public String getFfmpegCommand() {
		return ffmpegCommand;
	}

	public void setFfmpegCommand(String ffmpegCommand) {
		this.ffmpegCommand = ffmpegCommand;
	}

	public FfmpegConfig() {
		setFfmpegCommand(findExecutable());
	}

	public FfmpegConfig(String ffmpegCommand) {
		super();
		this.ffmpegCommand = ffmpegCommand;
	}

	public String findExecutable() {
		try {
			String osname = System.getProperty("os.name").toLowerCase();
			String cmd = osname.contains("windows") ? "where.exe ffmpeg" : "which ffmpeg";

			Process p = Runtime.getRuntime().exec(cmd);

			p.waitFor();

			String text = IOUtils.toString(p.getInputStream(), Charset.defaultCharset()).trim();
			
			if (text.isEmpty()){
				throw new FfmpegConfigurationException("ffmpeg command was not found in your classpath. " +
                        "Verify its installation or initialize wrapper configurations with correct path/to/ffmpeg");
			}
			setFfmpegCommand(text);
                
		} catch (IOException e) {
			// log日志记录错误信息, 暂时打印堆栈信息
			e.printStackTrace();
		} catch (InterruptedException e) {
			// log日志记录错误信息, 暂时打印堆栈信息
			e.printStackTrace();
		}
		return getFfmpegCommand();
	}

}
package com.zzg.ffmpeg.config.params;

import java.util.ArrayList;
import java.util.List;

/**
 * ffmpeg 请求参数实体对象封住
 * 
 * @author zzg
 *
 */
public class FfmpegParam {

	private String key;

	// 某些指令接受多个参数值
	private List<String> values = new ArrayList<String>();

	public FfmpegParam(String key, String... valueArray) {
		this.key = key;
		for (String value : valueArray) {
			values.add(value);
		}
	}

	// 某些指令无参数值
	public FfmpegParam(String key) {
		this(key, new String[0]);
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public List<String> getValues() {
		return values;
	}

	public void setValues(List<String> values) {
		this.values = values;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder().append(FfmpegSymbol.separator).append(FfmpegSymbol.param).append(key);
		for (String value : values) {
			sb.append(FfmpegSymbol.separator).append(value);
		}
		return sb.toString();
	}

}
package com.zzg.ffmpeg.config.params;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * 批量处理FfmpegParam 请求参数对象
 * @author zzg
 *
 */
public class FfmpegParams {
	private Collection<FfmpegParam> params;

    public FfmpegParams() {
        this.params = new ArrayList<FfmpegParam>();
    }

    public void add(FfmpegParam param, FfmpegParam... params) {
        this.params.add(param);
        this.params.addAll( Arrays.asList( params ) );
    }
    
    public List<String> getParamsAsStringList() {
        List<String> commandLine = new ArrayList<String>();

        for (FfmpegParam p : params) {
            commandLine.add(p.getKey());

            for (String value : p.getValues()) {
                if (value != null) {
                    commandLine.add(value);
                }
            }
        }

        return commandLine;
    }
}
package com.zzg.ffmpeg.config.params;
/**
 * ffmpeg 符号
 * @author zzg
 *
 */
public enum FfmpegSymbol {
	separator(" "), param("");
	
	private final String symbol;

	FfmpegSymbol(String symbol) {
        this.symbol = symbol;
    }

    @Override
    public String toString() {
        return symbol;
    }

}
package com.zzg.ffmpeg.exception;

@SuppressWarnings("serial")
public class FfmpegConfigurationException extends RuntimeException {

	public FfmpegConfigurationException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}
	
}
package com.zzg.ffmpeg.exception;

/**
 * ffmpeg 转换异常
 * 
 * @author zzg
 *
 */
@SuppressWarnings("serial")
public class FfmpegTransformException extends RuntimeException {
	private String command;

	private int exitStatus;

	private byte[] out;

	private byte[] err;

	public FfmpegTransformException(String command, int exitStatus, byte[] err, byte[] out) {
		this.command = command;
		this.exitStatus = exitStatus;
		this.err = err;
		this.out = out;
	}

	public String getCommand() {
		return command;
	}

	public int getExitStatus() {
		return exitStatus;
	}

	public byte[] getOut() {
		return out;
	}

	public byte[] getErr() {
		return err;
	}

	@Override
	public String getMessage() {
		return "Process (" + this.command + ") exited with status code " + this.exitStatus + ":\n" + new String(err);
	}
}
package com.zzg.ffmpeg.media;

public class Media {
	
	private String source;
	
	private MediaType type;

	public String getSource() {
		return source;
	}

	public void setSource(String source) {
		this.source = source;
	}

	public MediaType getType() {
		return type;
	}

	public void setType(MediaType type) {
		this.type = type;
	}

	public Media(String source, MediaType type) {
		this.source = source;
		this.type = type;
	}
}
package com.zzg.ffmpeg.media;
/**
 * 媒体文件:输入输出类型
 * @author zzg
 *
 */
public enum MediaType {
	input,
	output
}

功能测试代码:

package com.zzg.test;

import java.io.IOException;

import com.zzg.ffmpeg.Ffmpeg;
import com.zzg.ffmpeg.config.params.FfmpegParam;

public class FfmpegTest {
	
	// 视频转换:mp4 转换为flv
	// ffmpeg 指令:C:\ffmpg\ffmpeg\bin\ffmpeg.exe -i C:\ffmpg\ffmpeg\bin\test.mp4 -acodec copy -vcodec copy -f flv C:\ffmpg\ffmpeg\bin\output.flv
	public static void mp4TransformFlv() throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		Ffmpeg ffmpeg = new Ffmpeg();
		ffmpeg.addMediaInput("C:\\ffmpg\\ffmpeg\\bin\\test.mp4");
		ffmpeg.addMediaOutput("C:\\ffmpg\\ffmpeg\\bin\\output.flv");
		ffmpeg.addParam(new FfmpegParam("-acodec", new String[]{"copy"}), new FfmpegParam[]{new FfmpegParam("-vcodec", new String[]{"copy"}),new FfmpegParam("-f", new String[]{"flv"})});
		byte[] bytes = ffmpeg.getFFMPEG();
		System.out.println(new String(bytes));
	}
	
	// 视频转换:mp4 转换为h264
	// ffmpeg 指令:C:\ffmpg\ffmpeg\bin\ffmpeg.exe -i C:\ffmpg\ffmpeg\bin\test.mp4 -codec copy -bsf h264_mp4toannexb -f h264 C:\ffmpg\ffmpeg\bin\output.h264
	public static void mp4TransformH264() throws IOException, InterruptedException {
		Ffmpeg ffmpeg = new Ffmpeg();
		ffmpeg.addMediaInput("C:\\ffmpg\\ffmpeg\\bin\\test.mp4");
		ffmpeg.addMediaOutput("C:\\ffmpg\\ffmpeg\\bin\\output.h264");
		ffmpeg.addParam(new FfmpegParam("-codec", new String[]{"copy"}), new FfmpegParam[]{new FfmpegParam("-bsf", new String[]{"h264_mp4toannexb"}),new FfmpegParam("-f", new String[]{"h264"})});
		byte[] bytes = ffmpeg.getFFMPEG();
		System.out.println(new String(bytes));
	}
	
	// 视频转换:mp4 转换为ts
	// ffmpeg 指令:C:\ffmpg\ffmpeg\bin\ffmpeg.exe -i C:\ffmpg\ffmpeg\bin\test.mp4 -codec copy -bsf h264_mp4toannexb C:\ffmpg\ffmpeg\bin\test.ts
	public static void mp4TransformTs() throws IOException, InterruptedException{
		Ffmpeg ffmpeg = new Ffmpeg();
		ffmpeg.addMediaInput("C:\\ffmpg\\ffmpeg\\bin\\test.mp4");
		ffmpeg.addMediaOutput("C:\\ffmpg\\ffmpeg\\bin\\test.ts");
		ffmpeg.addParam(new FfmpegParam("-codec", new String[]{"copy"}), new FfmpegParam[]{new FfmpegParam("-bsf", new String[]{"h264_mp4toannexb"})});
		byte[] bytes = ffmpeg.getFFMPEG();
		System.out.println(new String(bytes));
	}
	
	// 视频转换: ts 转换为mp4
	// ffmpeg 指令:C:\ffmpg\ffmpeg\bin\ffmpeg.exe -i C:\ffmpg\ffmpeg\bin\test.ts -acodec copy -vcodec copy -f mp4 C:\ffmpg\ffmpeg\bin\output.mp4
	public static void tsTransformMp4() throws IOException, InterruptedException{
		Ffmpeg ffmpeg = new Ffmpeg();
		ffmpeg.addMediaInput("C:\\ffmpg\\ffmpeg\\bin\\test.ts");
		ffmpeg.addMediaOutput("C:\\ffmpg\\ffmpeg\\bin\\output.mp4");
		ffmpeg.addParam(new FfmpegParam("-acodec", new String[]{"copy"}), new FfmpegParam[]{new FfmpegParam("-vcodec", new String[]{"copy"}),new FfmpegParam("-f", new String[]{"mp4"})});
		byte[] bytes = ffmpeg.getFFMPEG();
		System.out.println(new String(bytes));
	}
	
	// 视频转换:ts 转换为flv
	// ffmpeg 指令:C:\ffmpg\ffmpeg\bin\ffmpeg.exe -i C:\ffmpg\ffmpeg\bin\test.ts -acodec copy -vcodec copy -f flv C:\ffmpg\ffmpeg\bin\123.flv
	public static void tsTransformFlv() throws IOException, InterruptedException{
		Ffmpeg ffmpeg = new Ffmpeg();
		ffmpeg.addMediaInput("C:\\ffmpg\\ffmpeg\\bin\\test.ts");
		ffmpeg.addMediaOutput("C:\\ffmpg\\ffmpeg\\bin\\123.flv");
		ffmpeg.addParam(new FfmpegParam("-acodec", new String[]{"copy"}), new FfmpegParam[]{new FfmpegParam("-vcodec", new String[]{"copy"}),new FfmpegParam("-f", new String[]{"flv"})});
		byte[] bytes = ffmpeg.getFFMPEG();
		System.out.println(new String(bytes));
	}
	
	// 视频分离之视频分离
	// ffmpeg 指令:C:\ffmpg\ffmpeg\bin\ffmpeg.exe -i C:\ffmpg\ffmpeg\bin\music.mp4 -vn  -f mp3 -y  C:\ffmpg\ffmpeg\bin\test.mp3
	public static void videoDelete() throws IOException, InterruptedException{
		Ffmpeg ffmpeg = new Ffmpeg();
		ffmpeg.addMediaInput("C:\\ffmpg\\ffmpeg\\bin\\demo.mp4");
		ffmpeg.addMediaOutput("C:\\ffmpg\\ffmpeg\\bin\\test.mp3");
		ffmpeg.addParam(new FfmpegParam("-vn", new String[]{""}), new FfmpegParam[]{new FfmpegParam("-f", new String[]{"mp3"}),new FfmpegParam("-y", new String[]{""})});
		byte[] bytes = ffmpeg.getFFMPEG();
		System.out.println(new String(bytes));
	}
	// 视频分离之音频分离
	// ffmpeg指令:C:\ffmpg\ffmpeg\bin\ffmpeg.exe -i C:\ffmpg\ffmpeg\bin\demo.mp4 -an  -vcodec copy C:\ffmpg\ffmpeg\bin\demo1.mp4
	public static void audioDelete() throws IOException, InterruptedException{
		Ffmpeg ffmpeg = new Ffmpeg();
		ffmpeg.addMediaInput("C:\\ffmpg\\ffmpeg\\bin\\demo.mp4");
		ffmpeg.addMediaOutput("C:\\ffmpg\\ffmpeg\\bin\\demo1.mp4");
		ffmpeg.addParam(new FfmpegParam("-an", new String[]{""}), new FfmpegParam[]{new FfmpegParam("-vcodec", new String[]{"copy"})});
		byte[] bytes = ffmpeg.getFFMPEG();
		System.out.println(new String(bytes));
	}
	public static void main(String[] args) throws IOException, InterruptedException {
		// TODO Auto-generated method stub
		// 视频文件之转换
		//mp4TransformFlv();
		//mp4TransformH264();
		//mp4TransformTs();
		//tsTransformMp4();
		//tsTransformFlv();
		
		// 视频文件之音频/视频分离
		//videoDelete();
		//audioDelete();
	}

}

效果截图:

参考文章地址:windows 如何安装ffmpeg 环境:https://blog.csdn.net/zhouzhiwengang/article/details/87251095

                       ffmpeg参数中文详细解释:https://blog.csdn.net/leixiaohua1020/article/details/12751349

回答: 如果你想在Java中使用FFmpeg工具类,一般可以通过调用CMD命令来实现。你可以使用类似于以下的命令来转换MP4文件为AVI格式:ffmpeg -i input.mp4 -y output.avi。其中,input.mp4是你要转换的MP4文件路径,output.avi是转换后的AVI文件路径。\[1\]另外,你也可以使用类似于以下的命令将AMR文件转换为MP3格式:ffmpeg -i input.amr -y output.mp3。同样,input.amr是你要转换的AMR文件路径,output.mp3是转换后的MP3文件路径。\[3\]请注意,这只是基本的使用方法,你可以在FFmpeg官网查询更多详细的参数使用方法。\[2\] #### 引用[.reference_title] - *1* *3* [ffmpeg安装和基本使用,java工具类,amr文件转MP3](https://blog.csdn.net/m0_60261305/article/details/120910667)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Ffmpeg入门级教程(Java代码开发)](https://blog.csdn.net/u012998680/article/details/126627715)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值