java生成视频缩略图

java生成视频缩略图

需要给前端返回视频的缩略图链接,本来使用的是阿里云的OSS,它提供了缩略图功能的,但是最近换成了Minio....就只有自己写了;

要求:返回给前端一个连接,缩略图实时生成,不会保存.

使用javacv包

参考:https://www.cnblogs.com/yy136/p/9608985.html

流程: 先从Minio中读取视频,然后使用javacv获取某一帧的图,最后使用thumbnailator将图片压缩

但是,视频几十上百M的时候很慢,大视频1分钟都出不来_(:з」∠)_
若是缩略图会保存起来,使用的时候直接读取缩略图的话,这个方案还可以,但是实时读取就不行了

        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.4</version>
        </dependency>

使用

    public void getViewResize(GlobalAccessoryFile accessory) throws Exception  {
        // 获取Minio服务
        MinioClient client = this.getOSSClient();
        //从服务器获取图片
        InputStream inputStream = client.getObject(GetObjectArgs.builder()
                                         .bucket(ossCfg.bucketName) //桶
                                         .object(accessory.getFileDirectoryPath()) //图片在桶内位置
                                          .build());

            FFmpegFrameGrabber grabber;
            InputStream img = null;
            try {
                grabber = new FFmpegFrameGrabber(inputStream,0);

                grabber.start();
                // 视频总帧数
                int videoLength = grabber.getLengthInFrames();

                Frame frame = null;
                int i = 0;

                while (i < videoLength) {
                    // 过滤前5帧,因为前5帧可能是全黑的
                    frame = grabber.grabFrame();
                    if (i>5&&frame.image != null) {
                        break;
                    }
                    i++;
                }

                Java2DFrameConverter converter = new Java2DFrameConverter();
                // 绘制图片
                BufferedImage bi = converter.getBufferedImage(frame);
                img = bufferedImageToInputStream(bi);

                grabber.stop();
                grabber.close();

            } catch (IOException e) {
                e.printStackTrace();
            }

            HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            response.setContentType("multipart/form-data");

            int h = accessory.getTHeight() != null ? accessory.getTHeight() : 200;

            Thumbnails.Builder<? extends InputStream> tb = Thumbnails.of(img).height(h);
            if (accessory.getTWidth() != null) {
                tb.width(accessory.getTWidth());
            }

            tb.toOutputStream(response.getOutputStream());

    }
    /**
     * 将BufferedImage转换为InputStream
     *
     * @param image
     * @return
     */
    public static InputStream bufferedImageToInputStream(BufferedImage image) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", os);
            InputStream input = new ByteArrayInputStream(os.toByteArray());
            return input;
        } catch (IOException e) {

        }
        return null;
    }

vidio查看--失败了

本来用这种方法,看着没有加载视频以为是成功了,后来发现,是之前浏览器缓存了,强制刷新之后还是会加载整个视频_(:з」∠)_

直接返回给前端查看视频的链接,前端使用这个连接显示缩略图
比如我的视频链接是 http://192.168.3.179:9111/achieve8321280.mov?X-Amz-Algorithm=Aac6f7a9e6a34

前端需要缩略图展示的时候(这样会自动展示缩略图,并且没有操作按钮)

<video height="200px" width="200" src="http://192.168.3.179:9111/achieve8321280.mov?X-Amz-Algorithm=Aac6f7a9e6a34"/>

前端需要播放视频的时候

<video controls   height="800px" width="1000" style="outline: none;width:100%" autoplay  src="http://192.168.3.179:9111/achieve8321280.mov?X-Amz-Algorithm=Aac6f7a9e6a34"/>

前端下载

<a href="http://192.168.3.179:9111/achieve8321280.mov?X-Amz-Algorithm=Aac6f7a9e6a34" download="achieve8321280.mov">视频下载</a>
posted @ 2020-12-19 08:04  紫月java  阅读(1328)  评论(0编辑  收藏  举报