当前位置:   article > 正文

Java视频抽取图片ffmpeg_java视频转图片

java视频转图片
package com.highsoft.video.processing.utils;

import org.apache.commons.lang3.RandomStringUtils;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class VideoProcessingUtil {

    /**
     * 判断是不是视频
     */
    public static boolean isVideo(String path) {
        //设置视频后缀
        List<String> typeList = new ArrayList<String>();
        typeList.add("mp4");
        typeList.add("flv");
        typeList.add("avi");
        typeList.add("rmvb");
        typeList.add("rm");
        typeList.add("wmv");
        //获取文件名和后缀
        String suffix = path.substring(path.lastIndexOf(".") + 1);
        for (String type : typeList) {
            //统一为大写作比较
            if (type.toUpperCase().equals(suffix.toUpperCase())) {
                return true;
            }
        }
        return false;
    }

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

    public static boolean getTempPath(String filePath) throws Exception {
        String path = "E:/images/";
        int count = 3;
        int sum = 0;
        System.out.println("确认文件是否是视频...");
        //判断文件是否为视频
        if (VideoProcessingUtil.isVideo(filePath)) {
            System.out.println("确认成功!");
            //判断文件是否存在
            FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
            ff.start();
            int width = ff.getImageWidth();
            int height = ff.getImageHeight();
            System.out.println("宽:" + width + ";高:" + height);
            // 视频帧数
            int ftp = ff.getLengthInFrames();
            System.out.println("一共有:" + ftp + "帧");
            // 视频帧率
            double videoFrameRate = ff.getVideoFrameRate();
            System.out.println("帧率:" + videoFrameRate);
            System.out.println("秒数:" + ff.getLengthInTime() / 1000000.00);


//            ff.start();

            int step = ftp / (count + 1);
            System.out.println("每隔:" + step + "帧取一帧");
            int flag = 0;
            Frame frame;
            List<String> images = new ArrayList<>();
            boolean isFirst = true;
            // 生成文件名称
            // 获取当前日期
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
            LocalDateTime now = LocalDateTime.now();
            Java2DFrameConverter java2dFrameConverter = new Java2DFrameConverter();
            Random random = new Random();
            long delayedTime = ff.getLengthInTime() / 1000000;
            long sep = delayedTime / (count+1);
            System.out.println(delayedTime + "." + sep);
            for(int i = 0; i < count; i++){
                long time = (sep * (i + 1)) * 1000000L;
                System.out.println(time);
                ff.setTimestamp(time);
                Frame f = ff.grabImage();
                BufferedImage bi = java2dFrameConverter.getBufferedImage(f);
                String fileName = now.format(dtf) + "/" + System.currentTimeMillis() + RandomStringUtils.randomAlphanumeric(8) + ".jpg";
                File out = Paths.get(path, fileName).toFile();
                ImageIO.write(bi, "jpg", out);
                images.add(fileName);
            }

            /*for (int i = 1; i <= ftp; i++) {
                frame = ff.grabImage();
                if ((i > 3 && frame != null && isFirst) || (i % step == 0 && frame != null)) {
                    sum++;
                    System.out.println(i);
                    String fileName = now.format(dtf) + "/" + System.currentTimeMillis() + RandomStringUtils.randomAlphanumeric(8) + ".jpg";
                    File file = new File(path + fileName);
                    if(!file.getParentFile().exists()){
                        file.getParentFile().mkdirs();
                    }
                    BufferedImage image = java2dFrameConverter.convert(frame);
                    // 存储抽取到的图片
                    boolean isSuccess = ImageIO.write(image, "jpg", file);
                    if(isSuccess){
                        images.add(fileName);
                    }
                    // 取首帧 过滤前3帧,避免出现全黑图片
                    isFirst = false;
                    if(sum == (count + 1)){
                        break;
                    }
                }
            }*/
            System.out.println(images);
            ff.stop();
            ff.release();
            return true;
        } else {
            System.out.println("确认失败!");
            return false;
        }
    }


    public static void main(String[] args) throws Exception {
//        boolean tempPath = VideoProcessingUtil.getTempPath("E:/images/542.jpg", "http://pinxls.zlzbgj.com/uploads/videos/202208/23/6fdd53665bf6f7aa847daca49b684436.mp4");
//        System.out.println("获取首帧是否成功!"+tempPath);
//        VideoProcessingUtil.getTempPath("http://pinxls.zlzbgj.com/uploads/videos/202208/23/5763bccd10bfb2be2a827d940cbb5b4d.mp4");

        long time = 12000000 / 1000; // 获取ms时长
        long step = time / (3 + 2); // 获取按照count拆分后的每段时长 为了去掉前一段和后一段 取中间段来截取图片
        System.out.println(step);
        Random random = new Random();
        for(int i = 0; i<3;i++){
            int randomInt = random.nextInt(Math.toIntExact(step));// 随机取一个点
            System.out.println(randomInt);
            long jumpTime = (step * (i+1) + randomInt) * 1000L;
            System.out.println(jumpTime);
        }
    }
}



public class ProcessingServiceImpl implements IProcessingService {

