zoukankan      html  css  js  c++  java
  • 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;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>
    
  • 相关阅读:
    ES6对象展开运算符
    Vue中keep-alive的深入理解和使用
    彻底明白VUE修饰符sync
    函数去抖和函数节流
    vue cli4.0 配置环境变量
    什么是process.env?
    new Function和with
    inline-block元素没有对齐的解决方案及总结
    【译文】为什么你的浏览器会限制并发网络调用的数量?
    高德地图Marker缩放位置变化
  • 原文地址:https://www.cnblogs.com/ziyue7575/p/14157940.html
Copyright © 2011-2022 走看看