java 视频统一转成mp4格式,并且异步多线程上传

背景:遇到一个项目就是上传视频文件不限格式,需要全部统一转成mp4格式。具体细节是 1.前端展示的视频不能是从头加载的,需要像某讯那样快进到哪里,从哪个节点开始加载,实现无卡顿播放,2,后台获取时长,大小等数据信息,四张视频截图封面,从其中选择一张作为封面。

直接上代码:视频获取时长大小,截图,视频转换

import com.alibaba.fastjson.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ConvertVideo {
    private static String mplayerPath; //= "C:/watermark/mencoder.exe";

    private static String ffmpegPath; //= "C:/watermark/ffmpeg-4.3.1-2021-01-01-essentials_build/bin/ffmpeg.exe";

    private static String filepath; //= "D:/minio/data/";

    public static void setMplayerPath(String mplayerPath) {
        ConvertVideo.mplayerPath = mplayerPath;
    }

    public static void setFfmpegPath(String ffmpegPath) {
        ConvertVideo.ffmpegPath = ffmpegPath;
    }

    public static void setFilepath(String filepath) {
        ConvertVideo.filepath = filepath;
    }

    /**
     * 视频格式转换入口
     *
     * @param inputPath  源文件 路径
     * @param outputPath 目标文件 路径
     * @param outputPath1 中间文件地址 路径
     * @return
     */
    public synchronized static boolean process(String inputPath, String outputPath ,String outputPath1) {
        int type = checkContentType(inputPath);
        boolean status = false;
        Long old = System.currentTimeMillis();
        System.out.println("old--------" + old);
        if (type == 0) {
            System.out.println("直接转成MP4格式");
            status = processMP4(inputPath, outputPath);// 直接转成flv格式
        } else if (type == 1) {
            String avifilepath = processAVI(inputPath, outputPath1);
            System.out.println(avifilepath);
            if (avifilepath == null){
                return false;// 没有得到avi格式
            }
            status = processMP4(avifilepath, outputPath);// 将avi转成flv格式
        }
        Long yong = System.currentTimeMillis();
        System.out.println("消耗时间----------" + (yong-old));
        return status;
    }

    /**
     * 判断文件类型.执行不同的转换流程
     *
     * @param inputPath 源文件路径
     * @return
     */
    private static int checkContentType(String inputPath) {
        String type = inputPath.substring(inputPath.lastIndexOf(".") + 1, inputPath.length())
                .toLowerCase();
        // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
        if (type.equals("avi")) {
            return 0;
        } else if (type.equals("mpg")) {
            return 0;
        } else if (type.equals("wmv")) {
            return 0;
        } else if (type.equals("3gp")) {
            return 0;
        } else if (type.equals("mov")) {
            return 0;
        } else if (type.equals("mp4")) {
            return 0;
        } else if (type.equals("asf")) {
            return 0;
        } else if (type.equals("asx")) {
            return 0;
        } else if (type.equals("flv")) {
            return 0;
        }
        // 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),
        // 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
        else if (type.equals("wmv9")) {
            return 1;
        } else if (type.equals("rm")) {
            return 1;
        } else if (type.equals("rmvb")) {
            return 1;
        }else if (type.equals("dat")) {
            return 1;
        }
        return 9;
    }

    /**
     * 判断源文件是否存在
     *
     * @param path 文件路径
     * @return
     */
    private static boolean checkfile(String path) {
        File file = new File(path);
        if (!file.isFile()) {
            return false;
        }
        return true;
    }

    // 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
    private static String processAVI(String inputPath, String outputPath1) {
        List<String> commend = new ArrayList<>();
        commend.add(mplayerPath);
        //commend.add("C:/watermark/mencoder.exe");
        commend.add(inputPath);
        commend.add("-oac");
        commend.add("mp3lame");
        commend.add("-lameopts");
        commend.add("preset=64");
        commend.add("-ovc");
        commend.add("xvid");
        commend.add("-xvidencopts");
        commend.add("bitrate=600");
        commend.add("-of");
        commend.add("avi");
        commend.add("-o");
        commend.add(outputPath1);
        try {
            ProcessBuilder builder = new ProcessBuilder();
            Process process = builder.command(commend).redirectErrorStream(true).start();
            new PrintStream(process.getInputStream()).start();
            new PrintStream(process.getErrorStream()).start();
            process.waitFor();
            process.destroy();
            return outputPath1;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等) 转换为MP4
    private static boolean processMP4(String inputPath, String outputPath) {

        if (!checkfile(inputPath)) {
            System.out.println(inputPath + " is not file");
            return false;
        }

        List<String> command = new ArrayList<>();
        command.add(ffmpegPath);
        //command.add("C:/watermark/ffmpeg-4.3.1-2021-01-01-essentials_build/bin/ffmpeg.exe");
        command.add("-i");
        command.add(inputPath);
        command.add("-c:v");
        command.add("libx264");
        command.add("-mbd");
        command.add("0");
        command.add("-c:a");
        command.add("aac");
        command.add("-strict");
        command.add("-2");
        command.add("-pix_fmt");
        command.add("yuv420p");
        command.add("-movflags");
        command.add("faststart");
        command.add(outputPath);
        try {
            Process videoProcess = new ProcessBuilder(command).redirectErrorStream(true).start();

            new PrintStream(videoProcess.getErrorStream()).start();

            new PrintStream(videoProcess.getInputStream()).start();

            videoProcess.waitFor();
            videoProcess.destroy();
            System.out.println(outputPath);
            return true;
        } catch (Exception e) {

            return false;
        }
    }
    
    //map4截取图片
    public synchronized static boolean processImg(String veido_path, String image_path,String minao) {
        File file = new File(veido_path);
        if (!file.exists()) {
          System.err.println("路径[" + veido_path + "]对应的视频文件不存在!");
          return false;
        }
        List<String> commands = new ArrayList<String>();
        commands.add(ffmpegPath);
        commands.add("-i");
        commands.add(veido_path);
        commands.add("-y");
        commands.add("-f");
        commands.add("image2");
        commands.add("-ss");
        System.out.println(String.valueOf(minao));
        commands.add(minao);// 这个参数是设置截取视频多少秒时的画面
        // commands.add("-t");
        // commands.add("0.001");
        commands.add("-s");
        commands.add("700x700");//尺寸
        /*commands.add(veido_path.substring(0, veido_path.lastIndexOf("."))
            .replaceFirst("vedio", "file") + ".jpg");*/
        commands.add(image_path);
        try {
          ProcessBuilder builder = new ProcessBuilder();
          builder.command(commands);
          builder.start();
          System.out.println("截取成功");
          return true;
        } catch (Exception e) {
          e.printStackTrace();
          return false;
        }
      }
    
    
    
    public static JSONObject readVideoTimeFromCommand(String filePath){
        JSONObject jsonObject = new JSONObject();
        ProcessBuilder builder = new ProcessBuilder();
        List<String> commands = new ArrayList<>();
        commands.add(ffmpegPath);
        commands.add("-i");
        commands.add(filePath);
        builder.command(commands);
        builder.redirectErrorStream(true);
        Process p = null;
        try {
            p = builder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取执行输出信息
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8));
        StringBuilder outInfo = new StringBuilder();
        String line = "";
        while (true) {
            try {
                if (!((line = br.readLine()) != null)) {
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            outInfo.append(line);
        }
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 通过正则获取时长信息
        String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
        Pattern pattern = Pattern.compile(regexDuration);
        Matcher matcher = pattern.matcher(outInfo.toString());
        if (matcher.find()) {
            return getTime(matcher.group(1));
        }
        return jsonObject;
    }

    /**
     * 获取时间毫秒
     * @param time 格式:"00:00:10.68"
     * @return
     */
    private static JSONObject getTime(String time) {
        JSONObject jsonObject = new JSONObject();
    	System.out.println(time);
        int index = time.lastIndexOf(".");
        String distpath = time.substring(0, index);
        jsonObject.put("time",distpath);
        int min = 0;
        String[] strs = time.split(":");
        String ZERO="0";
        if (strs[0].compareTo(ZERO) > 0) {
            // 秒
            min += Long.parseLong(strs[0]) * 60 * 60 * 1000;
        }
        if (strs[1].compareTo(ZERO) > 0) {
            min += Long.parseLong(strs[1]) * 60 * 1000;
        }
        if (strs[2].compareTo(ZERO) > 0) {
            min += Math.round(Double.parseDouble(strs[2]) * 1000);
        }
        System.out.println(min);
        jsonObject.put("min",min);
        return jsonObject;
    }

}

/**
 * 资源释放流.避免内存溢出导致进程阻塞
 */
class PrintStream extends Thread {

    java.io.InputStream __is = null;

    public PrintStream(java.io.InputStream is) {
        __is = is;
    }

    @Override
    public void run() {
        try {
            while (this != null) {
                int _ch = __is.read();
                if (_ch != -1){
                    System.out.print((char) _ch);
                }else{
                    break;
                }
            }
            __is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static String secondsToTime(int seconds){
        int h=seconds/3600;			//小时
        int m=(seconds%3600)/60;		//分钟
        int s=(seconds%3600)%60;		//秒
        String hh = "";
        String mm = "";
        String ss = "";
        if(h>0){
            if(h<9){
                hh = "0"+h;
            }else{
                hh = ""+h;
            }
            if(m<9){
                mm = "0"+m;
            }else{
                mm = ""+m;
            }
            if(s<9){
                ss = "0"+s;
            }else{
                ss = ""+s;
            }
            return hh+":"+mm+":"+ss;
        }
        if(m>0){
            if(m<9){
                mm = "0"+m;
            }else{
                mm = ""+m;
            }
            if(s<9){
                ss = "0"+s;
            }else{
                ss = ""+s;
            }
            return "00:"+mm+":"+ss;
        }
        if(s<9){
            ss = "0"+s;
        }else{
            ss = ""+s;
        }
        return "00:00:"+ss;
    }


    public static void main(String[] args) {
        //获取时长和大小
        ConvertVideo.readVideoTimeFromCommand("文件路径");
        //截图  最后一个参数需要是 00:00:00格式的  截图最好截图前10秒的图,要不然截图会不成功
       // ConvertVideo.processImg("源文件", "图片存放位置" + ".jpg", secondsToTime("视频文件大小"));//截图
       //视频转换
       // ConvertVideo.process("源文件路径", "转成的mp4文件路径", "中间avi临时文件路径");
    }


}

注:需要用到两个文件

链接:https://pan.baidu.com/s/1qZb7CqcUxTZDe-nYwsnWsQ 
提取码:abcd

链接:https://pan.baidu.com/s/1oPzD1ZNCgF3HCKfi8aTEzg 
提取码:abcd

注意这种转换不管是获取时长,截图还是视频转换如果是多线程执行的话,一个线程执行完成另一个线程才会被执行,相当于多线程没有啥用,但是转换太费时间了,所以获取时长和截图我又找了其他的方法

上代码:

import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.info.MultimediaInfo;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

public class VideoUtil {

    /**
     * 上传视频,获取视频时长,返回毫秒
     * @param multipartFile
     * @return
     */
    public static long getDurationBackMillis(MultipartFile multipartFile){
        if(multipartFile != null){
            try{
                // 根据上传的文件名字,构建初始化的文件对象(临时文件),这个文件是空的
                File file = new File(multipartFile.getOriginalFilename());
                // 通过工具类,将文件拷贝到空的文件对象中
                FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);

                // 将普通文件对象转换为媒体对象
                MultimediaObject multimediaObject = new MultimediaObject(file);
                // 获取媒体对象的信息对象
                MultimediaInfo info = multimediaObject.getInfo();
                // 从媒体信息对象中获取媒体的时长,单位是:ms
                long duration = info.getDuration();
                // 删除临时文件
                file.delete();

                return duration;
            } catch(Exception e){
                return 0L;
            }
        }
        return 0L;
    }

    /**
     * 上传视频,获取视频时长,返回时分秒字符串
     * @param multipartFile
     * @return
     */
    public static String getDurationBackString(MultipartFile multipartFile){
        // 获取视频时长,返回毫秒
        long duration = getDurationBackMillis(multipartFile);
        // 毫秒转时分秒的转换
        // 日期格式化对象,给时分秒格式
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
        // 这里很重要,如果不设置时区的话,输出结果就会是几点钟,而不是毫秒值对应的时分秒数量了。
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
        // 毫秒转化为字符串
        return formatter.format(duration);
    }
}

import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

public class DealVideo {

    /*默认图片格式 jpg*/
    public static String DEFAULT_IMG_FORMAT = "jpg";

    /**
     * 获取指定视频的帧并保存为图片JPG格式至指定文件
     *
     * @param videoFile  源视频文件路径
     * @param targetFile 截取帧的图片存放路径
     * @param frameNum   截取第几帧
     * @throws Exception
     */
    public static void fetchFrameToFile(String videoFile, String targetFile, int frameNum) {
        //校验输入和输出
        checkInAnOut(videoFile, targetFile);
        try {
            File frameFile = new File(targetFile);
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
            ff.start();
            int length = ff.getLengthInFrames();
            /*第几帧判断设置*/
            if (frameNum < 0) {
                frameNum = 0;
            }
            if (frameNum > length) {
                frameNum = length - 5;
            }
            //指定第几帧
            ff.setFrameNumber(frameNum);
            int i = 0;
            Frame f = null;
            while (i < length) {
                // 过滤前5帧,避免出现全黑的图片,依自己情况而定
                f = ff.grabFrame();
                if ((i >= 5) && (f.image != null)) {
                    break;
                }
                i++;
            }
            opencv_core.IplImage img = f.image;
            int width = img.width();
            int height = img.height();
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
            bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH),
                    0, 0, null);
            ff.flush();
            ff.stop();
            ImageIO.write(bi, DEFAULT_IMG_FORMAT, frameFile);
        } catch (Exception e) {
            //throw new RuntimeException("转换视频图片异常");
            e.printStackTrace();
        }

    }

    /**
     * 获取指定视频的帧并保存为图片自定义类型至指定文件
     *
     * @param videoFile  源视频文件路径
     * @param targetFile 截取帧的图片存放文件路径
     * @param outImgFormat 输出图片格式
     * @param frameNum   截取第几帧
     * @throws Exception
     */
/*    public static void fetchFrameToFile(String videoFile, String targetFile, String outImgFormat, int frameNum) throws FrameGrabber.Exception, IOException {
        //校验输入和输出
        checkInAnOut(videoFile, targetFile);
        try {
            File frameFile = new File(targetFile);
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
            ff.start();
            int length = ff.getLengthInFrames();
            *//*第几帧判断设置*//*
            if (frameNum < 0) {
                frameNum = 0;
            }
            if (frameNum > length) {
                frameNum = length - 5;
            }
            //指定第几帧
            ff.setFrameNumber(frameNum);
            int i = 0;
            Frame f = null;
            while (i < length) {
                // 过滤前5帧,避免出现全黑的图片,依自己情况而定
                f = ff.grabFrame();
                if ((i >= 5) && (f.image != null)) {
                    break;
                }
                i++;
            }
            opencv_core.IplImage img = f.image;
            int width = img.width();
            int height = img.height();
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
            bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH),
                    0, 0, null);
            ff.flush();
            ff.stop();
            // ImageUtils2 工具类旋转图片
            BufferedImage ret = ImageUtils2.rotateClockwise0(bi);
            ImageIO.write(ret, outImgFormat, frameFile);
        } catch (Exception e) {
            throw new RuntimeException("转换视频图片异常");
        }
    }*/

    /**
     * 获取指定视频的帧图片,并转换为base64字符串
     *
     * @param videoFile 源视频文件路径
     * @param frameNum  截取第几帧
     * @throws Exception
     */
    public static String fetchFrameToBase64(String videoFile, int frameNum) throws FrameGrabber.Exception, IOException {
        //校验输入
        checkVideoFile(videoFile);
        try (ByteArrayOutputStream output = new ByteArrayOutputStream();) {
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoFile);
            ff.start();
            int length = ff.getLengthInFrames();
            /*第几帧判断设置*/
            if (frameNum < 0) {
                frameNum = 0;
            }
            if (frameNum > length) {
                frameNum = length - 5;
            }
            //指定第几帧
            ff.setFrameNumber(frameNum);
            int i = 0;
            Frame f = null;
            while (i < length) {
                // 过滤前5帧,避免出现全黑的图片,依自己情况而定
                f = ff.grabFrame();
                if ((i >= 5) && (f.image != null)) {
                    break;
                }
                i++;
            }
            opencv_core.IplImage img = f.image;
            int width = img.width();
            int height = img.height();
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
            bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH),
                    0, 0, null);
            ImageIO.write(bi, DEFAULT_IMG_FORMAT, output);
            // 这里需要获取图片的base64数据串,所以将图片写到流里面
            ff.flush();
            ff.stop();
            return new BASE64Encoder().encode(output.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException("转换视频图片异常");
        }
    }


    /**
     * 校验输入输出
     *
     * @param videoFile
     * @param targetFile
     */
    public static void checkInAnOut(String videoFile, String targetFile) {
        checkVideoFile(videoFile);
        checkTargetFileDir(targetFile);
    }

    /**
     * 验证文件目录是否存在,不存在就创建
     *
     * @param targetFile 文件路径
     * @return
     */
    public static void checkTargetFileDir(String targetFile) {
        String dirPath = targetFile.substring(0, targetFile.lastIndexOf(File.separator) + 1);
        File dir = new File(dirPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
    }

    /**
     * 检验文件是否存在
     *
     * @param videoFile
     */
    public static void checkVideoFile(String videoFile) {
        File file = new File(videoFile);
        if (!file.exists()) {
            throw new RuntimeException("文件不存在");
        }
    }

}

