java传递参数调用python完成剪切多个视频最终拼接成一个
需求如题,综合考虑之后我选择python去做视频处理,最终结果也让我非常满意。
我是windows 环境,安装的python3.8和moviepy模块
第一步:安装python3.8
第二步:修改python模块下载源,在Roaming下直接新建pip文件夹,新建pip.ini文件
我的路径是C:\Users\用户名\AppData\Roaming\pip\pip.ini 可进行参考,如下:
[global] timeout = 6000 index-url = https://mirrors.aliyun.com/pypi/simple [install] use-mirrors = true mirros = https://pypi.mirrors.ustc.edu.cn/simple
第三步:下载moviepy模块
cmd 执行 pip install moviepy

第四步:编写python 剪切拼接视频的代码(123.mp4,456.mp4都是测试视频,自己找一个)
import moviepy
import sys
from moviepy.editor import *
def main(a):
print(url) # 打印java 传来的参数
video = VideoFileClip("C:\\Users\\HG\\123.mp4").subclip(1,5)# 表示截取123.mp4的1-5秒
video1 = VideoFileClip("C:\\Users\\HG\\456.mp4").subclip(5,10)
video2 = concatenate_videoclips([video,video1])# 拼接两个剪切好的视频
result = CompositeVideoClip([video2])
result.to_videofile("video_1.mp4")# 输出到工作目录下
if __name__ == '__main__':
for i in range(0, len(sys.argv)):
url = sys.argv[i]# 按数组的方式取出java 传来的参数
main(url)# 执行打印方法
第五步:写java 调用python 脚本的代码,这个地方我了解了一下,有两种办法①引入jython包执行,便捷但不能传参,故舍弃。②用Runtime.getRuntime().exec() 执行,可传参。
保存python执行日志到文件的java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* @ClassName: StreamReaderThread
* @Description: 执行python 脚本打印执行日志
* @Date 2022/10/18 14:28
*/
public class StreamReaderThread implements Runnable {
private Logger logger = LoggerFactory.getLogger(StreamReaderThread.class);
/*
* 输出流
*/
private InputStream inputStream;
/*
* 输出信息保存的文件名称
*/
private String logName;
public StreamReaderThread(InputStream inputStream, String logName) {
this.inputStream = inputStream;
this.logName = logName;
}
/**
* FileWriter将日志写入某文件
* 也可以用logger打印日志记录。
*/
@Override
public void run() {
BufferedReader in = null;
FileWriter fwriter = null;
try {
in = new BufferedReader(new InputStreamReader(this.inputStream, "gbk"));
fwriter = new FileWriter(logName, true);
String line = null;
while ((line = in.readLine()) != null) {
fwriter.write(line);
logger.info(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
fwriter.flush();
fwriter.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
python 调用的java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.rmi.ServerException;
/**
* @ClassName: PythonScriptUtils
* @Description: 调用python脚本
* @Date 2022/10/18 14:25
*/
public class PythonScriptUtils {
private static Logger logger = LoggerFactory.getLogger(PythonScriptUtils.class);
/**
* 执行python脚本
* @param path 文件地址:比如 D:\\xxx\\helloWorld.py
*/
public static Boolean exePython(String path) throws ServerException {
logger.info("======python start");
boolean success = false;
Process proc = null;
try {
// linux 用 "python3", windows 用python.exe的绝对路径("D:\\xxx\\Python\\Python39-32\\python.exe")
String a = "hello world";
String url = "www.baidu.com";
// String[] args1 = new String[]{"python3", path,a,url}; //linux 系统使用此代码进行执行
String[] args1 = new String[]{"C:\\Users\\HG\\AppData\\Local\\Programs\\Python\\Python38\\python.exe", path,a,url};
proc = Runtime.getRuntime().exec(args1);
// 读写日志线程,分成两个也是为了避免线程堵塞之类的问题,具体原因网络上有很多说明
Thread thread1 = new Thread(new StreamReaderThread(proc.getInputStream(),"info.txt"));
Thread thread2 = new Thread(new StreamReaderThread(proc.getErrorStream(),"error.txt"));
thread2.start();
//必须后执行,否则正确消息容易接收不到
thread1.start();
// result是结果,具体有哪些值,可以自己去查一下
int result = proc.waitFor();
success = result != -1;
//等待后台线程读写完毕
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
throw new ServerException("python error:" + e);
} finally {
try {
proc.getErrorStream().close();
proc.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
proc.destroy();
logger.info("======python end");
}
return success;
}
public static void main(String[] args) throws Exception {
exePython("C:\\Users\\HG\\test.py");
}
}

浙公网安备 33010602011771号