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

}

  

 

posted @ 2022-10-18 15:42  90的生力军  阅读(274)  评论(0编辑  收藏  举报