我上传的代码demo大概代码

//先上传源文件到系统
savePath = CommonUtils.upload(file, bizPath, uploadType,sy);
//获取源文件的时长和大小以及截图
 //时长
 String durationBackString = VideoUtil.getDurationBackString(file);
//大小
 long durationBackMillis = VideoUtil.getDurationBackMillis(file);
//截图
 DealVideo.fetchFrameToFile(inputPath,distpath + newnames + ".jpg",i1);

//异步转换
 task.task1(inputPath, outputPath, outputPath1, uuid);



异步线程池

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
public class ThreadPoolConfig {

    /**
     * 每秒需要多少个线程处理?
     * tasks/(1/taskcost)
     */
    private int corePoolSize = 3;

    /**
     * 线程池维护线程的最大数量
     * (max(tasks)- queueCapacity)/(1/taskcost)
     */
    private int maxPoolSize = 100;

    /**
     * 缓存队列
     * (coreSizePool/taskcost)*responsetime
     */
    private int queueCapacity = 10;

    /**
     * 允许的空闲时间
     * 默认为60
     */
    private int keepAlive = 100;

    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        executor.setCorePoolSize(corePoolSize);
        // 设置最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        // 设置队列容量
        executor.setQueueCapacity(queueCapacity);
        // 设置允许的空闲时间(秒)
        //executor.setKeepAliveSeconds(keepAlive);
        // 设置默认线程名称
        executor.setThreadNamePrefix("thread-");
        // 设置拒绝策略rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        return executor;
    }
}

