javacv视频获取第一帧作为缩略图

javacv视频获取第一帧作为缩略图,第1张

POM 依赖

    org.bytedeco
    javacv-platform
    1.4.2

package xyz.vivo.video;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class VideoUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(VideoUtil.class);
    //参数:视频路径和缩略图保存路径
    public static Map getVideoInfo (InputStream videoInputSteam)
            throws Exception {
        long start = System.currentTimeMillis();
        Map result = new HashMap();
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoInputSteam);
        ff.start();
        String rotate_old = ff.getVideoMetadata("rotate");
        int length = ff.getLengthInFrames();
        //设置视频截取帧(默认取第一帧)
        Frame frame = ff.grabImage();
        Java2DFrameConverter converter = new Java2DFrameConverter();
        //绘制图片
        BufferedImage bi = converter.getBufferedImage(frame);
        String rotate = ff.getVideoMetadata("rotate");
        result.put("videoWide", bi.getWidth());
        result.put("videoHigh", bi.getHeight());
        long duration = ff.getLengthInTime() / (1000 * 1000);
        result.put("rotate", StringUtils.isBlank(rotate) ? "0" : rotate);
        result.put("format", ff.getFormat());
        System.out.println(System.currentTimeMillis() - start);
    return  result;
    }
    //参数:视频路径和缩略图保存路径
    public static ByteArrayInputStream fetchFrame(InputStream videoInputSteam)
            throws Exception {
        long start = System.currentTimeMillis();
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoInputSteam);
        ff.start();
        String rotate = ff.getVideoMetadata("rotate");
        int length = ff.getLengthInFrames();
        int i = 0;
        Frame f = null;
        while (i < length) {
            // 去掉前5帧,避免出现全黑的图片,依自己情况而定
            f = ff.grabImage();
            if ((i > 5) && (f.image != null)) {
                break;
            }
            i++;
        }
        int owidth = f.imageWidth;
        int oheight = f.imageHeight;
        // 对截取的帧进行等比例缩放
        int width = 800;//生成图片宽度为800px
        int height = (int) (((double) width / owidth) * oheight);
        Java2DFrameConverter converter = new Java2DFrameConverter();
        BufferedImage fecthedImage = converter.getBufferedImage(f);
        BufferedImage bi = new BufferedImage(owidth, oheight, BufferedImage.TYPE_3BYTE_BGR);
        bi.getGraphics().drawImage(fecthedImage.getScaledInstance(owidth, oheight, Image.SCALE_SMOOTH),
                0, 0, null);
        ImageIO.setUseCache(false);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(bi, "jpg", byteArrayOutputStream);
        ff.stop();
        if (rotate != null && !rotate.isEmpty()) {
            int rotateInt = Integer.parseInt(rotate);
            return  rotatePhonePhoto(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), rotateInt);
        }
        long duration = ff.getLengthInTime() / (1000 * 1000);
        LOGGER.debug("视频的宽:" + bi.getWidth());
        LOGGER.debug("视频的高:" + bi.getHeight());
        LOGGER.debug("视频的旋转度:" + rotate);
        LOGGER.debug("视频的格式:" + ff.getFormat());
        LOGGER.debug("此视频时长(s/秒):" + duration);

        System.out.println(System.currentTimeMillis() - start);
        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    }

    /**
     * 旋转照片
     *
     * @param angel
     * @return
     */
    public static ByteArrayInputStream rotatePhonePhoto(InputStream inputStream, int angel) {
        BufferedImage src;
        try {
            src = ImageIO.read(inputStream);
            int src_width = src.getWidth(null);
            int src_height = src.getHeight(null);

            int swidth = src_width;
            int sheight = src_height;

            if (angel == 90 || angel == 270) {
                swidth = src_height;
                sheight = src_width;
            }
            Rectangle rect_des = new Rectangle(new Dimension(swidth, sheight));
            BufferedImage res = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = res.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, null, null);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(res, "jpg", byteArrayOutputStream);
            return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static BufferedImage FrameToBufferedImage(Frame frame) {
        //创建BufferedImage对象
        Java2DFrameConverter converter = new Java2DFrameConverter();
        BufferedImage bufferedImage = converter.getBufferedImage(frame);
        return bufferedImage;
    }

    public static void main(String[] args) throws Exception {
        ;
        FileOutputStream fileOutputStream = new FileOutputStream("E:\\workspace\\flinkTutorial\\1234.jpg");
        IOUtils.copy(fetchFrame(new FileInputStream("E:\\workspace\\flinkTutorial\\1234.mp4")), fileOutputStream);
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/738569.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-28
下一篇 2022-04-28

发表评论

登录后才能评论

评论列表(0条)

保存