栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java-视频按秒截取帧

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java-视频按秒截取帧

Java视频按秒截取帧 1. Java视频按秒截取帧工具类
具体方法都在工具类中,可以文件地址,可以按照参数传递,具体场景需要根据工具类具体改造一下,但是基本功能是不变的。
        
        
        
            com.github.vip-zpf
            jave
            1.1.1
        

        
            com.github.vip-zpf
            jave
            1.0.8
        
        
            org.bytedeco
            javacv
            1.5.6
        

        
            org.bytedeco
            ffmpeg-platform
            4.4-1.5.6
        
package com.xxx.util;

import com.xxx.util.img.ConvertToMultipartFile;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.MultimediaInfo;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
public class VideoUtil {


    
    public static Map getVideoPic(String frameFilePath, File video, String picPath){
        //1.根据一个视频文件,创建一个按照视频中每一帧进行抓取图片的抓取对象
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(video);
        Map  strMap=new HashMap<>();
        List strList=new ArrayList<>();
        try {
            ff.start();
            //抓每一帧图片
            //2.先知道这个视频一共有多少帧
            int length = ff.getLengthInFrames();
            //3.读取视频中每一帧图片
            Frame frame = null;
            for(int i=1;i图片的转换器
                BufferedImage image = converter.getBufferedImage(frame);//转换
                String img = picPath+i+".png";
                File picFile = new File(img);
                //将图片保存到目标文件中
                ImageIO.write(image, "png", picFile);
                strList.add(frameFilePath+"/"+i+".png");
            }
            strMap.put("height",ff.getImageHeight());//视频高度
            strMap.put("width",ff.getImageWidth());//视频宽度
            strMap.put("frame",ff.getFrameRate());//帧率
            strMap.put("imgPath",strList);//每一帧图像数据
            ff.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strMap;
    }

    
    public static int queryVideoDuration(MultipartFile multipartFile) throws EncoderException {
        //机算视频时长
        File dfile = null;
        try {
            dfile = File.createTempFile("prefix", "_" + multipartFile.getOriginalFilename());
            multipartFile.transferTo(dfile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取视频时长
        Encoder encoder = new Encoder();
        MultimediaInfo m = encoder.getInfo(dfile);
        long ls = m.getDuration()/1000;
        int hour = (int) (ls/3600);
        int minute = (int) (ls%3600)/60;
        int second = (int) (ls-hour*3600-minute*60);
        //删除临时文件
        dfile.delete();
        return second;
    }



    public static void approvalFile( MultipartFile filecontent , String path){
        OutputStream os = null;
        InputStream inputStream = null;
        String fileName = null;
        try {
            inputStream = filecontent.getInputStream();
            fileName = filecontent.getOriginalFilename();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流保存到本地文件
            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 完毕,关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    
    private static void getImage(String filePath, String fileName, int second) {
        File folder = new File(filePath);
        if (!folder.exists())
        {
            folder.mkdirs();//如果文件夹不存在则创建
        }
        try{
            FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filePath + File.separator + fileName);
            grabber.start();
            long ftp = grabber.getLengthInFrames();
            int flag=0;
            int sum=0;
            Frame frame = null;
            int count = (int)Math.round(grabber.getFrameRate());
            while (flag <= ftp) {
                if(countflag){
                    flag++;
                    continue;
                } else if(count > ftp){
                    break;
                } else{
                    count += (int)Math.round(grabber.getFrameRate());
                }
                sum++;
                //获取帧跳帧
                grabber.setFrameNumber(count);
                frame = grabber.grabImage();
                //过滤前 second 帧,避免出现全黑图片
                
                String rotate = grabber.getVideoMetadata("rotate");
                //创建BufferedImage对象
                Java2DFrameConverter converter = new Java2DFrameConverter();
                BufferedImage bufferedImage = converter.getBufferedImage(frame);
                if (rotate != null) {
                    //旋转图片
                    bufferedImage = rotate(bufferedImage, Integer.parseInt(rotate));
                }
                String newFileName = filePath + File.separator + fileName.substring(0, fileName.lastIndexOf(".")) + sum +".jpeg";
                ImageIO.write(bufferedImage, "jpeg", new File(newFileName));
                flag += (int)Math.round(grabber.getFrameRate());
            }

            grabber.close();
            grabber.stop();
        }catch(Exception e){
            System.out.printf("获取视频图片失败!", e);
        }
    }

    private static BufferedImage rotate(BufferedImage src, int angel) {
        int src_width = src.getWidth(null);
        int src_height = src.getHeight(null);
        int type = src.getColorModel().getTransparency();
        Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
        BufferedImage bi = new BufferedImage(rect_des.width, rect_des.height, type);
        Graphics2D g2 = bi.createGraphics();
        g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
        g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
        g2.drawImage(src, 0, 0, null);
        g2.dispose();
        return bi;
    }
    private static Rectangle calcRotatedSize(Rectangle src, int angel) {
        if (angel >= 90) {
            if(angel / 90 % 2 == 1) {
                int temp = src.height;
                src.height = src.width;
                src.width = temp;
            }
            angel = angel % 90;
        }
        double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
        double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
        double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
        double angel_dalta_width = Math.atan((double) src.height / src.width);
        double angel_dalta_height = Math.atan((double) src.width / src.height);
        int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
        int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
        int des_width = src.width + len_dalta_width * 2;
        int des_height = src.height + len_dalta_height * 2;
        return new Rectangle(new Dimension(des_width, des_height));
    }


    
    public static List getVideoImageByUrl(String onlineFileUrl) {
        //导出本地地址
//        String filePath="C:\Users\wonder\Desktop\ai测试图片\视频解析\截取后\";
//        File folder = new File(filePath);
//        if (!folder.exists())
//        {
//            folder.mkdirs();//如果文件夹不存在则创建
//        }
        Listlist=new ArrayList<>();
        try{
            //url编码处理,中文名称会变成百分号编码
            String fileUrl = URLDecoder.decode(onlineFileUrl, "utf-8");
            MultipartFile multipartFile = HuaweiOBSUtil.downloadFileByUrl(fileUrl);
            FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(multipartFile.getInputStream());
            grabber.start();
            long ftp = grabber.getLengthInFrames();
            Frame frame = null;
            int sum=0;
            int flag=0;
            int count = (int)Math.round(grabber.getFrameRate());
            while (flag <= ftp) {
                if(countflag){
                    flag++;
                    continue;
                } else if(count > ftp){
                    break;
                } else{
                    count += (int)Math.round(grabber.getFrameRate());
                }
                sum++;
                //获取帧
                grabber.setFrameNumber(count);
                frame = grabber.grabImage();
                //过滤前 second 帧,避免出现全黑图片
                
                String rotate = grabber.getVideoMetadata("rotate");
                //创建BufferedImage对象
                Java2DFrameConverter converter = new Java2DFrameConverter();
                BufferedImage bufferedImage = converter.getBufferedImage(frame);
                if (rotate != null) {
                    //旋转图片
                    bufferedImage = rotate(bufferedImage, Integer.parseInt(rotate));
                }
                String newFileName = sum +".jpeg";
                //写入本地
                //ImageIO.write(bufferedImage, "jpeg", new File(filePath+newFileName));
                //BufferedImage 转化为 ByteArrayOutputStream
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "jpeg", out);
                //ByteArrayOutputStream 转化为 byte[]
                byte[] imageByte = out.toByteArray();
                //将 byte[] 转为 MultipartFile
                MultipartFile convertMultipartFile = new ConvertToMultipartFile(imageByte, null, newFileName, "jpeg", imageByte.length);
                //MultipartFile multipartFile = new ConvertToMultipartFile(imageByte, "C:\Users\wonder\Desktop\ai测试图片\视频解析\截取后\", newFileName, "jpeg", imageByte.length);
                list.add(convertMultipartFile);
                flag += (int)Math.round(grabber.getFrameRate());
            }

            grabber.close();
            grabber.stop();
        }catch(Exception e){
            System.out.printf("获取视频图片失败!", e);
        }
        
        return list;
    }

    public static void main(String[] args) {
        List videoImageByUrl = getVideoImageByUrl("url");
        for (MultipartFile multipartFile : videoImageByUrl) {
            String s = FileUtil.generateBase64(multipartFile, true);
            System.out.println("multipartFile.getOriginalFilename() = " + multipartFile.getOriginalFilename());
            String fileNameNotPrefix = FileUtil.getFileNameNotPrefix(multipartFile.getOriginalFilename());
            System.out.println("fileNameNotPrefix = " + fileNameNotPrefix);


        }
    }

}
2.获取视频时长
    
    public static int queryVideoDuration(MultipartFile multipartFile) throws EncoderException {
        //机算视频时长
        File dfile = null;
        try {
            dfile = File.createTempFile("prefix", "_" + multipartFile.getOriginalFilename());
            multipartFile.transferTo(dfile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取视频时长
        Encoder encoder = new Encoder();
        MultimediaInfo m = encoder.getInfo(dfile);
        long ls = m.getDuration()/1000;
        int hour = (int) (ls/3600);
        int minute = (int) (ls%3600)/60;
        int second = (int) (ls-hour*3600-minute*60);
        //删除临时文件
        dfile.delete();
        return second;
    }


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1006813.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号