在启动类加上异步

 异步任务代码

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.ConvertVideo;
import org.jeecg.common.util.FileUrlUtil;
import org.jeecg.common.util.MinioUtil;
import org.jeecg.modules.business.num.entity.YwVisit;
import org.jeecg.modules.business.num.service.IYwVisitService;
import org.jeecg.modules.business.video.entity.YwVideo;
import org.jeecg.modules.business.video.service.IYwVideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;

import java.util.Random;

@Component
@Slf4j
public class MyTask {

    @Autowired
    private IYwVideoService videoService;

    @Autowired
    private IYwVisitService ywVisitService;

    @Async("taskExecutor")
    public synchronized void task1(String inputPath,String outputPath,String outputPath1,String uuid) throws Exception {
        System.out.println("正在执行线程" + Thread.currentThread().getName() + " 执行异步任务一"+uuid);
        boolean process = ConvertVideo.process(inputPath, outputPath, outputPath1);
        System.out.println("转换完成");
        YwVideo video = videoService.getOne(new QueryWrapper<YwVideo>()
                .eq("uuid", uuid)
        );
        if(null!=video){
            if(!process){
                video.setFlag("2");
                //根据uuid 更新状态
                //throw new Exception("转换错误");
            }else{
                video.setFlag("1");
            }
            //根据uuid更新状态
            videoService.updateById(video);
        }else{
            YwVisit visit = new YwVisit();
            visit.setUuid(uuid);
            ywVisitService.save(visit);
        }
        FileUrlUtil.removeObject(inputPath,"minio");
        FileUrlUtil.removeObject(outputPath1,"minio");
    }


    @Async("taskExecutor")
    public synchronized void test(int num) throws Exception {
        System.out.println("正在执行线程" + Thread.currentThread().getName() + " 执行异步任务"+num);
    }


}

猜你喜欢

转载自blog.csdn.net/weixin_41018853/article/details/128081894