    // 视频格式
    private static final String[] VIDEO_TYPES = {"mp4", "flv", "avi", "rmvb", "rm", "wmv"};
    // 文件存储路径
    @Value("${video.images.path:/www/wwwroot/supply_chain/images/}")
    private String path;
    // 图片展示路径前缀
    @Value("${video.images.url_prefix:http://images.kdfff.com/images/}")
    private String url_prefix;
    // 截取截图数量
    @Value("${video.images.count:3}")
    private Integer count;

    @Override
    public ResultDTO processing(String videoUrl) {
//        String videoUrl = params.get("video");
        if (StringUtils.isBlank(videoUrl)) {
            // 传入的视频路径为空
            log.info("传入的视频路径为空");
            return ResultDTO.fail("未传入视频路径!");
        }
        if (!isVideo(videoUrl)) {
            // 文件不为视频文件
            log.info("文件不为视频文件");
            return ResultDTO.fail("文件不为视频文件!");
        }
        String suffix = videoUrl.substring(videoUrl.lastIndexOf(".") + 1);
        log.info("开始获取视频,并抓取视频信息,url:【{}】, 后缀:【{}】", videoUrl, suffix);
        FFmpegFrameGrabber grabber = null;
        VideoInfoRespDTO respDTO = new VideoInfoRespDTO(); // 返回视频信息
        try {
            grabber = FFmpegFrameGrabber.createDefault(videoUrl); // 获取视频
            grabber.start(); // 启动视频
            respDTO.setUrlPrefix(url_prefix); // 设置图片展示前缀
            respDTO.setHeight(grabber.getImageHeight()); // 获取高度
            respDTO.setWidth(grabber.getImageWidth());  // 获取宽度
            respDTO.setBitrate(grabber.getVideoBitrate()); // 获取视频码率
            respDTO.setFps(grabber.getVideoFrameRate()); // 获取视频流帧率
            respDTO.setDuration(grabber.getLengthInTime() / 1000000); // 获取视频流长度: 单位s
            respDTO.setFormat(suffix); // 获取视频流格式
            // 生成文件名称 具体为 /日期/时间戳+随机字符串.jpg
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
            String now = LocalDateTime.now().format(dtf);
            Java2DFrameConverter java2dFrameConverter = new Java2DFrameConverter();
            // 获取首帧图片
            int ftp = grabber.getLengthInFrames();
            int flag = 0;
            Frame firstFrame;
            while (flag <= 10) {
                firstFrame = grabber.grabImage();
                //过滤前3帧,避免出现全黑图片
                if ((flag > 5) && (firstFrame != null)) {
                    BufferedImage bi = java2dFrameConverter.getBufferedImage(firstFrame);
                    String fileName = now + "/" + System.currentTimeMillis() + RandomStringUtils.randomAlphanumeric(8) + ".jpg";
                    File out = new File(path + fileName);
                    if(!out.getParentFile().exists()){
                        out.getParentFile().mkdirs();
                    }
                    if (ImageIO.write(bi, "jpg", out)) {
                        // 图片保存成功!
                        respDTO.setCover_url(url_prefix + fileName);
                        break;
                    }
                }
                flag++;
            }
            // 随机获取 count 帧图片
            long time = grabber.getLengthInTime() / 1000; // 获取ms时长
            long step = time / (count + 2); // 获取按照count拆分后的每段时长 为了去掉前一段和后一段 取中间段来截取图片
            Random random = new Random();
            List<String> images = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                int randomInt = random.nextInt(Math.toIntExact(step));// 随机取一个点
                long jumpTime = (step * (i + 1) + randomInt) * 1000L;
                grabber.setTimestamp(jumpTime);
                Frame f = grabber.grabImage();
                BufferedImage bi = java2dFrameConverter.getBufferedImage(f);
                String fileName = now + "/" + System.currentTimeMillis() + RandomStringUtils.randomAlphanumeric(8) + ".jpg";
                File out = Paths.get(path, fileName).toFile();
                if(!out.getParentFile().exists()){
                    out.getParentFile().mkdirs();
                }
                ImageIO.write(bi, "jpg", out);
                images.add(url_prefix + fileName);
            }
            respDTO.setSnapshots(images);
            log.info("处理结果:【{}】", JSONObject.toJSONString(respDTO));
            return ResultDTO.success(respDTO);
        } catch (Exception e) {
            log.error("处理发生异常!msg:{}", e);
        } finally {
            if (grabber != null) {
                try {
                    grabber.release();
                    grabber.stop();
                    grabber.close();
                } catch (FrameGrabber.Exception e) {
                    log.error("关闭grabber发生异常!msg:{}", e);
                }
            }
        }
        return ResultDTO.error();
    }

    /**
     * 判断是不是视频
     */
    private static boolean isVideo(String path) {
        //获取文件名和后缀
        String suffix = path.substring(path.lastIndexOf(".") + 1);
        for (String type : VIDEO_TYPES) {
            //统一为大写作比较
            if (type.equalsIgnoreCase(suffix)) {
                return true;
            }
        }
        return false;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/650487
推荐阅读
相关标签
  

闽ICP备14008679号